diff --git a/.gitignore b/.gitignore index 7abeab51f..f0b5aa053 100644 --- a/.gitignore +++ b/.gitignore @@ -34,10 +34,12 @@ obj/ _ReSharper*/ [Tt]est[Rr]esult* App_Data/ +.vs/ +.vscode/ +*.lock.json NuGet/ NuGet.Signed/ -*.pfx build/ *.nupkg diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..b15b8d333 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceRoot}/tests/ServiceStack.OrmLite.Tests/bin/Debug/netcoreapp1.1/ServiceStack.OrmLite.Tests.dll", + "args": ["--test=ServiceStack.OrmLite.Tests._TypeDescriptorMetadataTests.Can_add_AutoIncrement_Id_at_runtime"], + "cwd": "${workspaceRoot}", + "stopAtEntry": false, + "externalConsole": false + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..7a0209688 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,20 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "command": "dotnet", + "args": [], + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "dotnet", + "args": [ + "build", + "tests/ServiceStack.OrmLite.Tests" + ], + "problemMatcher": "$msCompile", + "group": "build" + } + ] +} \ No newline at end of file diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 000000000..42daf5f44 --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/NuGet.Signed/ServiceStack.OrmLite.Oracle.Signed/servicestack.ormlite.oracle.signed.nuspec b/NuGet.Signed/ServiceStack.OrmLite.Oracle.Signed/servicestack.ormlite.oracle.signed.nuspec deleted file mode 100644 index b44a66bd8..000000000 --- a/NuGet.Signed/ServiceStack.OrmLite.Oracle.Signed/servicestack.ormlite.oracle.signed.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - ServiceStack.OrmLite.Oracle.Signed - ServiceStack.OrmLite.Oracle.Signed - 4.0.0 - Service Stack, Guru Kathiresan - Service Stack, Guru Kathiresan - - Light, simple and fast convention-based code-first POCO ORM for Oracle RDBMS. - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Oracle. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - Oracle SQL OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2014 and contributors - - - - - - - - - diff --git a/NuGet.Signed/ServiceStack.OrmLite.Signed/servicestack.ormlite.signed.nuspec b/NuGet.Signed/ServiceStack.OrmLite.Signed/servicestack.ormlite.signed.nuspec deleted file mode 100644 index 2a3325789..000000000 --- a/NuGet.Signed/ServiceStack.OrmLite.Signed/servicestack.ormlite.signed.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - ServiceStack.OrmLite.Signed - ServiceStack.OrmLite.Signed - 4.0.0 - Service Stack - Service Stack - - Light, simple and fast convention-based code-first POCO ORM for Oracle RDBMS (Unofficial). - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently - stored in schemaless text blobs in Oracle. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - diff --git a/NuGet.Signed/ServiceStack.OrmLite.SqlServer.Signed/servicestack.ormlite.sqlserver.signed.nuspec b/NuGet.Signed/ServiceStack.OrmLite.SqlServer.Signed/servicestack.ormlite.sqlserver.signed.nuspec deleted file mode 100644 index d3a481a45..000000000 --- a/NuGet.Signed/ServiceStack.OrmLite.SqlServer.Signed/servicestack.ormlite.sqlserver.signed.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - ServiceStack.OrmLite.SqlServer.Signed - ServiceStack.OrmLite.SqlServer.Signed - 4.0.0 - Service Stack - Service Stack - - Light, simple and fast convention-based code-first POCO ORM for Sql Server. - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLServer. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - SQLServer SQL Server OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - diff --git a/NuGet.Signed/ServiceStack.OrmLite.Sqlite.Windows.Signed/servicestack.ormlite.sqlite.windows.signed.nuspec b/NuGet.Signed/ServiceStack.OrmLite.Sqlite.Windows.Signed/servicestack.ormlite.sqlite.windows.signed.nuspec deleted file mode 100644 index c4746bd89..000000000 --- a/NuGet.Signed/ServiceStack.OrmLite.Sqlite.Windows.Signed/servicestack.ormlite.sqlite.windows.signed.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - ServiceStack.OrmLite.Sqlite.Windows.Signed - OrmLite.Sqlite.Windows (x86/x64) - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack - Service Stack - - Light, simple and fast convention-based code-first POCO ORM. Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Sqlite. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - Sqlite Windows 32bit 64bit OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - - - - diff --git a/NuGet/NuGetPack.cmd b/NuGet/NuGetPack.cmd deleted file mode 100644 index 0e078776d..000000000 --- a/NuGet/NuGetPack.cmd +++ /dev/null @@ -1,11 +0,0 @@ -SET NUGET=..\src\.nuget\nuget -%NUGET% pack ServiceStack.OrmLite.Sqlite.Mono\servicestack.ormlite.sqlite.mono.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.Sqlite32\servicestack.ormlite.sqlite32.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.Sqlite64\servicestack.ormlite.sqlite64.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.SqlServer\servicestack.ormlite.sqlserver.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.MySql\servicestack.ormlite.mysql.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.PostgreSQL\servicestack.ormlite.postgresql.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.Oracle\servicestack.ormlite.oracle.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.Firebird\servicestack.ormlite.firebird.nuspec -symbols -%NUGET% pack ServiceStack.OrmLite.T4\servicestack.ormlite.t4.nuspec -symbols - diff --git a/NuGet/NuGetPush.cmd b/NuGet/NuGetPush.cmd deleted file mode 100644 index 005e973c9..000000000 --- a/NuGet/NuGetPush.cmd +++ /dev/null @@ -1,19 +0,0 @@ -SET NUGET=..\src\.nuget\nuget -%NUGET% push ServiceStack.OrmLite.Firebird.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.Firebird.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.MySql.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.MySql.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.Oracle.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.Oracle.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.PostgreSQL.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.PostgreSQL.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.Sqlite.Mono.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.Sqlite.Mono.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.Sqlite32.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.Sqlite32.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.Sqlite64.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.Sqlite64.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.SqlServer.3.9.60.nupkg -%NUGET% push ServiceStack.OrmLite.SqlServer.3.9.60.symbols.nupkg -%NUGET% push ServiceStack.OrmLite.T4.3.9.59.nupkg - diff --git a/NuGet/ServiceStack.OrmLite.Firebird/servicestack.ormlite.firebird.nuspec b/NuGet/ServiceStack.OrmLite.Firebird/servicestack.ormlite.firebird.nuspec deleted file mode 100644 index 76b9ad03d..000000000 --- a/NuGet/ServiceStack.OrmLite.Firebird/servicestack.ormlite.firebird.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - ServiceStack.OrmLite.Firebird - OrmLite.FireBird - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack, Angel Colmenares - Service Stack, Angel Colmenares - - Light, simple and fast convention-based code-first POCO ORM for Firebird. - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Firebird. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - Firebird OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.MySql/servicestack.ormlite.mysql.nuspec b/NuGet/ServiceStack.OrmLite.MySql/servicestack.ormlite.mysql.nuspec deleted file mode 100644 index fbb6d130f..000000000 --- a/NuGet/ServiceStack.OrmLite.MySql/servicestack.ormlite.mysql.nuspec +++ /dev/null @@ -1,29 +0,0 @@ - - - - ServiceStack.OrmLite.MySql - OrmLite.MySQL - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack, Thomas Grassauer - Service Stack, Thomas Grassauer - - Light, simple and fast convention-based code-first POCO ORM for MySQL. - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in MySQL. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - MySql OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.Oracle/servicestack.ormlite.oracle.nuspec b/NuGet/ServiceStack.OrmLite.Oracle/servicestack.ormlite.oracle.nuspec deleted file mode 100644 index 602e5eda3..000000000 --- a/NuGet/ServiceStack.OrmLite.Oracle/servicestack.ormlite.oracle.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - ServiceStack.OrmLite.Oracle - OrmLite.Oracle - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack, Guru Kathiresan - Service Stack, Guru Kathiresan - - Light, simple and fast convention-based code-first POCO ORM for Oracle RDBMS (Unofficial). - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently - stored in schemaless text blobs in Oracle. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - Oracle SQL OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.PostgreSQL/servicestack.ormlite.postgresql.nuspec b/NuGet/ServiceStack.OrmLite.PostgreSQL/servicestack.ormlite.postgresql.nuspec deleted file mode 100644 index d9834d40b..000000000 --- a/NuGet/ServiceStack.OrmLite.PostgreSQL/servicestack.ormlite.postgresql.nuspec +++ /dev/null @@ -1,29 +0,0 @@ - - - - ServiceStack.OrmLite.PostgreSQL - OrmLite.PostgreSQL - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack, Tomasz Kubacki - Service Stack, Tomasz Kubacki - - Light, simple and fast convention-based code-first POCO ORM for PostgreSQL. - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Postgres. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - PostgreSQL Postgres OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.SqlServer/servicestack.ormlite.sqlserver.nuspec b/NuGet/ServiceStack.OrmLite.SqlServer/servicestack.ormlite.sqlserver.nuspec deleted file mode 100644 index f8a58f434..000000000 --- a/NuGet/ServiceStack.OrmLite.SqlServer/servicestack.ormlite.sqlserver.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - ServiceStack.OrmLite.SqlServer - OrmLite.SqlServer - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack - Service Stack - - Light, simple and fast convention-based code-first POCO ORM for Sql Server. - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLServer. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - SQLServer SQL Server OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.Sqlite.Mono/content/sqlite3.dll b/NuGet/ServiceStack.OrmLite.Sqlite.Mono/content/sqlite3.dll deleted file mode 100644 index 2d241c4ec..000000000 Binary files a/NuGet/ServiceStack.OrmLite.Sqlite.Mono/content/sqlite3.dll and /dev/null differ diff --git a/NuGet/ServiceStack.OrmLite.Sqlite.Mono/servicestack.ormlite.sqlite.mono.nuspec b/NuGet/ServiceStack.OrmLite.Sqlite.Mono/servicestack.ormlite.sqlite.mono.nuspec deleted file mode 100644 index a0cc4426f..000000000 --- a/NuGet/ServiceStack.OrmLite.Sqlite.Mono/servicestack.ormlite.sqlite.mono.nuspec +++ /dev/null @@ -1,29 +0,0 @@ - - - - ServiceStack.OrmLite.Sqlite.Mono - OrmLite.Sqlite.Mono - Compatible with Mono / Windows (x86) - 4.0.0 - Service Stack - Service Stack - - Light, simple and fast convention-based code-first POCO ORM. Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Sqlite. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - Sqlite Mono Windows x86 32bit OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.Sqlite.Mono/tools/install.ps1 b/NuGet/ServiceStack.OrmLite.Sqlite.Mono/tools/install.ps1 deleted file mode 100644 index bc0152e2d..000000000 --- a/NuGet/ServiceStack.OrmLite.Sqlite.Mono/tools/install.ps1 +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################### -# -# install.ps1 -- Set 'sqlite3.dll' Build action to Copy to output directory -# -############################################################################### - -param($installPath, $toolsPath, $package, $project) - -$fileName = "sqlite3.dll" -$propertyName = "CopyToOutputDirectory" - -$item = $project.ProjectItems.Item($fileName) - -if ($item -eq $null) { - continue -} - -$property = $item.Properties.Item($propertyName) - -if ($property -eq $null) { - continue -} - -$property.Value = 2 diff --git a/NuGet/ServiceStack.OrmLite.Sqlite.Windows/servicestack.ormlite.sqlite.windows.nuspec b/NuGet/ServiceStack.OrmLite.Sqlite.Windows/servicestack.ormlite.sqlite.windows.nuspec deleted file mode 100644 index aee66918e..000000000 --- a/NuGet/ServiceStack.OrmLite.Sqlite.Windows/servicestack.ormlite.sqlite.windows.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - ServiceStack.OrmLite.Sqlite.Windows - OrmLite.Sqlite.Windows (x86/x64) - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack - Service Stack - - Light, simple and fast convention-based code-first POCO ORM. Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Sqlite. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - Sqlite Windows 32bit 64bit OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.Sqlite32/lib/net40/System.Data.SQLite.dll b/NuGet/ServiceStack.OrmLite.Sqlite32/lib/net40/System.Data.SQLite.dll deleted file mode 100644 index 009978cc7..000000000 Binary files a/NuGet/ServiceStack.OrmLite.Sqlite32/lib/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/NuGet/ServiceStack.OrmLite.Sqlite32/lib/net40/System.Data.SQLite.xml b/NuGet/ServiceStack.OrmLite.Sqlite32/lib/net40/System.Data.SQLite.xml deleted file mode 100644 index 149e17c83..000000000 --- a/NuGet/ServiceStack.OrmLite.Sqlite32/lib/net40/System.Data.SQLite.xml +++ /dev/null @@ -1,12758 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding and returning column values, always treat them as though - they were plain text (i.e. no numeric, date/time, or other conversions - should be attempted). - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - This lock is used to protect the static _SQLiteModule and - processorArchitecturePlatforms fields, below. - - - - - Stores the mappings between processor architecture names and platform - names. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The native module handle as returned by LoadLibrary -OR- IntPtr.Zero - if the loading fails for any reason. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/NuGet/ServiceStack.OrmLite.Sqlite32/servicestack.ormlite.sqlite32.nuspec b/NuGet/ServiceStack.OrmLite.Sqlite32/servicestack.ormlite.sqlite32.nuspec deleted file mode 100644 index 58e6d6829..000000000 --- a/NuGet/ServiceStack.OrmLite.Sqlite32/servicestack.ormlite.sqlite32.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - ServiceStack.OrmLite.Sqlite32 - OrmLite.Sqlite.32bit - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack - Service Stack - - This package is deprecated. - Use the new ServiceStack.OrmLite.Sqlite.Windows NuGet package which supports both x86/x64 architectures. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - Sqlite 32bit OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.Sqlite64/lib/net40/System.Data.SQLite.dll b/NuGet/ServiceStack.OrmLite.Sqlite64/lib/net40/System.Data.SQLite.dll deleted file mode 100644 index b1361de26..000000000 Binary files a/NuGet/ServiceStack.OrmLite.Sqlite64/lib/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/NuGet/ServiceStack.OrmLite.Sqlite64/lib/net40/System.Data.SQLite.xml b/NuGet/ServiceStack.OrmLite.Sqlite64/lib/net40/System.Data.SQLite.xml deleted file mode 100644 index 149e17c83..000000000 --- a/NuGet/ServiceStack.OrmLite.Sqlite64/lib/net40/System.Data.SQLite.xml +++ /dev/null @@ -1,12758 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding and returning column values, always treat them as though - they were plain text (i.e. no numeric, date/time, or other conversions - should be attempted). - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - This lock is used to protect the static _SQLiteModule and - processorArchitecturePlatforms fields, below. - - - - - Stores the mappings between processor architecture names and platform - names. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The native module handle as returned by LoadLibrary -OR- IntPtr.Zero - if the loading fails for any reason. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/NuGet/ServiceStack.OrmLite.Sqlite64/servicestack.ormlite.sqlite64.nuspec b/NuGet/ServiceStack.OrmLite.Sqlite64/servicestack.ormlite.sqlite64.nuspec deleted file mode 100644 index 92eb3e590..000000000 --- a/NuGet/ServiceStack.OrmLite.Sqlite64/servicestack.ormlite.sqlite64.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - ServiceStack.OrmLite.Sqlite64 - OrmLite.Sqlite.64bit - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack - Service Stack - - This package is deprecated. - Use the new ServiceStack.OrmLite.Sqlite.Windows NuGet package which supports both x86/x64 architectures. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - Sqlite 64bit OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite.T4/servicestack.ormlite.t4.nuspec b/NuGet/ServiceStack.OrmLite.T4/servicestack.ormlite.t4.nuspec deleted file mode 100644 index 59ffaf20e..000000000 --- a/NuGet/ServiceStack.OrmLite.T4/servicestack.ormlite.t4.nuspec +++ /dev/null @@ -1,22 +0,0 @@ - - - - ServiceStack.OrmLite.T4 - OrmLite.T4 - T4 schema-generation templates for OrmLite - 4.0.0 - Service Stack - Service Stack - - Generate POCO models for all existing tables and stored procedures in a database for use with OrmLite. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://github.com/ServiceStack/ServiceStack/blob/master/license.txt - https://servicestack.net/img/logo-32.png - T4 SQL Templates CodeGen OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - diff --git a/NuGet/ServiceStack.OrmLite.VistaDb/servicestack.ormlite.vistadb.nuspec b/NuGet/ServiceStack.OrmLite.VistaDb/servicestack.ormlite.vistadb.nuspec deleted file mode 100644 index e74d5bb02..000000000 --- a/NuGet/ServiceStack.OrmLite.VistaDb/servicestack.ormlite.vistadb.nuspec +++ /dev/null @@ -1,27 +0,0 @@ - - - - ServiceStack.OrmLite.VistaDb - ServiceStack.OrmLite.VistaDb - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack - Service Stack - - Light, simple and fast convention-based code-first POCO ORM. Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in VistaDB. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - VistaDb Windows OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2014 and contributors - - - - - - - - - diff --git a/NuGet/ServiceStack.OrmLite/servicestack.ormlite.nuspec b/NuGet/ServiceStack.OrmLite/servicestack.ormlite.nuspec deleted file mode 100644 index 9c3bd2296..000000000 --- a/NuGet/ServiceStack.OrmLite/servicestack.ormlite.nuspec +++ /dev/null @@ -1,29 +0,0 @@ - - - - ServiceStack.OrmLite - OrmLite - Fast, code-first, config-free Poco ORM - 4.0.0 - Service Stack - Service Stack - - Common library for the Light, simple and fast convention-based code-first POCO, OrmLite. - Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs. - OrmLite is a suite extension methods on ADO.NET's underlying IDbConnection providing DRY, typed access for common data usage patterns that map to clean, simple POCOs. Great support for testing where OrmLite methods can be mocked. - - https://github.com/ServiceStack/ServiceStack.OrmLite - https://servicestack.net/terms - true - https://servicestack.net/img/logo-32.png - OrmLite POCO Code-First Orm Schema-less Blobs - en-US - ServiceStack 2013 and contributors - - - - - - - - - diff --git a/README.md b/README.md index 3bc17eeb9..f51addde1 100644 --- a/README.md +++ b/README.md @@ -1,1789 +1,5 @@ -[Join the ServiceStack Google+ group](https://plus.google.com/u/0/communities/112445368900682590445) or -follow [@servicestack](http://twitter.com/servicestack) for updates. +Follow [@ServiceStack](https://twitter.com/servicestack), [view the docs](https://docs.servicestack.net), use [StackOverflow](https://stackoverflow.com/questions/ask?tags=servicestack,ormlite-servicestack) or [Customer Forums](https://forums.servicestack.net/) for support. -# Fast, Simple, Typed ORM for .NET +# Read ServiceStack.OrmLite Docs at [docs.servicestack.net/ormlite](https://docs.servicestack.net/ormlite/) -OrmLite's goal is to provide a convenient, DRY, config-free, RDBMS-agnostic typed wrapper that retains a high affinity with SQL, exposing intuitive APIs that generate predictable SQL and maps cleanly to (DTO-friendly) disconnected POCO's. This approach makes easier to reason-about your data access making it obvious what SQL is getting executed at what time, whilst mitigating unexpected behavior, implicit N+1 queries and leaky data access prevalent in Heavy ORMs. - -OrmLite was designed with a focus on the core objectives: - - * Provide a set of light-weight C# extension methods around .NET's impl-agnostic `System.Data.*` interfaces - * Map a POCO class 1:1 to an RDBMS table, cleanly by conventions, without any attributes required. - * Create/Drop DB Table schemas using nothing but POCO class definitions (IOTW a true code-first ORM) - * Simplicity - typed, wrist friendly API for common data access patterns. - * High performance - with support for indexes, text blobs, etc. - * Amongst the [fastest Micro ORMs](http://servicestack.net/benchmarks/) for .NET (just behind [Dapper](http://code.google.com/p/dapper-dot-net/)). - * Expressive power and flexibility - with access to IDbCommand and raw SQL - * Cross platform - supports multiple dbs (currently: Sql Server, Sqlite, MySql, PostgreSQL, Firebird) running on both .NET and Mono platforms. - -In OrmLite: **1 Class = 1 Table**. There should be no surprising or hidden behaviour. -Any non-scalar properties (i.e. complex types) are by default text blobbed in a schema-less text field using any of the [avilable pluggable text serializers](#pluggable-complex-type-serializers). Support for [POCO-friendly references](#reference-support-poco-style) is also available to provide a convenient API to persist related models. Effectively this allows you to create a table from any POCO type and it should persist as expected in a DB Table with columns for each of the classes 1st level public properties. - -# Download - -[![Download on NuGet](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/release-notes/install-ormlite.png)](https://www.nuget.org/packages?q=servicestack+ormlite) - -### 8 flavours of OrmLite is on NuGet: - - - [ServiceStack.OrmLite.Sql Server](http://nuget.org/List/Packages/ServiceStack.OrmLite.SqlServer) - - [ServiceStack.OrmLite.MySql](http://nuget.org/List/Packages/ServiceStack.OrmLite.MySql) - - [ServiceStack.OrmLite.PostgreSQL](http://nuget.org/List/Packages/ServiceStack.OrmLite.PostgreSQL) - - [ServiceStack.OrmLite.Sqlite.Mono](http://nuget.org/packages/ServiceStack.OrmLite.Sqlite.Mono) - Compatible with Mono / Windows (x86) - - [ServiceStack.OrmLite.Sqlite.Windows](http://nuget.org/List/Packages/ServiceStack.OrmLite.Sqlite.Windows) - 32/64bit Mixed mode .NET for WIndows only - - [ServiceStack.OrmLite.Oracle](http://nuget.org/packages/ServiceStack.OrmLite.Oracle) (unofficial) - - [ServiceStack.OrmLite.Firebird](http://nuget.org/List/Packages/ServiceStack.OrmLite.Firebird) (unofficial) - - [ServiceStack.OrmLite.VistaDb](http://nuget.org/List/Packages/ServiceStack.OrmLite.VistaDb) (unofficial) - -_Latest v4+ on NuGet is a commercial release with [free quotas](https://servicestack.net/download#free-quotas)._ - -#### [Docs and Downloads for older v3 BSD releases](https://github.com/ServiceStackV3/ServiceStackV3) - -### Copying - -Since September 2013, ServiceStack source code is available under GNU Affero General Public License/FOSS License Exception, see license.txt in the source. Alternative [commercial licensing](https://servicestack.net/ormlite) is also available. - -### Contributing - -Contributors need to approve the [Contributor License Agreement](https://docs.google.com/forms/d/16Op0fmKaqYtxGL4sg7w_g-cXXyCoWjzppgkuqzOeKyk/viewform) before submitting pull-requests, see the [Contributing wiki](https://github.com/ServiceStack/ServiceStack/wiki/Contributing) for more details. - -*** - -# Async API Overview - -A quick overview of Async API's can be seen in the class diagram below: - -![OrmLite Async APIs](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/ormlite/OrmLiteApiAsync.png) - -Essentially most of OrmLite public API's now have async equivalents of the same name and an additional conventional `*Async` suffix. -The Async API's also take an optional `CancellationToken` making converting sync code trivial, where you just need to -add the `Async` suffix and **await** keyword, as can be seen in the -[Customer Orders UseCase upgrade to Async diff](https://github.com/ServiceStack/ServiceStack.OrmLite/commit/c1ce6f0eac99133fc232b263c26c42379d4c5f48) -, e.g: - -Sync: - -```csharp -db.Insert(new Employee { Id = 1, Name = "Employee 1" }); -db.Save(product1, product2); -var customer = db.Single(new { customer.Email }); -``` - -Async: - -```csharp -await db.InsertAsync(new Employee { Id = 1, Name = "Employee 1" }); -await db.SaveAsync(product1, product2); -var customer = await db.SingleAsync(new { customer.Email }); -``` - -> Effectively the only Data Access API's that doesn't have async equivalents are `*Lazy` APIs yielding a lazy -> sequence (incompatible with async) as well as **Schema** DDL API's which are typically not used at runtime. - -For a quick preview of many of the new Async API's in action, checkout -[ApiSqlServerTestsAsync.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLiteV45.Tests/ApiSqlServerTestsAsync.cs). - -### Async RDBMS Providers - -Currently only a limited number of RDBMS providers offer async API's which are only available in their **.NET 4.5** builds, which at this time are only: - - - [SQL Server .NET 4.5+](https://www.nuget.org/packages/ServiceStack.OrmLite.SqlServer) - - [MySQL .NET 4.5+](https://www.nuget.org/packages/ServiceStack.OrmLite.MySql) - -We've also added a -[.NET 4.5 build for Sqlite](https://www.nuget.org/packages/ServiceStack.OrmLite.Sqlite.Mono) -as it's a common use-case to swapout to use Sqlite's in-memory provider for faster tests. -But as Sqlite doesn't provide async API's under-the-hood we fallback to *pseudo async* support where we just wrap its synchronous responses in `Task` results. - -# API Examples - -OrmLite's SQL Expression support lets you use LINQ-liked querying in all our providers. -To give you a flavour here are some examples with their partial SQL output (using SqlServer dialect): - -### Querying with SELECT - -```csharp -int agesAgo = DateTime.Today.AddYears(-20).Year; -db.Select(q => q.Birthday >= new DateTime(agesAgo, 1, 1) - && q.Birthday <= new DateTime(agesAgo, 12, 31)); -``` - -**WHERE (("Birthday" >= '1992-01-01 00:00:00.000') AND ("Birthday" <= '1992-12-31 00:00:00.000'))** - -```csharp -db.Select(q => Sql.In(q.City, "London", "Madrid", "Berlin")); -``` - -**WHERE "JobCity" In ('London', 'Madrid', 'Berlin')** - -```csharp -db.Select(q => q.Earnings <= 50); -``` - -**WHERE ("Earnings" <= 50)** - -```csharp -db.Select(q => q.Name.StartsWith("A")); -``` - -**WHERE upper("Name") like 'A%'** - -```csharp -db.Select(q => q.Name.EndsWith("garzon")); -``` - -**WHERE upper("Name") like '%GARZON'** - -```csharp -db.Select(q => q.Name.Contains("Benedict")); -``` - -**WHERE upper("Name") like '%BENEDICT%'** - -```csharp -db.Select(q => q.Rate == 10 && q.City == "Mexico"); -``` - -**WHERE (("Rate" = 10) AND ("JobCity" = 'Mexico'))** - -Right now the Expression support can satisfy most simple queries with a strong-typed API. -For anything more complex (e.g. queries with table joins) you can still easily fall back to raw SQL queries as seen below. - -### Convenient common usage data access patterns - -OrmLite also includes a number of convenient API's providing DRY, typed data access for common queries: - -```csharp -Person personById = db.SingleById(1); -``` - -**SELECT "Id", "FirstName", "LastName", "Age" FROM "Person" WHERE "Id" = @Id** - -```csharp -Person personByAge = db.Single(x => x.Age == 42); -``` - -**SELECT TOP 1 "Id", "FirstName", "LastName", "Age" FROM "Person" WHERE ("Age" = 42)** - -```csharp -int maxAgeUnder50 = db.Scalar(x => Sql.Max(x.Age), x => x.Age < 50); -``` - -**SELECT Max("Age") FROM "Person" WHERE ("Age" < 50)** - -```csharp -int peopleOver40 = db.Scalar( - db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); -``` - -**SELECT COUNT(*) FROM "Person" WHERE ("Age" > 40)** - -```csharp -int peopleUnder50 = db.Count(x => x.Age < 50); -``` - -**SELECT COUNT(*) FROM "Person" WHERE ("Age" < 50)** - -```csharp -bool has42YearOlds = db.Exists(new { Age = 42 }); -``` - -**WHERE "Age" = @Age** - -```csharp -List results = db.Column(db.From().Select(x => x.LastName) - .Where(q => q.Age == 27)); -``` - -**SELECT "LastName" FROM "Person" WHERE ("Age" = 27)** - -```csharp -HashSet results = db.ColumnDistinct(db.From().Select(x => x.Age) - .Where(q => q.Age < 50)); -``` - -**SELECT "Age" FROM "Person" WHERE ("Age" < 50)** - -```csharp -Dictionary results = db.Dictionary( - db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); -``` - -**SELECT "Id","LastName" FROM "Person" WHERE ("Age" < 50)** - - -```csharp -Dictionary> results = db.Lookup( - db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); -``` - -**SELECT "Age","LastName" FROM "Person" WHERE ("Age" < 50)** - -### INSERT, UPDATE and DELETEs - -To see the behaviour of the different APIs, all examples uses this simple model - -```csharp -public class Person -{ - public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public int? Age { get; set; } -} -``` - -### UPDATE - -In its most simple form, updating any model without any filters will update every field, except the **Id** which -is used to filter the update to this specific record: - -```csharp -db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27}); -``` -**UPDATE "Person" SET "FirstName" = 'Jimi',"LastName" = 'Hendrix',"Age" = 27 WHERE "Id" = 1** - -If you supply your own where expression, it updates every field (inc. Id) but uses your filter instead: - -```csharp -db.Update(new Person { Id = 1, FirstName = "JJ" }, p => p.LastName == "Hendrix"); -``` -**UPDATE "Person" SET "Id" = 1,"FirstName" = 'JJ',"LastName" = NULL,"Age" = NULL WHERE ("LastName" = 'Hendrix')** - -One way to limit the fields which gets updated is to use an **Anonymous Type**: - -```csharp -db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); -``` - -Or by using `UpdateNonDefaults` which only updates the non-default values in your model using the filter specified: - -```csharp -db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); -``` - -**UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix')** - -#### UpdateOnly - -As updating a partial row is a common use-case in Db's, we've added a number of methods for just -this purpose, named **UpdateOnly**. - -The first expression in an `UpdateOnly` statement is used to specify which fields should be updated: -```csharp -db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName); -``` -**UPDATE "Person" SET "FirstName" = 'JJ'** - -```csharp -db.UpdateOnly(new Person { FirstName = "JJ", Age = 12 }, - onlyFields: p => new { p.FirstName, p.Age }); -``` -**UPDATE "Person" SET "FirstName" = 'JJ', "Age" = 12** - -When present, the second expression is used as the where filter: -```csharp -db.UpdateOnly(new Person { FirstName = "JJ" }, - onlyFields: p => p.FirstName, - where: p => p.LastName == "Hendrix"); -``` -**UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix')** - -Instead of using the expression filters above you can choose to use an ExpressionVisitor builder which provides more flexibility when you want to programatically construct the update statement: - -```csharp -db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, - onlyFields: q => q.Update(p => p.FirstName)); -``` -**UPDATE "Person" SET "FirstName" = 'JJ'** - -```csharp -db.UpdateOnly(new Person { FirstName = "JJ" }, - onlyFields: q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); -``` -**UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix')** - -For the ultimate flexibility we also provide un-typed, string-based expressions. Use the `.Params()` extension method escape parameters (inspired by [massive](https://github.com/robconery/massive)): - -```csharp -db.Update(set: "FirstName = {0}".Params("JJ"), - where: "LastName = {0}".Params("Hendrix")); -``` -Even the Table name can be a string so you perform the same update without requiring the Person model at all: - -```csharp -db.Update(table: "Person", set: "FirstName = {0}".Params("JJ"), - where: "LastName = {0}".Params("Hendrix")); -``` -**UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'** - -### INSERT - -Insert's are pretty straight forward since in most cases you want to insert every field: - -```csharp -db.Insert(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); -``` -**INSERT INTO "Person" ("Id","FirstName","LastName","Age") VALUES (1,'Jimi','Hendrix',27)** - -But do provide an API that takes an Expression Visitor for the rare cases you don't want to insert every field - -```csharp -db.InsertOnly(new Person { FirstName = "Amy" }, q => q.Insert(p => new {p.FirstName})) -``` -**INSERT INTO "Person" ("FirstName") VALUES ('Amy')** - -### DELETE - -Like updates for DELETE's we also provide APIs that take a where Expression: -```csharp -db.Delete(p => p.Age == 27); -``` - -Or an Expression Visitor: -```csharp -db.Delete(q => q.Where(p => p.Age == 27)); -``` - -**DELETE FROM "Person" WHERE ("Age" = 27)** - -As well as un-typed, string-based expressions: -```csharp -db.Delete(where: "Age = {0}".Params(27)); -``` - -Which also can take a table name so works without requiring a typed **Person** model -```csharp -db.Delete(table: "Person", where: "Age = {0}".Params(27)); -``` - -**DELETE FROM "Person" WHERE Age = 27** - -# API Overview - -The API is minimal, providing basic shortcuts for the primitive SQL statements: - -[![OrmLite API](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/ormlite/OrmLiteApi.png)](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/ormlite/OrmLiteApi.png) - -### Notes - -OrmLite Extension methods hang off ADO.NET's `IDbConnection`. - -`CreateTable` and `DropTable` create and drop tables based on a classes type definition (only public properties used). - -By default the Select API's use parameterized SQL whilst any selection methods ending with **Fmt** allow you to construct Sql using C# `string.Format()` syntax. - -If your SQL doesn't start with a **SELECT** statement, it is assumed a WHERE clause is being provided, e.g: - -```csharp -var tracks = db.SelectFmt("Artist = {0} AND Album = {1}", - "Nirvana", - "Heart Shaped Box"); -``` - -Which is equivalent to: - -```csharp -var tracks = db.SelectFmt("SELECT * FROM track WHERE Artist={0} AND Album={1}", - "Nirvana", - "Heart Shaped Box"); -``` - -**Select** returns multiple records: - -```csharp -List tracks = db.Select() -``` - -**Single** returns a single record: - -```csharp -Track track = db.Single(q => q.RefId == refId) -``` - -**Dictionary** returns a Dictionary made from the first two columns: - -```csharp -Dictionary trackIdNamesMap = db.Dictionary( - "select Id, Name from Track") -``` - -**Lookup** returns an `Dictionary>` made from the first two columns: - -```csharp -Dictionary> albumTrackNames = db.Lookup( - "select AlbumId, Name from Track") -``` - -**Column** returns a List of first column values: - -```csharp -List trackNames = db.Column("select Name from Track") -``` - -**HashSet** returns a HashSet of distinct first column values: - -```csharp -HashSet uniqueTrackNames = db.ColumnDistinct("select Name from Track") -``` - -**Scalar** returns a single scalar value: - -```csharp -var trackCount = db.Scalar("select count(*) from Track") -``` - -Anonymous types passed into **Where** are treated like an **AND** filter: - -```csharp -var track3 = db.Where(new { AlbumName = "Throwing Copper", TrackNo = 3 }) -``` - -**Select** statements take in parameterized SQL using properties from the supplied anonymous type (if any): - -```csharp -var track3 = db.Select( - "select * from Track Where AlbumName = @album and TrackNo = @trackNo", - new { album = "Throwing Copper", trackNo = 3 }) -``` - -SingleById(s), SelectById(s), etc provide strong-typed convenience methods to fetch by a Table's **Id** primary key field. - -```csharp -var track = db.SingleById(1); -var tracks = db.SelectByIds(new[]{ 1,2,3 }); -``` - -### Other Notes - - - All **Insert**, **Update**, and **Delete** methods take multiple params, while `InsertAll`, `UpdateAll` and `DeleteAll` take IEnumerables. - - `Save` and `SaveAll` will Insert if no record with **Id** exists, otherwise it Updates. - - Methods containing the word **Each** return an IEnumerable and are lazily loaded (i.e. non-buffered). - - -# Features - -Whilst OrmLite aims to provide a light-weight typed wrapper around SQL, it offers a number of convenient features that makes working with RDBMS's a clean and enjoyable experience: - -## Typed SqlExpression support for JOIN's - -Starting with the most basic example you can simply specify the table you want to join with: - -```csharp -var dbCustomers = db.Select(q => q.Join()); -``` - -This query rougly maps to the following SQL: - -```sql -SELECT Customer.* - FROM Customer - INNER JOIN - CustomerAddress ON (Customer.Id == CustomerAddress.Id) -``` - -Just like before `q` is an instance of `SqlExpression` which is bounded to the base `Customer` type (and what any subsequent implicit API's apply to). - -To better illustrate the above query, lets expand it to the equivalent explicit query: - -```csharp -SqlExpression q = db.From(); -q.Join((cust,address) => cust.Id == address.CustomerId); - -List dbCustomers = db.Select(q); -``` - -### Reference Conventions - -The above query implicitly joins together the `Customer` and `CustomerAddress` POCO's using the same `{ParentType}Id` property convention used in [OrmLite's support for References](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs), e.g: - -```csharp -class Customer { - public int Id { get; set; } - ... -} -class CustomerAddress { - public int Id { get; set; } - public int CustomerId { get; set; } // Reference based on Property name convention -} -``` - -References based on matching alias names is also supported, e.g: - -```csharp -[Alias("LegacyCustomer")] -class Customer { - public int Id { get; set; } - ... -} -class CustomerAddress { - public int Id { get; set; } - - [Alias("LegacyCustomerId")] // Matches `LegacyCustomer` Alias - public int RenamedCustomerId { get; set; } // Reference based on Alias Convention -} -``` - -### Self References - -Self References are also supported for **1:1** relations where the Foreign Key can instead be on the parent table: - -```csharp -public class Customer -{ - ... - public int CustomerAddressId { get; set; } - - [Reference] - public CustomerAddress PrimaryAddress { get; set; } -} -``` - -### Foreign Key and References Attributes - -References that don't follow the above naming conventions can be declared explicitly using -the `[References]` and `[ForeignKey]` attributes: - -```csharp -public class Customer -{ - [References(typeof(CustomerAddress))] - public int PrimaryAddressId { get; set; } - - [Reference] - public CustomerAddress PrimaryAddress { get; set; } -} -``` - -> Reference Attributes take precedence over naming conventions - -### Multiple Self References - -The example below shows a customer with multiple `CustomerAddress` references which are able to be matched with -the `{PropertyReference}Id` naming convention, e.g: - -```csharp -public class Customer -{ - [AutoIncrement] - public int Id { get; set; } - public string Name { get; set; } - - [References(typeof(CustomerAddress))] - public int? HomeAddressId { get; set; } - - [References(typeof(CustomerAddress))] - public int? WorkAddressId { get; set; } - - [Reference] - public CustomerAddress HomeAddress { get; set; } - - [Reference] - public CustomerAddress WorkAddress { get; set; } -} -``` - -Once defined, it can be saved and loaded via OrmLite's normal Reference and Select API's, e.g: - -```csharp -var customer = new Customer -{ - Name = "The Customer", - HomeAddress = new CustomerAddress { - Address = "1 Home Street", - Country = "US" - }, - WorkAddress = new CustomerAddress { - Address = "2 Work Road", - Country = "UK" - }, -}; - -db.Save(customer, references:true); - -var c = db.LoadSelect(q => q.Name == "The Customer"); -c.WorkAddress.Address.Print(); // 2 Work Road - -var ukAddress = db.Single(q => q.Country == "UK"); -ukAddress.Address.Print(); // 2 Work Road -``` - -### Implicit Reference Conventions are applied by default - -The implicit relationship above allows you to use any of these equilvalent APIs to JOIN tables: - -```csharp -q.Join(); -q.Join(); -q.Join((cust,address) => cust.Id == address.CustomerId); -``` - -### Selecting multiple columns across joined tables - -Another implicit behaviour when selecting from a typed SqlExpression is that results are mapped to the `Customer` POCO. To change this default we just need to explicitly specify what POCO it should map to instead: - -```csharp -List customers = db.Select( - db.From().Join()); -``` - -Where `FullCustomerInfo` is any POCO that contains a combination of properties matching any of the joined tables in the query. - -The above example is also equivalent to the shorthand `db.Select()` API: - -```csharp -var customers = db.Select(q => q.Join()); -``` - -Rules for how results are mapped is simply each property on `FullCustomerInfo` is mapped to the first matching property in any of the tables in the order they were added to the SqlExpression. - -The mapping also includes a fallback for referencing fully-qualified names in the format: `{TableName}{FieldName}` allowing you to reference ambiguous fields, e.g: - - - `CustomerId` => "Customer"."Id" - - `OrderId` => "Order"."Id" - - `CustomerName` => "Customer"."Name" - - `OrderCost` => "Order"."Cost" - -### Advanced Example - -Seeing how the SqlExpression is constructed, joined and mapped, we can take a look at a more advanced example to showcase more of the new API's available: - -```csharp -List rows = db.Select( // Map results to FullCustomerInfo POCO - db.From() // Create typed Customer SqlExpression - .LeftJoin() // Implict left join with base table - .Join((c,o) => c.Id == o.CustomerId) // Explicit join and condition - .Where(c => c.Name == "Customer 1") // Implicit condition on base table - .And(o => o.Cost < 2) // Explicit condition on joined Table - .Or((c,o) => c.Name == o.LineItem)); // Explicit condition with joined Tables -``` - -The comments next to each line document each Type of API used. Some of the new API's introduced in this example include: - - - Usage of `LeftJoin` for specifying a LEFT JOIN, `RightJoin` and `FullJoin` also available - - Usage of `And()`, to specify an **AND** condition on a Joined table - - Usage of `Or`, to specify an **OR** condition against 2 joined tables - -More code examples of References and Joined tables are available in: - - - [LoadReferencesTests.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs) - - [LoadReferencesJoinTests.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesJoinTests.cs) - -### Reference Support, POCO style - -OrmLite lets you Store and Load related entities in separate tables using `[Reference]` attributes in primary tables in conjunction with `{Parent}Id` property convention in child tables, e.g: - -```csharp -public class Customer -{ - [AutoIncrement] - public int Id { get; set; } - public string Name { get; set; } - - [Reference] // Save in CustomerAddress table - public CustomerAddress PrimaryAddress { get; set; } - - [Reference] // Save in Order table - public List Orders { get; set; } -} - -public class CustomerAddress -{ - [AutoIncrement] - public int Id { get; set; } - public int CustomerId { get; set; } //`{Parent}Id` convention to refer to Customer - public string AddressLine1 { get; set; } - public string AddressLine2 { get; set; } - public string City { get; set; } - public string State { get; set; } - public string Country { get; set; } -} - -public class Order -{ - [AutoIncrement] - public int Id { get; set; } - public int CustomerId { get; set; } //`{Parent}Id` convention to refer to Customer - public string LineItem { get; set; } - public int Qty { get; set; } - public decimal Cost { get; set; } -} -``` - -With the above structure you can save a POCO and all its entity references with `db.Save(T,references:true)`, e.g: - -```csharp -var customer = new Customer { - Name = "Customer 1", - PrimaryAddress = new CustomerAddress { - AddressLine1 = "1 Australia Street", - Country = "Australia" - }, - Orders = new[] { - new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, - new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, - }.ToList(), -}; - -db.Save(customer, references:true); -``` - -This saves the root customer POCO in the `Customer` table, its related PrimaryAddress in the `CustomerAddress` table and its 2 Orders in the `Order` table. - -### Querying POCO's with References - -The `Load*` API's are used to automatically load a POCO and all it's child references, e.g: - -```csharp -var customer = db.LoadSingleById(customerId); -``` - -Using Typed SqlExpressions: - -```csharp -var customers = db.LoadSelect(q => q.Name == "Customer 1"); -``` - -More examples available in [LoadReferencesTests.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs) - -Unlike normal complex properties, references: - - - Doesn't persist as complex type blobs - - Doesn't impact normal querying - - Saves and loads references independently from itself - - Are serializable with Text serializers (only populated are visible). - - Loads related data only 1-reference-level deep - -Basically they provides a better story when dealing with referential data that doesn't impact the POCO's ability to be used as DTO's. - -## Optimistic Concurrency - -Optimistic concurrency can be added to any table by adding the `ulong RowVersion { get; set; }` property, e.g: - -```csharp -public class Poco -{ - ... - public ulong RowVersion { get; set; } -} -``` - -RowVersion is implemented efficiently in all major RDBMS's, i.e: - - - Uses `rowversion` datatype in SqlServer - - Uses PostgreSql's `xmin` system column (no column on table required) - - Uses UPDATE triggers on MySql, Sqlite and Oracle whose lifetime is attached to Create/Drop tables APIs - -Despite their differing implementations each provider works the same way where the `RowVersion` property is populated when the record is selected and only updates the record if the RowVersion matches with what's in the database, e.g: - -```csharp -var rowId = db.Insert(new Poco { Text = "Text" }, selectIdentity:true); - -var row = db.SingleById(rowId); -row.Text += " Updated"; -db.Update(row); //success! - -row.Text += "Attempting to update stale record"; - -//Can't update stale record -Assert.Throws(() => - db.Update(row)); - -//Can update latest version -var updatedRow = db.SingleById(rowId); // fresh version -updatedRow.Text += "Update Success!"; -db.Update(updatedRow); - -updatedRow = db.SingleById(rowId); -db.Delete(updatedRow); // can delete fresh version -``` - -Optimistic concurrency is only verified on API's that update or delete an entire entity, i.e. it's not enforced in partial updates. There's also an Alternative API available for DELETE's: - -```csharp -db.DeleteById(id:updatedRow.Id, rowversion:updatedRow.RowVersion) -``` - -### Exec, Result and String Filters - -OrmLite's core Exec filters makes it possible to inject your own behavior, tracing, profiling, etc. - -It's useful in situations like wanting to use SqlServer in production but use an `in-memory` Sqlite database in tests and being able to emulate any missing SQL Server Stored Procedures in code: - -```csharp -public class MockStoredProcExecFilter : OrmLiteExecFilter -{ - public override T Exec(IDbConnection dbConn, Func filter) - { - try - { - return base.Exec(dbConn, filter); - } - catch (Exception ex) - { - if (dbConn.GetLastSql() == "exec sp_name @firstName, @age") - return (T)(object)new Person { FirstName = "Mocked" }; - throw; - } - } -} - -OrmLiteConfig.ExecFilter = new MockStoredProcExecFilter(); - -using (var db = OpenDbConnection()) -{ - var person = db.SqlScalar("exec sp_name @firstName, @age", - new { firstName = "aName", age = 1 }); - - person.FirstName.Print(); //Mocked -} -``` - -Results filters makes it trivial to implement the `CaptureSqlFilter` which allows you to capture SQL Statements without running them, e.g: - -```csharp -public class CaptureSqlFilter : OrmLiteResultsFilter -{ - public CaptureSqlFilter() - { - SqlFilter = CaptureSql; - SqlStatements = new List(); - } - - private void CaptureSql(string sql) - { - SqlStatements.Add(sql); - } - - public List SqlStatements { get; set; } -} -``` - -Which can be used to wrap around existing database calls to capture, defer or print generated SQL, e.g: - -```csharp -using (var captured = new CaptureSqlFilter()) -using (var db = OpenDbConnection()) -{ - db.CreateTable(); - db.Count(x => x.Age < 50); - db.Insert(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" }); - db.Delete(new { FirstName = "Jimi", Age = 27 }); - - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); -} -``` - -### Replay Exec Filter - -Or if you want to do things like executing each operation multiple times, e.g: - -```csharp -public class ReplayOrmLiteExecFilter : OrmLiteExecFilter -{ - public int ReplayTimes { get; set; } - - public override T Exec(IDbConnection dbConn, Func filter) - { - var holdProvider = OrmLiteConfig.DialectProvider; - var dbCmd = CreateCommand(dbConn); - try - { - var ret = default(T); - for (var i = 0; i < ReplayTimes; i++) - { - ret = filter(dbCmd); - } - return ret; - } - finally - { - DisposeCommand(dbCmd); - OrmLiteConfig.DialectProvider = holdProvider; - } - } -} - -OrmLiteConfig.ExecFilter = new ReplayOrmLiteExecFilter { ReplayTimes = 3 }; - -using (var db = OpenDbConnection()) -{ - db.DropAndCreateTable(); - db.Insert(new PocoTable { Name = "Multiplicity" }); - - var rowsInserted = db.Count(q => q.Name == "Multiplicity"); //3 -} -``` - - -## Mockable extension methods - -The Result Filters also lets you easily mock results and avoid hitting the database, typically useful in Unit Testing Services to mock OrmLite API's directly instead of using a repository, e.g: - -```csharp -using (new OrmLiteResultsFilter { - PrintSql = true, - SingleResult = new Person { - Id = 1, FirstName = "Mocked", LastName = "Person", Age = 100 - }, -}) -{ - db.Single(x => x.Age == 42).FirstName // Mocked - db.Single(db.From().Where(x => x.Age == 42)).FirstName // Mocked - db.Single(new { Age = 42 }).FirstName // Mocked - db.Single("Age = @age", new { age = 42 }).FirstName // Mocked -} -``` - -More examples showing how to mock different API's including support for nesting available in [MockAllApiTests.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/MockAllApiTests.cs) - -### String Filter - -There's also a specific filter for strings available which allows you to apply custom sanitization on String fields, e.g. you can ensure all strings are right trimmed with: - -```csharp -OrmLiteConfig.StringFilter = s => s.TrimEnd(); - -db.Insert(new Poco { Name = "Value with trailing " }); -db.Select().First().Name // "Value with trailing" -``` - -## Pluggable Complex Type Serializers - -Pluggable serialization lets you specify different serialization strategies of Complex Types for each available RDBMS provider, e.g: - -```csharp -//ServiceStack's JSON and JSV Format -SqliteDialect.Provider.StringSerializer = new JsvStringSerializer(); -PostgreSqlDialect.Provider.StringSerializer = new JsonStringSerializer(); -//.NET's XML and JSON DataContract serializers -SqlServerDialect.Provider.StringSerializer = new DataContractSerializer(); -MySqlDialect.Provider.StringSerializer = new JsonDataContractSerializer(); -//.NET XmlSerializer -OracleDialect.Provider.StringSerializer = new XmlSerializableSerializer(); -``` -You can also provide a custom serialization strategy by implementing -[IStringSerializer](https://github.com/ServiceStack/ServiceStack.Text/blob/master/src/ServiceStack.Text/IStringSerializer.cs). - -By default all dialects use the existing `JsvStringSerializer`, except for PostgreSQL which due to its built-in support for JSON, uses the JSON format by default. - -## Global Insert / Update Filters - -Similar to interceptors in some heavy ORM's, Insert and Update filters get fired just before any **INSERT** or **UPDATE** operation using OrmLite's typed API's (i.e. not dynamic SQL or partial updates using anon types). This functionality can be used for easily auto-maintaining Audit information for your POCO data models, e.g: - -```csharp -public interface IAudit -{ - DateTime CreatedDate { get; set; } - DateTime ModifiedDate { get; set; } - string ModifiedBy { get; set; } -} - -OrmLiteConfig.InsertFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null) - auditRow.CreatedDate = auditRow.ModifiedDate = DateTime.UtcNow; -}; - -OrmLiteConfig.UpdateFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null) - auditRow.ModifiedDate = DateTime.UtcNow; -}; -``` - -Which will ensure that the `CreatedDate` and `ModifiedDate` fields are populated on every insert and update. - -### Validation Example - -The filters can also be used for validation where throwing an exception will prevent the operation and bubble the exception, e.g: - -```csharp -OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null && auditRow.ModifiedBy == null) - throw new ArgumentNullException("ModifiedBy"); -}; - -try -{ - db.Insert(new AuditTable()); -} -catch (ArgumentNullException) { - //throws ArgumentNullException -} - -db.Insert(new AuditTable { ModifiedBy = "Me!" }); //succeeds -``` - -## Custom SQL Customizations - -A number of new hooks are available to provide more flexibility when creating and dropping your RDBMS tables. - -### Custom Field Declarations - -The `[CustomField]` attribute can be used for specifying custom field declarations in the generated Create table DDL statements, e.g: - -```csharp -public class PocoTable -{ - public int Id { get; set; } - - [CustomField("CHAR(20)")] - public string CharColumn { get; set; } - - [CustomField("DECIMAL(18,4)")] - public decimal? DecimalColumn { get; set; } -} - -db.CreateTable(); -``` - -Generates and executes the following SQL: - -```sql -CREATE TABLE "PocoTable" -( - "Id" INTEGER PRIMARY KEY, - "CharColumn" CHAR(20) NULL, - "DecimalColumn" DECIMAL(18,4) NULL -); -``` - -#### Pre / Post Custom SQL Hooks when Creating and Dropping tables - -Pre / Post Custom SQL Hooks allow you to inject custom SQL before and after tables are created or dropped, e.g: - -```csharp -[PostCreateTable("INSERT INTO TableWithSeedData (Name) VALUES ('Foo');" + - "INSERT INTO TableWithSeedData (Name) VALUES ('Bar');")] -public class TableWithSeedData -{ - [AutoIncrement] - public int Id { get; set; } - public string Name { get; set; } -} -``` - -Which like other ServiceStack attributes, can also be added dynamically, e.g: - -```csharp -typeof(TableWithSeedData) - .AddAttributes(new PostCreateTableAttribute( - "INSERT INTO TableWithSeedData (Name) VALUES ('Foo');" + - "INSERT INTO TableWithSeedData (Name) VALUES ('Bar');")); -``` - -Custom SQL Hooks also allow executing custom SQL before and after a table has been created or dropped, i.e: - -```csharp -[PreCreateTable(runSqlBeforeTableCreated)] -[PostCreateTable(runSqlAfterTableCreated)] -[PreDropTable(runSqlBeforeTableDropped)] -[PostDropTable(runSqlAfterTableDropped)] -public class Table {} -``` - -### Untyped API support - -The [IUntypedApi](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/src/ServiceStack.OrmLite/IUntypedApi.cs) interface is useful for when you only have access to a late-bound object runtime type which is accessible via `db.CreateTypedApi`, e.g: - -```csharp -public class BaseClass -{ - public int Id { get; set; } -} - -public class Target : BaseClass -{ - public string Name { get; set; } -} - -var row = (BaseClass)new Target { Id = 1, Name = "Foo" }; - -var useType = row.GetType(); -var typedApi = db.CreateTypedApi(useType); - -db.DropAndCreateTables(useType); - -typedApi.Save(row); - -var typedRow = db.SingleById(1); -typedRow.Name //= Foo - -var updateRow = (BaseClass)new Target { Id = 1, Name = "Bar" }; - -typedApi.Update(updateRow); - -typedRow = db.SingleById(1); -typedRow.Name //= Bar - -typedApi.Delete(typedRow, new { Id = 1 }); - -typedRow = db.SingleById(1); //= null -``` - -## T4 Template Support - -[OrmLite's T4 Template](https://github.com/ServiceStack/ServiceStack.OrmLite/tree/master/src/T4) -are useful in database-first development or when wanting to use OrmLite with an existing -RDBMS by automatically generating POCO's and strong-typed wrappers -for executing stored procedures. - -OrmLite's T4 support can be added via NuGet with: - - PM> Install-Package ServiceStack.OrmLite.T4 - -## Typed SqlExpressions with Custom SQL APIs - -The Custom SQL API's allow you to map custom SqlExpressions into different responses: - -```csharp -List results = db.SqlList( - db.From().Select("*").Where(q => q.Age < 50)); -List results = db.SqlList( - "SELECT * FROM Person WHERE Age < @age", new { age=50}); - -List results = db.SqlColumn(db.From().Select(x => x.LastName)); -List results = db.SqlColumn("SELECT LastName FROM Person"); - -HashSet results = db.ColumnDistinct(db.From().Select(x => x.Age)); -HashSet results = db.ColumnDistinct("SELECT Age FROM Person"); - -int result = db.SqlScalar( - db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); -int result = db.SqlScalar("SELCT COUNT(*) FROM Person WHERE Age < 50"); -``` - -## Stored Procedures using Custom Raw SQL API's - -The Raw SQL API's provide a convenient way for mapping results of any Custom SQL like -executing Stored Procedures: - -```csharp -List results = db.SqlList("EXEC GetAnalyticsForWeek 1"); -List results = db.SqlList( - "EXEC GetAnalyticsForWeek @weekNo", new { weekNo = 1 }); - -List results = db.SqlList("EXEC GetTotalsForWeek 1"); -List results = db.SqlList( - "EXEC GetTotalsForWeek @weekNo", new { weekNo = 1 }); - -int result = db.SqlScalar("SELECT 10"); -``` - -### Stored Procedures with output params - -The `SqlProc` API provides even greater customization by letting you modify the underlying -ADO.NET Stored Procedure call by returning a prepared `IDbCommand` allowing for -advanced customization like setting and retriving OUT parameters, e.g: - -```csharp -string spSql = @"DROP PROCEDURE IF EXISTS spSearchLetters; - CREATE PROCEDURE spSearchLetters (IN pLetter varchar(10), OUT pTotal int) - BEGIN - SELECT COUNT(*) FROM LetterFrequency WHERE Letter = pLetter INTO pTotal; - SELECT * FROM LetterFrequency WHERE Letter = pLetter; - END"; - -db.ExecuteSql(spSql); - -using (var cmd = db.SqlProc("spSearchLetters", new { pLetter = "C" })) -{ - var pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); - - var results = cmd.ConvertToList(); - var total = pTotal.Value; -} -``` - -An alternative approach is to use `SqlList` which lets you use a filter to customize a -Stored Procedure or any other command type, e.g: - -```csharp -IDbDataParameter pTotal = null; -var results = db.SqlList("spSearchLetters", cmd => { - cmd.CommandType = CommandType.StoredProcedure; - cmd.AddParam("pLetter", "C"); - pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); - }); -var total = pTotal.Value; -``` - -More examples can be found in [SqlServerProviderTests](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/SqlServerProviderTests.cs). - -## New Foreign Key attribute for referential actions on Update/Deletes - -Creating a foreign key in OrmLite can be done by adding `[References(typeof(ForeignKeyTable))]` on the relation property, -which will result in OrmLite creating the Foreign Key relationship when it creates the DB table with `db.CreateTable`. -[@brainless83](https://github.com/brainless83) has extended this support further by adding more finer-grain options -and behaviours with the new `[ForeignKey]` attribute which will now let you specify the desired behaviour when deleting -or updating related rows in Foreign Key tables. - -An example of a table with all the different options: - -```csharp -public class TableWithAllCascadeOptions -{ - [AutoIncrement] public int Id { get; set; } - - [References(typeof(ForeignKeyTable1))] - public int SimpleForeignKey { get; set; } - - [ForeignKey(typeof(ForeignKeyTable2), OnDelete = "CASCADE", OnUpdate = "CASCADE")] - public int? CascadeOnUpdateOrDelete { get; set; } - - [ForeignKey(typeof(ForeignKeyTable3), OnDelete = "NO ACTION")] - public int? NoActionOnCascade { get; set; } - - [Default(typeof(int), "17")] - [ForeignKey(typeof(ForeignKeyTable4), OnDelete = "SET DEFAULT")] - public int SetToDefaultValueOnDelete { get; set; } - - [ForeignKey(typeof(ForeignKeyTable5), OnDelete = "SET NULL")] - public int? SetToNullOnDelete { get; set; } -} -``` - -The [ForeignKeyTests](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/ForeignKeyAttributeTests.cs) -show the resulting behaviour with each of these configurations in more detail. - -> Note: Only supported on RDBMS's with foreign key/referential action support, e.g. -[Sql Server](http://msdn.microsoft.com/en-us/library/ms174979.aspx), -[PostgreSQL](http://www.postgresql.org/docs/9.1/static/ddl-constraints.html), -[MySQL](http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html). Otherwise they're ignored. - -## Multi nested database connections - -We now support multiple nested database connections so you can now trivially use OrmLite to access multiple databases -on different connections. The `OrmLiteConnectionFactory` class has been extended to support named connections which -allows you to conveniently define all your db connections when you register it in your IOC and access them with the -named property when you use them. - -A popular way of scaling RDBMS's is to create a Master / Shard setup where datasets for queries that span entire system -are kept in the master database, whilst context-specific related data can be kept together in an isolated shard. -This feature makes it trivial to maintain multiple separate db shards with a master database in a different RDBMS. - -Here's an (entire source code) sample of the code needed to define, and populate a Master/Shard setup. -Sqlite can create DB shards on the fly so only the blank SqlServer master database needed to be created out-of-band: - -### Sharding 1000 Robots into 10 Sqlite DB shards - referencing each in a Master SqlServer RDBMS - -```csharp -public class MasterRecord { - public Guid Id { get; set; } - public int RobotId { get; set; } - public string RobotName { get; set; } - public DateTime? LastActivated { get; set; } -} - -public class Robot { - public int Id { get; set; } - public string Name { get; set; } - public bool IsActivated { get; set; } - public long CellCount { get; set; } - public DateTime CreatedDate { get; set; } -} - -const int NoOfShards = 10; -const int NoOfRobots = 1000; - -var dbFactory = new OrmLiteConnectionFactory( - "Data Source=host;Initial Catalog=RobotsMaster;Integrated Security=SSPI", //Connection String - SqlServerDialect.Provider); - -dbFactory.Run(db => db.CreateTable(overwrite:false)); - -NoOfShards.Times(i => { - var namedShard = "robots-shard" + i; - dbFactory.RegisterConnection(namedShard, - "~/App_Data/{0}.sqlite".Fmt(shardId).MapAbsolutePath(), //Connection String - SqliteDialect.Provider); - - dbFactory.OpenDbConnection(namedShard).Run(db => db.CreateTable(overwrite:false)); -}); - -var newRobots = NoOfRobots.Times(i => //Create 1000 Robots - new Robot { Id=i, Name="R2D"+i, CreatedDate=DateTime.UtcNow, CellCount=DateTime.Now.ToUnixTimeMs() % 100000 }); - -foreach (var newRobot in newRobots) -{ - using (IDbConnection db = dbFactory.OpenDbConnection()) //Open Connection to Master DB - { - db.Insert(new MasterRecord { Id = Guid.NewGuid(), RobotId = newRobot.Id, RobotName = newRobot.Name }); - using (IDbConnection robotShard = dbFactory.OpenDbConnection("robots-shard"+newRobot.Id % NoOfShards)) //Shard - { - robotShard.Insert(newRobot); - } - } -} -``` - -Using the [SQLite Manager](https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/?src=search) Firefox extension -we can peek at one of the created shards to see 100 Robots in each shard. This is the dump of `robots-shard0.sqlite`: - -![Data dump of Robot Shard #1](http://mono.servicestack.net/files/robots-shard0.png) - -As expected each shard has every 10th robot inside. - -## Code-first Customer & Order example with complex types on POCO as text blobs - -Below is a complete stand-alone example. No other config or classes is required for it to run. It's also available as a -[stand-alone unit test](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCase.cs). - -```csharp -public enum PhoneType { - Home, - Work, - Mobile, -} - -public enum AddressType { - Home, - Work, - Other, -} - -public class Address { - public string Line1 { get; set; } - public string Line2 { get; set; } - public string ZipCode { get; set; } - public string State { get; set; } - public string City { get; set; } - public string Country { get; set; } -} - -public class Customer { - public Customer() { - this.PhoneNumbers = new Dictionary(); - this.Addresses = new Dictionary(); - } - - [AutoIncrement] // Creates Auto primary key - public int Id { get; set; } - - public string FirstName { get; set; } - public string LastName { get; set; } - - [Index(Unique = true)] // Creates Unique Index - public string Email { get; set; } - - public Dictionary PhoneNumbers { get; set; } //Blobbed - public Dictionary Addresses { get; set; } //Blobbed - public DateTime CreatedAt { get; set; } -} - -public class Order { - - [AutoIncrement] - public int Id { get; set; } - - [References(typeof(Customer))] //Creates Foreign Key - public int CustomerId { get; set; } - - [References(typeof(Employee))] //Creates Foreign Key - public int EmployeeId { get; set; } - - public Address ShippingAddress { get; set; } //Blobbed (no Address table) - - public DateTime? OrderDate { get; set; } - public DateTime? RequiredDate { get; set; } - public DateTime? ShippedDate { get; set; } - public int? ShipVia { get; set; } - public decimal Freight { get; set; } - public decimal Total { get; set; } -} - -public class OrderDetail { - - [AutoIncrement] - public int Id { get; set; } - - [References(typeof(Order))] //Creates Foreign Key - public int OrderId { get; set; } - - public int ProductId { get; set; } - public decimal UnitPrice { get; set; } - public short Quantity { get; set; } - public decimal Discount { get; set; } -} - -public class Employee { - public int Id { get; set; } - public string Name { get; set; } -} - -public class Product { - public int Id { get; set; } - public string Name { get; set; } - public decimal UnitPrice { get; set; } -} - -//Setup SQL Server Connection Factory -var dbFactory = new OrmLiteConnectionFactory( - @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\App_Data\Database1.mdf;Integrated Security=True;User Instance=True", - SqlServerDialect.Provider); - -//Use in-memory Sqlite DB instead -//var dbFactory = new OrmLiteConnectionFactory( -// ":memory:", false, SqliteDialect.Provider); - -//Non-intrusive: All extension methods hang off System.Data.* interfaces -using (IDbConnection db = Config.OpenDbConnection()) -{ - //Re-Create all table schemas: - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - - db.Insert(new Employee { Id = 1, Name = "Employee 1" }); - db.Insert(new Employee { Id = 2, Name = "Employee 2" }); - var product1 = new Product { Id = 1, Name = "Product 1", UnitPrice = 10 }; - var product2 = new Product { Id = 2, Name = "Product 2", UnitPrice = 20 }; - db.Save(product1, product2); - - var customer = new Customer { - FirstName = "Orm", - LastName = "Lite", - Email = "ormlite@servicestack.net", - PhoneNumbers = - { - { PhoneType.Home, "555-1234" }, - { PhoneType.Work, "1-800-1234" }, - { PhoneType.Mobile, "818-123-4567" }, - }, - Addresses = - { - { AddressType.Work, new Address { - Line1 = "1 Street", Country = "US", State = "NY", City = "New York", ZipCode = "10101" } - }, - }, - CreatedAt = DateTime.UtcNow, - }; - - var customerId = db.Insert(customer, selectIdentity: true); //Get Auto Inserted Id - customer = db.Single(new { customer.Email }); //Query - Assert.That(customer.Id, Is.EqualTo(customerId)); - - //Direct access to System.Data.Transactions: - using (IDbTransaction trans = db.OpenTransaction(IsolationLevel.ReadCommitted)) - { - var order = new Order { - CustomerId = customer.Id, - EmployeeId = 1, - OrderDate = DateTime.UtcNow, - Freight = 10.50m, - ShippingAddress = new Address { - Line1 = "3 Street", Country = "US", State = "NY", City = "New York", ZipCode = "12121" }, - }; - db.Save(order); //Inserts 1st time - - //order.Id populated on Save(). - - var orderDetails = new[] { - new OrderDetail { - OrderId = order.Id, - ProductId = product1.Id, - Quantity = 2, - UnitPrice = product1.UnitPrice, - }, - new OrderDetail { - OrderId = order.Id, - ProductId = product2.Id, - Quantity = 2, - UnitPrice = product2.UnitPrice, - Discount = .15m, - } - }; - - db.Save(orderDetails); - - order.Total = orderDetails.Sum(x => x.UnitPrice * x.Quantity * x.Discount) + order.Freight; - - db.Save(order); //Updates 2nd Time - - trans.Commit(); - } -} -``` - -Running this against a SQL Server database will yield the results below: - -[![SQL Server Management Studio results](http://mono.servicestack.net/files/ormlite-example.png)](http://www.servicestack.net/files/ormlite-example.png) - -Notice the POCO types are stored in the [very fast](http://mono.servicestack.net/mythz_blog/?p=176) -and [Versatile](http://mono.servicestack.net/mythz_blog/?p=314) -[JSV Format](https://github.com/ServiceStack/ServiceStack.Text/wiki/JSV-Format) which although hard to do - -is actually more compact, human and parser-friendly than JSON :) - -### Ignoring DTO Properties - -You may use the `[Ignore]` attribute to denote DTO properties that are not fields in the table. This will force the SQL generation to ignore that property. - -# More Examples - -In its simplest useage, OrmLite can persist any POCO type without any attributes required: - -```csharp -public class SimpleExample -{ - public int Id { get; set; } - public string Name { get; set; } -} - -//Set once before use (i.e. in a static constructor). -OrmLiteConfig.DialectProvider = SqliteDialect.Provider; - -using (IDbConnection db = "/path/to/db.sqlite".OpenDbConnection()) -{ - db.CreateTable(true); - db.Insert(new SimpleExample { Id=1, Name="Hello, World!"}); - var rows = db.Select(); - - Assert.That(rows, Has.Count(1)); - Assert.That(rows[0].Id, Is.EqualTo(1)); -} -``` - -To get a better idea of the features of OrmLite lets walk through a complete example using sample tables from the Northwind database. -_ (Full source code for this example is [available here](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/ShippersExample.cs).) _ - -So with no other configuration using only the classes below: - -```csharp -[Alias("Shippers")] -public class Shipper - : IHasId -{ - [AutoIncrement] - [Alias("ShipperID")] - public int Id { get; set; } - - [Required] - [Index(Unique = true)] - [StringLength(40)] - public string CompanyName { get; set; } - - [StringLength(24)] - public string Phone { get; set; } - - [References(typeof(ShipperType))] - public int ShipperTypeId { get; set; } -} - -[Alias("ShipperTypes")] -public class ShipperType - : IHasId -{ - [AutoIncrement] - [Alias("ShipperTypeID")] - public int Id { get; set; } - - [Required] - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set; } -} - -public class SubsetOfShipper -{ - public int ShipperId { get; set; } - public string CompanyName { get; set; } -} - -public class ShipperTypeCount -{ - public int ShipperTypeId { get; set; } - public int Total { get; set; } -} -``` - -### Creating tables -Creating tables is a simple 1-liner: - -```csharp -using (IDbConnection db = ":memory:".OpenDbConnection()) -{ - db.CreateTable(); - db.CreateTable(); -} - -/* In debug mode the line above prints: -DEBUG: CREATE TABLE "ShipperTypes" -( - "ShipperTypeID" INTEGER PRIMARY KEY AUTOINCREMENT, - "Name" VARCHAR(40) NOT NULL -); -DEBUG: CREATE UNIQUE INDEX uidx_shippertypes_name ON "ShipperTypes" ("Name" ASC); -DEBUG: CREATE TABLE "Shippers" -( - "ShipperID" INTEGER PRIMARY KEY AUTOINCREMENT, - "CompanyName" VARCHAR(40) NOT NULL, - "Phone" VARCHAR(24) NULL, - "ShipperTypeId" INTEGER NOT NULL, - - CONSTRAINT "FK_Shippers_ShipperTypes" FOREIGN KEY ("ShipperTypeId") REFERENCES "ShipperTypes" ("ShipperID") -); -DEBUG: CREATE UNIQUE INDEX uidx_shippers_companyname ON "Shippers" ("CompanyName" ASC); -*/ -``` - -### Transaction Support -As we have direct access to IDbCommand and friends - playing with transactions is easy: - -```csharp - var trainsType = new ShipperType { Name = "Trains" }; - var planesType = new ShipperType { Name = "Planes" }; - - //Playing with transactions - using (IDbTransaction dbTrans = db.OpenTransaction()) - { - db.Save(trainsType); - db.Save(planesType); - - dbTrans.Commit(); - } - - using (IDbTransaction dbTrans = db.OpenTransaction(IsolationLevel.ReadCommitted)) - { - db.Insert(new ShipperType { Name = "Automobiles" }); - Assert.That(db.Select(), Has.Count.EqualTo(3)); - } - Assert.That(db.Select(), Has.Count(2)); -``` - -### CRUD Operations -No ORM is complete without the standard crud operations: - -```csharp - //Performing standard Insert's and Selects - db.Insert(new Shipper { CompanyName = "Trains R Us", Phone = "555-TRAINS", ShipperTypeId = trainsType.Id }); - db.Insert(new Shipper { CompanyName = "Planes R Us", Phone = "555-PLANES", ShipperTypeId = planesType.Id }); - db.Insert(new Shipper { CompanyName = "We do everything!", Phone = "555-UNICORNS", ShipperTypeId = planesType.Id }); - - var trainsAreUs = db.SingleFmt("ShipperTypeId = {0}", trainsType.Id); - Assert.That(trainsAreUs.CompanyName, Is.EqualTo("Trains R Us")); - Assert.That(db.SelectFmt("CompanyName = {0} OR Phone = {1}", "Trains R Us", "555-UNICORNS"), Has.Count.EqualTo(2)); - Assert.That(db.SelectFmt("ShipperTypeId = {0}", planesType.Id), Has.Count.EqualTo(2)); - - //Lets update a record - trainsAreUs.Phone = "666-TRAINS"; - db.Update(trainsAreUs); - Assert.That(db.SingleById(trainsAreUs.Id).Phone, Is.EqualTo("666-TRAINS")); - - //Then make it dissappear - db.Delete(trainsAreUs); - Assert.That(db.SingleById(trainsAreUs.Id), Is.Null); - - //And bring it back again - db.Insert(trainsAreUs); -``` - -### Performing custom queries -And with access to raw sql when you need it - the database is your oyster :) - -```csharp - var partialColumns = db.SelectFmt(typeof (Shipper), "ShipperTypeId = {0}", planesType.Id); - Assert.That(partialColumns, Has.Count.EqualTo(2)); - - //Select into another POCO class that matches sql - var rows = db.SelectFmt( - "SELECT ShipperTypeId, COUNT(*) AS Total FROM Shippers GROUP BY ShipperTypeId ORDER BY COUNT(*)"); - - Assert.That(rows, Has.Count.EqualTo(2)); - Assert.That(rows[0].ShipperTypeId, Is.EqualTo(trainsType.Id)); - Assert.That(rows[0].Total, Is.EqualTo(1)); - Assert.That(rows[1].ShipperTypeId, Is.EqualTo(planesType.Id)); - Assert.That(rows[1].Total, Is.EqualTo(2)); - - - //And finally lets quickly clean up the mess we've made: - db.DeleteAll(); - db.DeleteAll(); - - Assert.That(db.Select(), Has.Count.EqualTo(0)); - Assert.That(db.Select(), Has.Count.EqualTo(0)); -``` - -# Limitations - -For simplicity, and to be able to have the same POCO class persisted in db4o, memcached, redis or on the filesystem (i.e. providers included in ServiceStack), each model must have a single primary key, by convention OrmLite expects it -to be `Id` although you use `[Alias("DbFieldName")]` attribute it map it to a column with a different name or use -the `[PrimaryKey]` attribute to tell OrmLite to use a different property for the primary key. - -You can still `SELECT` from these tables, you will just be unable to make use of APIs that rely on it, e.g. -`Update` or `Delete` where the filter is implied (i.e. not specified), all the APIs that end with `ById`, etc. - -### Workaround single Primary Key limitation - -A potential workaround to support tables with multiple primary keys is to create an auto generated `Id` property that -returns a unique value based on all the primary key fields, e.g: - -```csharp -public class OrderDetail -{ - public string Id { get { return this.OrderId + "/" + this.ProductId; } } - - public int OrderId { get; set; } - public int ProductId { get; set; } - public decimal UnitPrice { get; set; } - public short Quantity { get; set; } - public double Discount { get; set; } -} -``` - -## Oracle Provider Notes - -The Oracle provider requires an installation of Oracle's ODP.NET. It has been tested with Oracle 11g but should work with 10g and perhaps even older versions. It has not been tested with Oracle 12c and does not support any new 12c features such as AutoIncrement keys. It also does not support the new Oracle fully-managed client. - -By default the Oracle provider stores Guids in the database as character strings and when generating SQL it quotes only table and column names that are reserved words in Oracle. That requires that you use the same quoting if you code your own SQL. Both of these options can be overridden, but overriding them will cause problems: the provider can store Guids as raw(16) but it cannot read them. - -The Oracle provider uses Oracle sequences to implement AutoIncrement columns and it queries the sequence to get a new value in a separate database call. You can override the automatically generated sequence name with a - - [Sequence("name")] - -attribute on a field. The Sequence attribute implies [AutoIncrement], but you can use both on the same field. - -Since Oracle has a very restrictive 30 character limit on names, it is strongly suggested that you use short entity class and field names or aliases, remembering that indexes and foreign keys get compound names. If you use long names, the provider will squash them to make them compliant with the restriction. The algorithm used is to remove all vowels ("aeiouy") and if still too long then every fourth letter starting with the third one and finally if still too long to truncate the name. You must apply the same squashing algorithm if you are coding your own SQL. - -The previous version of ServiceStack.OrmLite.Oracle used System.Data.OracleClient to talk to the database. Microsoft has deprecated that client, but it does still mostly work if you construct the Oracle provider like this: - - OracleOrmLiteDialectProvider.Instance = new OracleOrmLiteDialectProvider( - compactGuid: false, - quoteNames: false, - clientProvider: OracleOrmLiteDialectProvider.MicrosoftProvider); - -DateTimeOffset fields and, in locales that use a comma to separate the fractional part of a floating point number, some aspects of using floating point numbers, do not work with System.Data.OracleClient. - - -# Community Resources - - - [OrmLite and Redis: New alternatives for handling db communication](http://www.abtosoftware.com/blog/servicestack-ormlite-and-redis-new-alternatives-for-handling-db-communication) by [@abtosoftware](https://twitter.com/abtosoftware) - - [Object Serialization as Step Towards Normalization](http://www.unpluggeddevelopment.com/post/85225892120/object-serialization-as-step-towards-normalization) by [@ 82unpluggd](https://twitter.com/82unpluggd) - - [Creating a Data Access Layer using OrmLite](http://blogs.askcts.com/2014/05/07/getting-started-with-servicestack-part-2/) by [Lydon Bergin](http://blogs.askcts.com/) - - [Code Generation using ServiceStack.OrmLite and T4 Text templates](http://jokecamp.wordpress.com/2013/09/07/code-generation-using-servicestack-ormlite-and-t4-text-templates/) by [@jokecamp](https://twitter.com/jokecamp) - - [Simple ServiceStack OrmLite Example](http://www.curlette.com/?p=1068) by [@robrtc](https://twitter.com/robrtc) - - [OrmLite Blobbing done with NHibernate and Serialized JSON](http://www.philliphaydon.com/2012/03/ormlite-blobbing-done-with-nhibernate-and-serialized-json/) by [@philliphaydon](https://twitter.com/philliphaydon) - - [Creating An ASP.NET MVC Blog With ServiceStack.OrmLite](http://www.eggheadcafe.com/tutorials/asp-net/285cbe96-9922-406a-b193-3a0b40e31c40/creating-an-aspnet-mvc-blog-with-servicestackormlite.aspx) by [@peterbromberg](https://twitter.com/peterbromberg) - - -## Other notable Micro ORMs for .NET -Many performance problems can be mitigated and a lot of use-cases can be simplified without the use of a heavyweight ORM, and their config, mappings and infrastructure. -As [performance is the most important feature](https://github.com/mythz/ScalingDotNET) we can recommend the following list, each with their own unique special blend of features. - - * **[Dapper](http://code.google.com/p/dapper-dot-net/)** - by [@samsaffron](http://twitter.com/samsaffron) and [@marcgravell](http://twitter.com/marcgravell) - - The current performance king, supports both POCO and dynamic access, fits in a single class. Put in production to solve [StackOverflow's DB Perf issues](http://samsaffron.com/archive/2011/03/30/How+I+learned+to+stop+worrying+and+write+my+own+ORM). Requires .NET 4. - * **[PetaPoco](http://www.toptensoftware.com/petapoco/)** - by [@toptensoftware](http://twitter.com/toptensoftware) - - Fast, supports dynamics, expandos and typed POCOs, fits in a single class, runs on .NET 3.5 and Mono. Includes optional T4 templates for POCO table generation. - * **[Massive](https://github.com/robconery/massive)** - by [@robconery](http://twitter.com/robconery) - - Fast, supports dynamics and expandos, smart use of optional params to provide a wrist-friendly api, fits in a single class. Multiple RDBMS support. Requires .NET 4. - * **[Simple.Data](https://github.com/markrendle/Simple.Data)** - by [@markrendle](http://twitter.com/markrendle) - - A little slower than above ORMS, most wrist-friendly courtesy of a dynamic API, multiple RDBMS support inc. Mongo DB. Requires .NET 4. +### This repository [has moved](https://docs.servicestack.net/mono-repo) to [github.com/ServiceStack/ServiceStack/ServiceStack.OrmLite](https://github.com/ServiceStack/ServiceStack/tree/main/ServiceStack.OrmLite) diff --git a/build/build-core-data.proj b/build/build-core-data.proj new file mode 100644 index 000000000..0f081f566 --- /dev/null +++ b/build/build-core-data.proj @@ -0,0 +1,67 @@ + + + + + + 6 + 0 + $(BUILD_NUMBER) + + + + $(MSBuildProjectDirectory)/.. + $(BuildSolutionDir)/src + Release + $(MajorVersion).$(MinorVersion).$(PatchVersion) + + + + + BeforeBuildSolutions; + BuildSolutions + + + + + + + + + + + + + + + + + + + + + + <Version>[^<]* + <Version>$(PackageVersion) + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/build-core.proj b/build/build-core.proj new file mode 100644 index 000000000..6d768d126 --- /dev/null +++ b/build/build-core.proj @@ -0,0 +1,119 @@ + + + + + + 6 + 0 + $(BUILD_NUMBER) + + + + $(MSBuildProjectDirectory)/.. + $(BuildSolutionDir)/src + $(BuildSolutionDir)/tests + Release + $(MajorVersion).$(MinorVersion).$(PatchVersion) + + + + + BeforeBuildSolutions; + BuildSolutions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <Version>[^<]* + <Version>$(PackageVersion) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/build-local.bat b/build/build-local.bat deleted file mode 100644 index 7b52482da..000000000 --- a/build/build-local.bat +++ /dev/null @@ -1,3 +0,0 @@ -SET MSBUILD=C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe - -%MSBUILD% Build.proj /target:NuGetPack /property:Configuration=Release;RELEASE=true;PatchVersion=60 \ No newline at end of file diff --git a/build/build-sn.proj b/build/build-sn.proj deleted file mode 100644 index db65ca5a1..000000000 --- a/build/build-sn.proj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - 4 - 0 - $(BUILD_NUMBER) - - - - $(MSBuildProjectDirectory)/.. - $(BuildSolutionDir)/src - $(BuildSolutionDir)/lib - Signed - $(BuildSolutionDir)/src/.nuget/nuget.exe - $(BuildSolutionDir)/NuGet.Signed - $(MajorVersion).$(MinorVersion).$(PatchVersion).0 - -unstable - $(MajorVersion).$(MinorVersion).$(PatchVersion)$(UnstableTag) - $(MajorVersion).$(MinorVersion)$(PatchVersion) - - - - - - - - - - - BeforeBuildSolutions; - BuildSolutions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AssemblyFileVersion\(\"\d+\.\d+\.\d+\.\d+\"\) - AssemblyFileVersion("$(Version)") - - - - - AssemblyVersion\(\"\d+\.\d+\.\d+\.\d+\"\) - AssemblyVersion("4.0.0.0") - - - - - version="4\.0[^"]*" - version="$(PackageVersion)" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/build.bat b/build/build.bat index 087b332cc..5dbf7e252 100644 --- a/build/build.bat +++ b/build/build.bat @@ -1,4 +1,5 @@ -SET MSBUILD=C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe +for /f "usebackq tokens=*" %%i in (`vswhere.exe -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe`) do ( + SET MSBUILD="%%i" +) +%MSBUILD% build.proj /property:Configuration=Release;MinorVersion=8;PatchVersion=1 -REM %MSBUILD% build.proj /target:NuGetPack /property:Configuration=Release;RELEASE=true;PatchVersion=0 -%MSBUILD% build-sn.proj /target:NuGetPack /property:Configuration=Signed;RELEASE=true;PatchVersion=0 diff --git a/build/build.proj b/build/build.proj index 2f9c5d6da..31beda421 100644 --- a/build/build.proj +++ b/build/build.proj @@ -1,10 +1,10 @@ + xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="4.0"> - 4 + 6 0 $(BUILD_NUMBER) @@ -12,22 +12,10 @@ $(MSBuildProjectDirectory)/.. $(BuildSolutionDir)/src - $(BuildSolutionDir)/lib Release - $(BuildSolutionDir)/src/.nuget/nuget.exe - $(BuildSolutionDir)/NuGet - $(MajorVersion).$(MinorVersion).$(PatchVersion).0 - -unstable - $(MajorVersion).$(MinorVersion).$(PatchVersion)$(UnstableTag) - $(MajorVersion).$(MinorVersion)$(PatchVersion) + $(MajorVersion).$(MinorVersion).$(PatchVersion) - - - - - - BeforeBuildSolutions; @@ -35,269 +23,121 @@ - - - - - - - - - - - - - - - - - - + + + + + Properties="Configuration=$(Configuration)" /> + + + + + + + + + + + + + + + + - - \d+\.\d+\.\d+\.\d+ - $(Version) - - - key="servicestack:license".* - key="servicestack:license" value="$([System.IO.File]::ReadAllText($(MSBuildProjectDirectory)/appsettings.license.txt))" /> - - - - version="4\.0[^"]*" - version="$(PackageVersion)" + + <Version>[^<]* + <Version>$(PackageVersion) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/copy.bat b/build/copy.bat index 1a691ea31..93f412481 100644 --- a/build/copy.bat +++ b/build/copy.bat @@ -1,50 +1,27 @@ REM SET BUILD=Debug SET BUILD=Release -SET MSBUILD=C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe -MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite32\lib\ -MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite32\lib\net40 -MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite64\lib\net40 MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.SqlServer\lib -MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite.Mono\lib -MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite.Mono\lib\net40 MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.MySql\lib MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.PostgreSQL\lib MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Oracle\lib MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Firebird\lib MD ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.T4\content -COPY ..\src\ServiceStack.OrmLite.Sqlite32\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite32\lib\net35 -COPY ..\src\ServiceStack.OrmLite.Sqlite32\bin\x86\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite32\lib\net40 -COPY ..\src\ServiceStack.OrmLite.Sqlite64\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite64\lib\net35 -COPY ..\src\ServiceStack.OrmLite.Sqlite64\bin\x64\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite64\lib\net40 -COPY ..\src\ServiceStack.OrmLite.SqlServer\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.SqlServer\lib - -COPY ..\lib\Mono.Data.Sqlite.dll ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite.Mono\lib\net35 -COPY ..\src\ServiceStack.OrmLite.Sqlite\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite.Mono\lib\net35 -COPY ..\lib\Mono.Data.Sqlite.dll ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite.Mono\lib\net40 -COPY ..\src\ServiceStack.OrmLite.Sqlite\bin\x86\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Sqlite.Mono\lib\net40 - COPY ..\src\T4\*.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.T4\content - -COPY ..\src\ServiceStack.OrmLite.MySql\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.MySql\lib -COPY ..\src\ServiceStack.OrmLite.PostgreSQL\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.PostgreSQL\lib -COPY ..\src\ServiceStack.OrmLite.Oracle\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Oracle\lib -COPY ..\src\ServiceStack.OrmLite.Firebird\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Firebird\lib -COPY ..\src\ServiceStack.OrmLite.Firebird\bin\%BUILD%\FirebirdSql.Data.FirebirdClient.dll ..\..\ServiceStack.OrmLite\NuGet\ServiceStack.OrmLite.Firebird\lib - -COPY ..\src\ServiceStack.OrmLite.Sqlite\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack\lib -COPY ..\src\ServiceStack.OrmLite.Sqlite\bin\x86\sqlite3.dll ..\..\ServiceStack\lib -COPY ..\src\ServiceStack.OrmLite.Sqlite\bin\x86\Mono.Data.Sqlite.dll ..\..\ServiceStack\lib -COPY ..\src\ServiceStack.OrmLite.Sqlite.Windows\bin\%BUILD%\ServiceStack.OrmLite.Sqlite.Windows* ..\..\ServiceStack\lib -COPY ..\src\ServiceStack.OrmLite.SqlServer\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack\lib -COPY ..\src\ServiceStack.OrmLite.MySql\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack\lib -COPY ..\src\ServiceStack.OrmLite.PostgreSQL\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack\lib -COPY ..\src\ServiceStack.OrmLite.PostgreSQL\bin\%BUILD%\Npgsql.* ..\..\ServiceStack\lib - -COPY ..\src\ServiceStack.OrmLite\bin\Signed\ServiceStack.OrmLite.* ..\..\ServiceStack\lib\signed -COPY ..\src\ServiceStack.OrmLite.SqlServer\bin\Signed\ServiceStack.OrmLite.SqlServer.* ..\..\ServiceStack\lib\signed - -COPY ..\src\ServiceStack.OrmLiteV45\bin\%BUILD%\ServiceStack.OrmLite.* ..\..\ServiceStack\lib\net45 -COPY ..\src\ServiceStack.OrmLite.SqlServerV45\bin\%BUILD%\ServiceStack.OrmLite.SqlServer.* ..\..\ServiceStack\lib\net45 +COPY ..\src\ServiceStack.OrmLite\bin\%BUILD%\net45\ServiceStack.OrmLite.* ..\..\ServiceStack\lib\net45 +COPY ..\src\ServiceStack.OrmLite\bin\%BUILD%\netstandard2.0\ServiceStack.OrmLite.* ..\..\ServiceStack\lib\netstandard2.0 +COPY ..\src\ServiceStack.OrmLite.Sqlite\bin\%BUILD%\net45\ServiceStack.OrmLite.Sqlite.* ..\..\ServiceStack\lib\net45 +COPY ..\src\ServiceStack.OrmLite.Sqlite\bin\%BUILD%\netstandard2.0\ServiceStack.OrmLite.Sqlite.* ..\..\ServiceStack\lib\netstandard2.0 +COPY ..\src\ServiceStack.OrmLite.Sqlite.Windows\bin\%BUILD%\net45\ServiceStack.OrmLite.Sqlite.Windows.* ..\..\ServiceStack\lib\net45 +COPY ..\src\ServiceStack.OrmLite.SqlServer\bin\%BUILD%\net45\ServiceStack.OrmLite.SqlServer.* ..\..\ServiceStack\lib\net45 +COPY ..\src\ServiceStack.OrmLite.SqlServer\bin\%BUILD%\netstandard2.0\ServiceStack.OrmLite.SqlServer.* ..\..\ServiceStack\lib\netstandard2.0 +COPY ..\src\ServiceStack.OrmLite.MySql\bin\%BUILD%\net45\ServiceStack.OrmLite.MySql.* ..\..\ServiceStack\lib\net45 +COPY ..\src\ServiceStack.OrmLite.MySql\bin\%BUILD%\netstandard2.0\ServiceStack.OrmLite.MySql.* ..\..\ServiceStack\lib\netstandard2.0 +COPY ..\src\ServiceStack.OrmLite.PostgreSQL\bin\%BUILD%\net45\ServiceStack.OrmLite.PostgreSQL.* ..\..\ServiceStack\lib\net45 +COPY ..\src\ServiceStack.OrmLite.PostgreSQL\bin\%BUILD%\netstandard2.0\ServiceStack.OrmLite.PostgreSQL.* ..\..\ServiceStack\lib\netstandard2.0 +COPY ..\src\ServiceStack.OrmLite.PostgreSQL\bin\%BUILD%\net45\Npgsql.* ..\..\ServiceStack\lib\net45 + +COPY ..\src\ServiceStack.OrmLite\bin\Signed\net45\ServiceStack.OrmLite.* ..\..\ServiceStack\lib\signed +COPY ..\src\ServiceStack.OrmLite.SqlServer\bin\Signed\net45\ServiceStack.OrmLite.SqlServer.* ..\..\ServiceStack\lib\signed diff --git a/build/vswhere.exe b/build/vswhere.exe new file mode 100644 index 000000000..1731aa6ed Binary files /dev/null and b/build/vswhere.exe differ diff --git a/lib/FirebirdSql.Data.FirebirdClient.dll b/lib/FirebirdSql.Data.FirebirdClient.dll deleted file mode 100644 index fba59bc38..000000000 Binary files a/lib/FirebirdSql.Data.FirebirdClient.dll and /dev/null differ diff --git a/lib/Mono.Data.Sqlite.dll b/lib/Mono.Data.Sqlite.dll deleted file mode 100644 index dad79f065..000000000 Binary files a/lib/Mono.Data.Sqlite.dll and /dev/null differ diff --git a/lib/Mono.Security.dll b/lib/Mono.Security.dll deleted file mode 100644 index 1371f5cb6..000000000 Binary files a/lib/Mono.Security.dll and /dev/null differ diff --git a/lib/MonoDroid/ServiceStack.Common.dll b/lib/MonoDroid/ServiceStack.Common.dll deleted file mode 100755 index 18757391b..000000000 Binary files a/lib/MonoDroid/ServiceStack.Common.dll and /dev/null differ diff --git a/lib/MonoDroid/ServiceStack.Interfaces.dll b/lib/MonoDroid/ServiceStack.Interfaces.dll deleted file mode 100755 index 841c6362c..000000000 Binary files a/lib/MonoDroid/ServiceStack.Interfaces.dll and /dev/null differ diff --git a/lib/MonoDroid/ServiceStack.Text.dll b/lib/MonoDroid/ServiceStack.Text.dll deleted file mode 100755 index 4f7372581..000000000 Binary files a/lib/MonoDroid/ServiceStack.Text.dll and /dev/null differ diff --git a/lib/MySql.Data.dll b/lib/MySql.Data.dll deleted file mode 100644 index 4e6009a02..000000000 Binary files a/lib/MySql.Data.dll and /dev/null differ diff --git a/lib/Npgsql.dll b/lib/Npgsql.dll deleted file mode 100644 index 593e3669d..000000000 Binary files a/lib/Npgsql.dll and /dev/null differ diff --git a/lib/ServiceStack.Client.dll b/lib/ServiceStack.Client.dll deleted file mode 100644 index be7d4c609..000000000 Binary files a/lib/ServiceStack.Client.dll and /dev/null differ diff --git a/lib/ServiceStack.Common.MonoTouch.dll b/lib/ServiceStack.Common.MonoTouch.dll deleted file mode 100755 index f088b71b9..000000000 Binary files a/lib/ServiceStack.Common.MonoTouch.dll and /dev/null differ diff --git a/lib/ServiceStack.Common.dll b/lib/ServiceStack.Common.dll deleted file mode 100644 index 94e4b3f34..000000000 Binary files a/lib/ServiceStack.Common.dll and /dev/null differ diff --git a/lib/ServiceStack.Common.pdb b/lib/ServiceStack.Common.pdb deleted file mode 100644 index aa5d3e8c9..000000000 Binary files a/lib/ServiceStack.Common.pdb and /dev/null differ diff --git a/lib/ServiceStack.Interfaces.MonoTouch.dll b/lib/ServiceStack.Interfaces.MonoTouch.dll deleted file mode 100755 index cefe76e5f..000000000 Binary files a/lib/ServiceStack.Interfaces.MonoTouch.dll and /dev/null differ diff --git a/lib/ServiceStack.Interfaces.dll b/lib/ServiceStack.Interfaces.dll deleted file mode 100644 index b32b20b21..000000000 Binary files a/lib/ServiceStack.Interfaces.dll and /dev/null differ diff --git a/lib/ServiceStack.Pcl.Net45.dll b/lib/ServiceStack.Pcl.Net45.dll deleted file mode 100644 index 1d289b872..000000000 Binary files a/lib/ServiceStack.Pcl.Net45.dll and /dev/null differ diff --git a/lib/ServiceStack.Pcl.WinStore.dll b/lib/ServiceStack.Pcl.WinStore.dll deleted file mode 100644 index 51ebd33ce..000000000 Binary files a/lib/ServiceStack.Pcl.WinStore.dll and /dev/null differ diff --git a/lib/ServiceStack.Pcl.WinStore.pri b/lib/ServiceStack.Pcl.WinStore.pri deleted file mode 100644 index a3071fe88..000000000 Binary files a/lib/ServiceStack.Pcl.WinStore.pri and /dev/null differ diff --git a/lib/ServiceStack.Text.MonoTouch.dll b/lib/ServiceStack.Text.MonoTouch.dll deleted file mode 100755 index b1deb6437..000000000 Binary files a/lib/ServiceStack.Text.MonoTouch.dll and /dev/null differ diff --git a/lib/ServiceStack.Text.XML b/lib/ServiceStack.Text.XML deleted file mode 100644 index 6cf831f51..000000000 --- a/lib/ServiceStack.Text.XML +++ /dev/null @@ -1,714 +0,0 @@ - - - - ServiceStack.Text - - - - - Utils to load types - - - - - Find the type from the name supplied - - [typeName] or [typeName, assemblyName] - - - - - The top-most interface of the given type, if any. - - - - - Find type if it exists - - - - The type if it exists - - - - Populate an object with Example data. - - - - - - - Populates the object with example data. - - - Tracks how deeply nested we are - - - - - If AlwaysUseUtc is set to true then convert all DateTime to UTC. - - - - - - - Repairs an out-of-spec XML date/time string which incorrectly uses a space instead of a 'T' to separate the date from the time. - These string are occasionally generated by SQLite and can cause errors in OrmLite when reading these columns from the DB. - - The XML date/time string to repair - The repaired string. If no repairs were made, the original string is returned. - - - - WCF Json format: /Date(unixts+0000)/ - - - - - - - WCF Json format: /Date(unixts+0000)/ - - - - - - - Get the type(string) constructor if exists - - The type. - - - - - micro optimizations: using flags instead of value.IndexOfAny(EscapeChars) - - - - - - - Class to hold - - - - - - A fast, standards-based, serialization-issue free DateTime serailizer. - - - - - Determines whether this serializer can create the specified type from a string. - - The type. - - true if this instance [can create from string] the specified type; otherwise, false. - - - - - Parses the specified value. - - The value. - - - - - Deserializes from reader. - - The reader. - - - - - Serializes to string. - - The value. - - - - - Serializes to writer. - - The value. - The writer. - - - - Sets which format to use when serializing TimeSpans - - - - - if the is configured - to take advantage of specification, - to support user-friendly serialized formats, ie emitting camelCasing for JSON - and parsing member names and enum values in a case-insensitive manner. - - - - - if the is configured - to support web-friendly serialized formats, ie emitting lowercase_underscore_casing for JSON - - - - - Define how property names are mapped during deserialization - - - - - Gets or sets a value indicating if the framework should throw serialization exceptions - or continue regardless of deserialization errors. If the framework - will throw; otherwise, it will parse as many fields as possible. The default is . - - - - - Gets or sets a value indicating if the framework should always convert to UTC format instead of local time. - - - - - Gets or sets a value indicating if the framework should always assume is in UTC format if Kind is Unspecified. - - - - - Gets or sets whether we should append the Utc offset when we serialize Utc dates. Defaults to no. - Only supported for when the JsConfig.DateHandler == JsonDateHandler.TimestampOffset - - - - - Gets or sets a value indicating if unicode symbols should be serialized as "\uXXXX". - - - - - If set to true, Interface types will be prefered over concrete types when serializing. - - - - - For extra serialization performance you can re-use a ThreadStatic StringBuilder - when serializing to a JSON String. - - - - - Sets the maximum depth to avoid circular dependencies - - - - - Set this to enable your own type construction provider. - This is helpful for integration with IoC containers where you need to call the container constructor. - Return null if you don't know how to construct the type and the parameterless constructor will be used. - - - - - If set to true, Interface types will be prefered over concrete types when serializing. - - - - - Always emit type info for this type. Takes precedence over ExcludeTypeInfo - - - - - Never emit type info for this type - - - - - if the is configured - to take advantage of specification, - to support user-friendly serialized formats, ie emitting camelCasing for JSON - and parsing member names and enum values in a case-insensitive manner. - - - - - Define custom serialization fn for BCL Structs - - - - - Define custom raw serialization fn - - - - - Define custom serialization hook - - - - - Define custom after serialization hook - - - - - Define custom deserialization fn for BCL Structs - - - - - Define custom raw deserialization fn for objects - - - - - Exclude specific properties of this type from being serialized - - - - - Opt-in flag to set some Value Types to be treated as a Ref Type - - - - - Whether there is a fn (raw or otherwise) - - - - - The property names on target types must match property names in the JSON source - - - - - The property names on target types may not match the property names in the JSON source - - - - - Uses the xsd format like PT15H10M20S - - - - - Uses the standard .net ToString method of the TimeSpan class - - - - - Get JSON string value converted to T - - - - - Get JSON string value - - - - - Get unescaped string value - - - - - Get unescaped string value - - - - - Write JSON Array, Object, bool or number values as raw string - - - - - Get JSON string value - - - - - Creates an instance of a Type from a string value - - - - - Parses the specified value. - - The value. - - - - - Shortcut escape when we're sure value doesn't contain any escaped chars - - - - - - - Given a character as utf32, returns the equivalent string provided that the character - is legal json. - - - - - - - micro optimizations: using flags instead of value.IndexOfAny(EscapeChars) - - - - - - - Implement the serializer using a more static approach - - - - - - Implement the serializer using a more static approach - - - - - - Public Code API to register commercial license for ServiceStack. - - - - - Internal Utilities to verify licensing - - - - - Pretty Thread-Safe cache class from: - http://code.google.com/p/dapper-dot-net/source/browse/Dapper/SqlMapper.cs - - This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - equality. The type is fully thread-safe. - - - - - Represents an individual object, allowing access to members by-name - - - - - Use the target types definition of equality - - - - - Obtain the hash of the target object - - - - - Use the target's definition of a string representation - - - - - Wraps an individual object, allowing by-name access to that instance - - - - - Get or Set the value of a named member for the underlying object - - - - - The object represented by this instance - - - - - Provides by-name member-access to objects of a given type - - - - - Create a new instance of this type - - - - - Provides a type-specific accessor, allowing by-name access for all objects of that type - - The accessor is cached internally; a pre-existing accessor may be returned - - - - Does this type support new instances via a parameterless constructor? - - - - - Get or set the value of a named member on the target instance - - - - - Maps the path of a file in the context of a VS project - - the relative path - the absolute path - Assumes static content is two directories above the /bin/ directory, - eg. in a unit test scenario the assembly would be in /bin/Debug/. - - - - Maps the path of a file in a self-hosted scenario - - the relative path - the absolute path - Assumes static content is copied to /bin/ folder with the assemblies - - - - Maps the path of a file in an Asp.Net hosted scenario - - the relative path - the absolute path - Assumes static content is in the parent folder of the /bin/ directory - - - - Implement the serializer using a more static approach - - - - - - Creates a new instance of type. - First looks at JsConfig.ModelFactory before falling back to CreateInstance - - - - - Creates a new instance of type. - First looks at JsConfig.ModelFactory before falling back to CreateInstance - - - - - Creates a new instance from the default constructor of type - - - - - Add a Property attribute at runtime. - Not threadsafe, should only add attributes on Startup. - - - - - Add a Property attribute at runtime. - Not threadsafe, should only add attributes on Startup. - - - - - @jonskeet: Collection of utility methods which operate on streams. - r285, February 26th 2009: http://www.yoda.arachsys.com/csharp/miscutil/ - - - - - Reads the given stream up to the end, returning the data as a byte - array. - - - - - Reads the given stream up to the end, returning the data as a byte - array, using the given buffer size. - - - - - Reads the given stream up to the end, returning the data as a byte - array, using the given buffer for transferring data. Note that the - current contents of the buffer is ignored, so the buffer needn't - be cleared beforehand. - - - - - Copies all the data from one stream into another. - - - - - Copies all the data from one stream into another, using a buffer - of the given size. - - - - - Copies all the data from one stream into another, using the given - buffer for transferring data. Note that the current contents of - the buffer is ignored, so the buffer needn't be cleared beforehand. - - - - - Reads exactly the given number of bytes from the specified stream. - If the end of the stream is reached before the specified amount - of data is read, an exception is thrown. - - - - - Reads into a buffer, filling it completely. - - - - - Reads exactly the given number of bytes from the specified stream, - into the given buffer, starting at position 0 of the array. - - - - - Reads exactly the given number of bytes from the specified stream, - into the given buffer, starting at position 0 of the array. - - - - - Same as ReadExactly, but without the argument checks. - - - - - Converts from base: 0 - 62 - - The source. - From. - To. - - - - - Skip the encoding process for 'safe strings' - - - - - - - A class to allow the conversion of doubles to string representations of - their exact decimal values. The implementation aims for readability over - efficiency. - - Courtesy of @JonSkeet - http://www.yoda.arachsys.com/csharp/DoubleConverter.cs - - - - - - - - How many digits are *after* the decimal point - - - - - Constructs an arbitrary decimal expansion from the given long. - The long must not be negative. - - - - - Multiplies the current expansion by the given amount, which should - only be 2 or 5. - - - - - Shifts the decimal point; a negative value makes - the decimal expansion bigger (as fewer digits come after the - decimal place) and a positive value makes the decimal - expansion smaller. - - - - - Removes leading/trailing zeroes from the expansion. - - - - - Converts the value to a proper decimal string representation. - - - - - Creates an instance of a Type from a string value - - - - - Determines whether the specified type is convertible from string. - - The type. - - true if the specified type is convertible from string; otherwise, false. - - - - - Parses the specified value. - - The value. - - - - - Parses the specified type. - - The type. - The value. - - - - - Useful extension method to get the Dictionary[string,string] representation of any POCO type. - - - - - - Recursively prints the contents of any POCO object in a human-friendly, readable format - - - - - - Print Dump to Console.WriteLine - - - - - Print string.Format to Console.WriteLine - - - - - Parses the specified value. - - The value. - - - - diff --git a/lib/ServiceStack.Text.dll b/lib/ServiceStack.Text.dll deleted file mode 100644 index dc7759416..000000000 Binary files a/lib/ServiceStack.Text.dll and /dev/null differ diff --git a/lib/ServiceStack.Text.pdb b/lib/ServiceStack.Text.pdb deleted file mode 100644 index 6cc59d08d..000000000 Binary files a/lib/ServiceStack.Text.pdb and /dev/null differ diff --git a/lib/ServiceStack.dll b/lib/ServiceStack.dll deleted file mode 100644 index 9c9c52284..000000000 Binary files a/lib/ServiceStack.dll and /dev/null differ diff --git a/lib/signed/ServiceStack.Common.dll b/lib/signed/ServiceStack.Common.dll deleted file mode 100644 index 4dfde049d..000000000 Binary files a/lib/signed/ServiceStack.Common.dll and /dev/null differ diff --git a/lib/signed/ServiceStack.OrmLite.dll b/lib/signed/ServiceStack.OrmLite.dll deleted file mode 100644 index c70c26a70..000000000 Binary files a/lib/signed/ServiceStack.OrmLite.dll and /dev/null differ diff --git a/lib/signed/ServiceStack.Text.XML b/lib/signed/ServiceStack.Text.XML deleted file mode 100644 index 6cf831f51..000000000 --- a/lib/signed/ServiceStack.Text.XML +++ /dev/null @@ -1,714 +0,0 @@ - - - - ServiceStack.Text - - - - - Utils to load types - - - - - Find the type from the name supplied - - [typeName] or [typeName, assemblyName] - - - - - The top-most interface of the given type, if any. - - - - - Find type if it exists - - - - The type if it exists - - - - Populate an object with Example data. - - - - - - - Populates the object with example data. - - - Tracks how deeply nested we are - - - - - If AlwaysUseUtc is set to true then convert all DateTime to UTC. - - - - - - - Repairs an out-of-spec XML date/time string which incorrectly uses a space instead of a 'T' to separate the date from the time. - These string are occasionally generated by SQLite and can cause errors in OrmLite when reading these columns from the DB. - - The XML date/time string to repair - The repaired string. If no repairs were made, the original string is returned. - - - - WCF Json format: /Date(unixts+0000)/ - - - - - - - WCF Json format: /Date(unixts+0000)/ - - - - - - - Get the type(string) constructor if exists - - The type. - - - - - micro optimizations: using flags instead of value.IndexOfAny(EscapeChars) - - - - - - - Class to hold - - - - - - A fast, standards-based, serialization-issue free DateTime serailizer. - - - - - Determines whether this serializer can create the specified type from a string. - - The type. - - true if this instance [can create from string] the specified type; otherwise, false. - - - - - Parses the specified value. - - The value. - - - - - Deserializes from reader. - - The reader. - - - - - Serializes to string. - - The value. - - - - - Serializes to writer. - - The value. - The writer. - - - - Sets which format to use when serializing TimeSpans - - - - - if the is configured - to take advantage of specification, - to support user-friendly serialized formats, ie emitting camelCasing for JSON - and parsing member names and enum values in a case-insensitive manner. - - - - - if the is configured - to support web-friendly serialized formats, ie emitting lowercase_underscore_casing for JSON - - - - - Define how property names are mapped during deserialization - - - - - Gets or sets a value indicating if the framework should throw serialization exceptions - or continue regardless of deserialization errors. If the framework - will throw; otherwise, it will parse as many fields as possible. The default is . - - - - - Gets or sets a value indicating if the framework should always convert to UTC format instead of local time. - - - - - Gets or sets a value indicating if the framework should always assume is in UTC format if Kind is Unspecified. - - - - - Gets or sets whether we should append the Utc offset when we serialize Utc dates. Defaults to no. - Only supported for when the JsConfig.DateHandler == JsonDateHandler.TimestampOffset - - - - - Gets or sets a value indicating if unicode symbols should be serialized as "\uXXXX". - - - - - If set to true, Interface types will be prefered over concrete types when serializing. - - - - - For extra serialization performance you can re-use a ThreadStatic StringBuilder - when serializing to a JSON String. - - - - - Sets the maximum depth to avoid circular dependencies - - - - - Set this to enable your own type construction provider. - This is helpful for integration with IoC containers where you need to call the container constructor. - Return null if you don't know how to construct the type and the parameterless constructor will be used. - - - - - If set to true, Interface types will be prefered over concrete types when serializing. - - - - - Always emit type info for this type. Takes precedence over ExcludeTypeInfo - - - - - Never emit type info for this type - - - - - if the is configured - to take advantage of specification, - to support user-friendly serialized formats, ie emitting camelCasing for JSON - and parsing member names and enum values in a case-insensitive manner. - - - - - Define custom serialization fn for BCL Structs - - - - - Define custom raw serialization fn - - - - - Define custom serialization hook - - - - - Define custom after serialization hook - - - - - Define custom deserialization fn for BCL Structs - - - - - Define custom raw deserialization fn for objects - - - - - Exclude specific properties of this type from being serialized - - - - - Opt-in flag to set some Value Types to be treated as a Ref Type - - - - - Whether there is a fn (raw or otherwise) - - - - - The property names on target types must match property names in the JSON source - - - - - The property names on target types may not match the property names in the JSON source - - - - - Uses the xsd format like PT15H10M20S - - - - - Uses the standard .net ToString method of the TimeSpan class - - - - - Get JSON string value converted to T - - - - - Get JSON string value - - - - - Get unescaped string value - - - - - Get unescaped string value - - - - - Write JSON Array, Object, bool or number values as raw string - - - - - Get JSON string value - - - - - Creates an instance of a Type from a string value - - - - - Parses the specified value. - - The value. - - - - - Shortcut escape when we're sure value doesn't contain any escaped chars - - - - - - - Given a character as utf32, returns the equivalent string provided that the character - is legal json. - - - - - - - micro optimizations: using flags instead of value.IndexOfAny(EscapeChars) - - - - - - - Implement the serializer using a more static approach - - - - - - Implement the serializer using a more static approach - - - - - - Public Code API to register commercial license for ServiceStack. - - - - - Internal Utilities to verify licensing - - - - - Pretty Thread-Safe cache class from: - http://code.google.com/p/dapper-dot-net/source/browse/Dapper/SqlMapper.cs - - This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - equality. The type is fully thread-safe. - - - - - Represents an individual object, allowing access to members by-name - - - - - Use the target types definition of equality - - - - - Obtain the hash of the target object - - - - - Use the target's definition of a string representation - - - - - Wraps an individual object, allowing by-name access to that instance - - - - - Get or Set the value of a named member for the underlying object - - - - - The object represented by this instance - - - - - Provides by-name member-access to objects of a given type - - - - - Create a new instance of this type - - - - - Provides a type-specific accessor, allowing by-name access for all objects of that type - - The accessor is cached internally; a pre-existing accessor may be returned - - - - Does this type support new instances via a parameterless constructor? - - - - - Get or set the value of a named member on the target instance - - - - - Maps the path of a file in the context of a VS project - - the relative path - the absolute path - Assumes static content is two directories above the /bin/ directory, - eg. in a unit test scenario the assembly would be in /bin/Debug/. - - - - Maps the path of a file in a self-hosted scenario - - the relative path - the absolute path - Assumes static content is copied to /bin/ folder with the assemblies - - - - Maps the path of a file in an Asp.Net hosted scenario - - the relative path - the absolute path - Assumes static content is in the parent folder of the /bin/ directory - - - - Implement the serializer using a more static approach - - - - - - Creates a new instance of type. - First looks at JsConfig.ModelFactory before falling back to CreateInstance - - - - - Creates a new instance of type. - First looks at JsConfig.ModelFactory before falling back to CreateInstance - - - - - Creates a new instance from the default constructor of type - - - - - Add a Property attribute at runtime. - Not threadsafe, should only add attributes on Startup. - - - - - Add a Property attribute at runtime. - Not threadsafe, should only add attributes on Startup. - - - - - @jonskeet: Collection of utility methods which operate on streams. - r285, February 26th 2009: http://www.yoda.arachsys.com/csharp/miscutil/ - - - - - Reads the given stream up to the end, returning the data as a byte - array. - - - - - Reads the given stream up to the end, returning the data as a byte - array, using the given buffer size. - - - - - Reads the given stream up to the end, returning the data as a byte - array, using the given buffer for transferring data. Note that the - current contents of the buffer is ignored, so the buffer needn't - be cleared beforehand. - - - - - Copies all the data from one stream into another. - - - - - Copies all the data from one stream into another, using a buffer - of the given size. - - - - - Copies all the data from one stream into another, using the given - buffer for transferring data. Note that the current contents of - the buffer is ignored, so the buffer needn't be cleared beforehand. - - - - - Reads exactly the given number of bytes from the specified stream. - If the end of the stream is reached before the specified amount - of data is read, an exception is thrown. - - - - - Reads into a buffer, filling it completely. - - - - - Reads exactly the given number of bytes from the specified stream, - into the given buffer, starting at position 0 of the array. - - - - - Reads exactly the given number of bytes from the specified stream, - into the given buffer, starting at position 0 of the array. - - - - - Same as ReadExactly, but without the argument checks. - - - - - Converts from base: 0 - 62 - - The source. - From. - To. - - - - - Skip the encoding process for 'safe strings' - - - - - - - A class to allow the conversion of doubles to string representations of - their exact decimal values. The implementation aims for readability over - efficiency. - - Courtesy of @JonSkeet - http://www.yoda.arachsys.com/csharp/DoubleConverter.cs - - - - - - - - How many digits are *after* the decimal point - - - - - Constructs an arbitrary decimal expansion from the given long. - The long must not be negative. - - - - - Multiplies the current expansion by the given amount, which should - only be 2 or 5. - - - - - Shifts the decimal point; a negative value makes - the decimal expansion bigger (as fewer digits come after the - decimal place) and a positive value makes the decimal - expansion smaller. - - - - - Removes leading/trailing zeroes from the expansion. - - - - - Converts the value to a proper decimal string representation. - - - - - Creates an instance of a Type from a string value - - - - - Determines whether the specified type is convertible from string. - - The type. - - true if the specified type is convertible from string; otherwise, false. - - - - - Parses the specified value. - - The value. - - - - - Parses the specified type. - - The type. - The value. - - - - - Useful extension method to get the Dictionary[string,string] representation of any POCO type. - - - - - - Recursively prints the contents of any POCO object in a human-friendly, readable format - - - - - - Print Dump to Console.WriteLine - - - - - Print string.Format to Console.WriteLine - - - - - Parses the specified value. - - The value. - - - - diff --git a/lib/signed/ServiceStack.Text.dll b/lib/signed/ServiceStack.Text.dll deleted file mode 100644 index 794729c86..000000000 Binary files a/lib/signed/ServiceStack.Text.dll and /dev/null differ diff --git a/lib/sqlite3.def b/lib/sqlite3.def deleted file mode 100644 index 251d5bb56..000000000 --- a/lib/sqlite3.def +++ /dev/null @@ -1,210 +0,0 @@ -EXPORTS -sqlite3_aggregate_context -sqlite3_aggregate_count -sqlite3_auto_extension -sqlite3_backup_finish -sqlite3_backup_init -sqlite3_backup_pagecount -sqlite3_backup_remaining -sqlite3_backup_step -sqlite3_bind_blob -sqlite3_bind_double -sqlite3_bind_int -sqlite3_bind_int64 -sqlite3_bind_null -sqlite3_bind_parameter_count -sqlite3_bind_parameter_index -sqlite3_bind_parameter_name -sqlite3_bind_text -sqlite3_bind_text16 -sqlite3_bind_value -sqlite3_bind_zeroblob -sqlite3_blob_bytes -sqlite3_blob_close -sqlite3_blob_open -sqlite3_blob_read -sqlite3_blob_reopen -sqlite3_blob_write -sqlite3_busy_handler -sqlite3_busy_timeout -sqlite3_cancel_auto_extension -sqlite3_changes -sqlite3_clear_bindings -sqlite3_close -sqlite3_close_v2 -sqlite3_collation_needed -sqlite3_collation_needed16 -sqlite3_column_blob -sqlite3_column_bytes -sqlite3_column_bytes16 -sqlite3_column_count -sqlite3_column_database_name -sqlite3_column_database_name16 -sqlite3_column_decltype -sqlite3_column_decltype16 -sqlite3_column_double -sqlite3_column_int -sqlite3_column_int64 -sqlite3_column_name -sqlite3_column_name16 -sqlite3_column_origin_name -sqlite3_column_origin_name16 -sqlite3_column_table_name -sqlite3_column_table_name16 -sqlite3_column_text -sqlite3_column_text16 -sqlite3_column_type -sqlite3_column_value -sqlite3_commit_hook -sqlite3_compileoption_get -sqlite3_compileoption_used -sqlite3_complete -sqlite3_complete16 -sqlite3_config -sqlite3_context_db_handle -sqlite3_create_collation -sqlite3_create_collation16 -sqlite3_create_collation_v2 -sqlite3_create_function -sqlite3_create_function16 -sqlite3_create_function_v2 -sqlite3_create_module -sqlite3_create_module_v2 -sqlite3_data_count -sqlite3_db_config -sqlite3_db_filename -sqlite3_db_handle -sqlite3_db_mutex -sqlite3_db_readonly -sqlite3_db_release_memory -sqlite3_db_status -sqlite3_declare_vtab -sqlite3_enable_load_extension -sqlite3_enable_shared_cache -sqlite3_errcode -sqlite3_errmsg -sqlite3_errmsg16 -sqlite3_errstr -sqlite3_exec -sqlite3_expired -sqlite3_extended_errcode -sqlite3_extended_result_codes -sqlite3_file_control -sqlite3_finalize -sqlite3_free -sqlite3_free_table -sqlite3_get_autocommit -sqlite3_get_auxdata -sqlite3_get_table -sqlite3_global_recover -sqlite3_initialize -sqlite3_interrupt -sqlite3_last_insert_rowid -sqlite3_libversion -sqlite3_libversion_number -sqlite3_limit -sqlite3_load_extension -sqlite3_log -sqlite3_malloc -sqlite3_memory_alarm -sqlite3_memory_highwater -sqlite3_memory_used -sqlite3_mprintf -sqlite3_mutex_alloc -sqlite3_mutex_enter -sqlite3_mutex_free -sqlite3_mutex_leave -sqlite3_mutex_try -sqlite3_next_stmt -sqlite3_open -sqlite3_open16 -sqlite3_open_v2 -sqlite3_os_end -sqlite3_os_init -sqlite3_overload_function -sqlite3_prepare -sqlite3_prepare16 -sqlite3_prepare16_v2 -sqlite3_prepare_v2 -sqlite3_profile -sqlite3_progress_handler -sqlite3_randomness -sqlite3_realloc -sqlite3_release_memory -sqlite3_reset -sqlite3_reset_auto_extension -sqlite3_result_blob -sqlite3_result_double -sqlite3_result_error -sqlite3_result_error16 -sqlite3_result_error_code -sqlite3_result_error_nomem -sqlite3_result_error_toobig -sqlite3_result_int -sqlite3_result_int64 -sqlite3_result_null -sqlite3_result_text -sqlite3_result_text16 -sqlite3_result_text16be -sqlite3_result_text16le -sqlite3_result_value -sqlite3_result_zeroblob -sqlite3_rollback_hook -sqlite3_rtree_geometry_callback -sqlite3_set_authorizer -sqlite3_set_auxdata -sqlite3_shutdown -sqlite3_sleep -sqlite3_snprintf -sqlite3_soft_heap_limit -sqlite3_soft_heap_limit64 -sqlite3_sourceid -sqlite3_sql -sqlite3_status -sqlite3_step -sqlite3_stmt_busy -sqlite3_stmt_readonly -sqlite3_stmt_status -sqlite3_strglob -sqlite3_stricmp -sqlite3_strnicmp -sqlite3_table_column_metadata -sqlite3_test_control -sqlite3_thread_cleanup -sqlite3_threadsafe -sqlite3_total_changes -sqlite3_trace -sqlite3_transfer_bindings -sqlite3_update_hook -sqlite3_uri_boolean -sqlite3_uri_int64 -sqlite3_uri_parameter -sqlite3_user_data -sqlite3_value_blob -sqlite3_value_bytes -sqlite3_value_bytes16 -sqlite3_value_double -sqlite3_value_int -sqlite3_value_int64 -sqlite3_value_numeric_type -sqlite3_value_text -sqlite3_value_text16 -sqlite3_value_text16be -sqlite3_value_text16le -sqlite3_value_type -sqlite3_vfs_find -sqlite3_vfs_register -sqlite3_vfs_unregister -sqlite3_vmprintf -sqlite3_vsnprintf -sqlite3_vtab_config -sqlite3_vtab_on_conflict -sqlite3_wal_autocheckpoint -sqlite3_wal_checkpoint -sqlite3_wal_checkpoint_v2 -sqlite3_wal_hook -sqlite3_win32_mbcs_to_utf8 -sqlite3_win32_set_directory -sqlite3_win32_sleep -sqlite3_win32_utf8_to_mbcs -sqlite3_win32_write_debug diff --git a/lib/sqlite3.dll b/lib/sqlite3.dll deleted file mode 100644 index 1058a2b17..000000000 Binary files a/lib/sqlite3.dll and /dev/null differ diff --git a/lib/tests/Mono.Data.Sqlite.dll b/lib/tests/Mono.Data.Sqlite.dll deleted file mode 100644 index dad79f065..000000000 Binary files a/lib/tests/Mono.Data.Sqlite.dll and /dev/null differ diff --git a/lib/tests/Northwind.Common.dll b/lib/tests/Northwind.Common.dll deleted file mode 100644 index b33ffb109..000000000 Binary files a/lib/tests/Northwind.Common.dll and /dev/null differ diff --git a/lib/tests/Northwind.Common.pdb b/lib/tests/Northwind.Common.pdb deleted file mode 100644 index 50e93c29d..000000000 Binary files a/lib/tests/Northwind.Common.pdb and /dev/null differ diff --git a/lib/tests/Northwind.Perf.dll b/lib/tests/Northwind.Perf.dll deleted file mode 100644 index 2b06a8801..000000000 Binary files a/lib/tests/Northwind.Perf.dll and /dev/null differ diff --git a/lib/tests/Northwind.Perf.pdb b/lib/tests/Northwind.Perf.pdb deleted file mode 100644 index 5eff9823b..000000000 Binary files a/lib/tests/Northwind.Perf.pdb and /dev/null differ diff --git a/lib/tests/Platform.dll b/lib/tests/Platform.dll deleted file mode 100644 index 9261e75ff..000000000 Binary files a/lib/tests/Platform.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Client.dll b/lib/tests/ServiceStack.Client.dll deleted file mode 100644 index 30bcf562a..000000000 Binary files a/lib/tests/ServiceStack.Client.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Client.xml b/lib/tests/ServiceStack.Client.xml deleted file mode 100644 index 10ce7eee9..000000000 --- a/lib/tests/ServiceStack.Client.xml +++ /dev/null @@ -1,374 +0,0 @@ - - - - ServiceStack.Client - - - - Need to provide async request options - http://msdn.microsoft.com/en-us/library/86wf6409(VS.71).aspx - - - - The request filter is called before any request. - This request filter is executed globally. - - - - - The response action is called once the server response is available. - It will allow you to access raw response information. - This response action is executed globally. - Note that you should NOT consume the response stream as this is handled by ServiceStack - - - - - Called before request resend, when the initial request required authentication - - - - - The request filter is called before any request. - This request filter only works with the instance where it was set (not global). - - - - - The response action is called once the server response is available. - It will allow you to access raw response information. - Note that you should NOT consume the response stream as this is handled by ServiceStack - - - - - Returns the next message from queueName or null if no message - - - - - - - Generic Proxy for service calls. - - The service Contract - - - - Returns the transparent proxy for the service call - - - - Need to provide async request options - http://msdn.microsoft.com/en-us/library/86wf6409(VS.71).aspx - - - - The request filter is called before any request. - This request filter is executed globally. - - - - - The response action is called once the server response is available. - It will allow you to access raw response information. - This response action is executed globally. - Note that you should NOT consume the response stream as this is handled by ServiceStack - - - - - Sets all baseUri properties, using the Format property for the SyncReplyBaseUri and AsyncOneWayBaseUri - - Base URI of the service - - - - Whether to Accept Gzip,Deflate Content-Encoding and to auto decompress responses - - - - - The user name for basic authentication - - - - - The password for basic authentication - - - - - Sets the username and the password for basic authentication. - - - - - Determines if the basic auth header should be sent with every request. - By default, the basic auth header is only sent when "401 Unauthorized" is returned. - - - - - Specifies if cookies should be stored - - - - - Called by Send method if an exception occurs, for instance a System.Net.WebException because the server - returned an HTTP error code. Override if you want to handle specific exceptions or always want to parse the - response to a custom ErrorResponse DTO type instead of ServiceStack's ErrorResponse class. In case ex is a - System.Net.WebException, do not use - createWebRequest/getResponse/HandleResponse<TResponse> to parse the response - because that will result in the same exception again. Use - ThrowWebServiceException<YourErrorResponseType> to parse the response and to throw a - WebServiceException containing the parsed DTO. Then override Send to handle that exception. - - - - - Gets the collection of headers to be added to outgoing requests. - - - - - Whether to execute async callbacks on the same Synchronization Context it was called from. - - - - - Gets or sets authentication information for the request. - Warning: It's recommened to use and for basic auth. - This property is only used for IIS level authentication. - - - - - Called before request resend, when the initial request required authentication - - - - - The request filter is called before any request. - This request filter only works with the instance where it was set (not global). - - - - - The response action is called once the server response is available. - It will allow you to access raw response information. - Note that you should NOT consume the response stream as this is handled by ServiceStack - - - - - Creates the error response from the values provided. - - If the errorCode is empty it will use the first validation error code, - if there is none it will throw an error. - - The error code. - The error message. - The validation errors. - - - - - Default MaxStringContentLength is 8k, and throws an exception when reached - - - - - Serializer cache of delegates required to create a type from a string map (e.g. for REST urls) - - - - - Gets the namespace from an attribute marked on the type's definition - - - Namespace of type - - - - Specifies if cookies should be stored - - - - - Compresses the specified text using the default compression method: Deflate - - The text. - Type of the compression. - - - - - Decompresses the specified gz buffer using the default compression method: Inflate - - The gz buffer. - Type of the compression. - - - - - Donated by Ivan Korneliuk from his post: - http://korneliuk.blogspot.com/2012/08/servicestack-reusing-dtos.html - - Modified to only allow using routes matching the supplied HTTP Verb - - - - - Generate a url from a Request DTO. Pretty URL generation require Routes to be defined using `[Route]` on the Request DTO - - - - - The exception which is thrown when a validation error occurred. - This validation is serialized in a extra clean and human-readable way by ServiceStack. - - - - - Used if we need to serialize this exception to XML - - - - - - Returns the first error code - - The error code. - - - - Encapsulates a validation result. - - - - - Constructs a new ValidationResult - - - - - Constructs a new ValidationResult - - A list of validation results - - - - Initializes a new instance of the class. - - The errors. - The success code. - The error code. - - - - Merge errors from another - - - - - - Gets or sets the success code. - - The success code. - - - - Gets or sets the error code. - - The error code. - - - - Gets or sets the success message. - - The success message. - - - - Gets or sets the error message. - - The error message. - - - - The errors generated by the validation. - - - - - Returns True if the validation was successful (errors list is empty). - - - - - Adds the singleton instance of to an endpoint on the client. - - - Based on http://megakemp.wordpress.com/2009/02/06/managing-shared-cookies-in-wcf/ - - - - - Adds the singleton of the class to the client endpoint's message inspectors. - - The endpoint that is to be customized. - The client runtime to be customized. - - - - Maintains a copy of the cookies contained in the incoming HTTP response received from any service - and appends it to all outgoing HTTP requests. - - - This class effectively allows to send any received HTTP cookies to different services, - reproducing the same functionality available in ASMX Web Services proxies with the class. - Based on http://megakemp.wordpress.com/2009/02/06/managing-shared-cookies-in-wcf/ - - - - - Initializes a new instance of the class. - - - - - Inspects a message after a reply message is received but prior to passing it back to the client application. - - The message to be transformed into types and handed back to the client application. - Correlation state data. - - - - Inspects a message before a request message is sent to a service. - - The message to be sent to the service. - The client object channel. - - Null since no message correlation is used. - - - - - Gets the singleton instance. - - - - - Naming convention for the request's Response DTO - - - - - Shortcut to get the ResponseStatus whether it's bare or inside a IHttpResult - - - - - - diff --git a/lib/tests/ServiceStack.Common.Tests.dll b/lib/tests/ServiceStack.Common.Tests.dll deleted file mode 100644 index 3825ee424..000000000 Binary files a/lib/tests/ServiceStack.Common.Tests.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Common.Tests.dll.config b/lib/tests/ServiceStack.Common.Tests.dll.config deleted file mode 100644 index 3e05c78c7..000000000 --- a/lib/tests/ServiceStack.Common.Tests.dll.config +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/tests/ServiceStack.Common.Tests.pdb b/lib/tests/ServiceStack.Common.Tests.pdb deleted file mode 100644 index dca93b3bf..000000000 Binary files a/lib/tests/ServiceStack.Common.Tests.pdb and /dev/null differ diff --git a/lib/tests/ServiceStack.Common.dll b/lib/tests/ServiceStack.Common.dll deleted file mode 100644 index cde379b75..000000000 Binary files a/lib/tests/ServiceStack.Common.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Common.xml b/lib/tests/ServiceStack.Common.xml deleted file mode 100644 index eefa5dfbf..000000000 --- a/lib/tests/ServiceStack.Common.xml +++ /dev/null @@ -1,231 +0,0 @@ - - - - ServiceStack.Common - - - - - Useful .NET Encryption Utils from: - http://andrewlocatelliwoodcock.com/2011/08/01/implementing-rsa-asymmetric-public-private-key-encryption-in-c-encrypting-under-the-public-key/ - - - - - Encrypt an arbitrary string of data under the supplied public key - - The public key to encrypt under - The data to encrypt - The bit length or strength of the public key: 1024, 2048 or 4096 bits. This must match the - value actually used to create the publicKey - - - - - Create Public and Private Key Pair based on settings already in static class. - - RsaKeyPair - - - - Return T[0] when enumerable is null, safe to use in enumerations like foreach - - - - - Gets the textual description of the enum if it has one. e.g. - - - enum UserColors - { - [Description("Bright Red")] - BrightRed - } - UserColors.BrightRed.ToDescription(); - - - - - - - - Creates a Console Logger, that logs all messages to: System.Console - - Made public so its testable - - - - - Default logger is to Console.WriteLine - - Made public so its testable - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - - - Logs the specified message. - - - - - Logs the format. - - - - - Logs the specified message. - - - - - Useful IPAddressExtensions from: - http://blogs.msdn.com/knom/archive/2008/12/31/ip-address-calculations-with-c-subnetmasks-networks.aspx - - - - - - Gets the ipv4 addresses from all Network Interfaces that have Subnet masks. - - - - - - Gets the ipv6 addresses from all Network Interfaces. - - - - - - Func to get the Strongly-typed field - - - - - Required to cast the return ValueType to an object for caching - - - - - Func to set the Strongly-typed field - - - - - Required to cast the ValueType to an object for caching - - - - - Required to cast the ValueType to an object for caching - - - - - Func to get the Strongly-typed field - - - - - Required to cast the return ValueType to an object for caching - - - - - Func to set the Strongly-typed field - - - - - Required to cast the ValueType to an object for caching - - - - - Required to cast the ValueType to an object for caching - - - - - Common functionality when creating adapters - - - - - Executes the specified expression. - - - The action. - - - - - Executes the specified action (for void methods). - - The action. - - - - Note: InMemoryLog keeps all logs in memory, so don't use it long running exceptions - - Returns a thread-safe InMemoryLog which you can use while *TESTING* - to provide a detailed analysis of your logs. - - - - - Creates a Unified Resource Name (URN) with the following formats: - - - urn:{TypeName}:{IdFieldValue} e.g. urn:UserSession:1 - - urn:{TypeName}:{IdFieldName}:{IdFieldValue} e.g. urn:UserSession:UserId:1 - - - - - - - Provide the an option for the callee to block until all commands are executed - - - - - - - Invokes the action provided and returns true if no excpetion was thrown. - Otherwise logs the exception and returns false if an exception was thrown. - - The action. - - - - - Runs an action for a minimum of runForMs - - What to run - Minimum ms to run for - time elapsed in micro seconds - - - - Returns average microseconds an action takes when run for the specified runForMs - - What to run - How many times to run for each iteration - Minimum ms to run for - - - - - - - diff --git a/lib/tests/ServiceStack.Interfaces.dll b/lib/tests/ServiceStack.Interfaces.dll deleted file mode 100644 index b3c7ddc3c..000000000 Binary files a/lib/tests/ServiceStack.Interfaces.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Interfaces.xml b/lib/tests/ServiceStack.Interfaces.xml deleted file mode 100644 index 8729e037b..000000000 --- a/lib/tests/ServiceStack.Interfaces.xml +++ /dev/null @@ -1,1722 +0,0 @@ - - - - ServiceStack.Interfaces - - - - - A common interface implementation that is implemented by most cache providers - - - - - Removes the specified item from the cache. - - The identifier for the item to delete. - - true if the item was successfully removed from the cache; false otherwise. - - - - - Removes the cache for all the keys provided. - - The keys. - - - - Retrieves the specified item from the cache. - - - The identifier for the item to retrieve. - - The retrieved item, or null if the key was not found. - - - - - Increments the value of the specified key by the given amount. - The operation is atomic and happens on the server. - A non existent value at key starts at 0 - - The identifier for the item to increment. - The amount by which the client wants to increase the item. - - The new value of the item or -1 if not found. - - The item must be inserted into the cache before it can be changed. The item must be inserted as a . The operation only works with values, so -1 always indicates that the item was not found. - - - - Increments the value of the specified key by the given amount. - The operation is atomic and happens on the server. - A non existent value at key starts at 0 - - The identifier for the item to increment. - The amount by which the client wants to decrease the item. - - The new value of the item or -1 if not found. - - The item must be inserted into the cache before it can be changed. The item must be inserted as a . The operation only works with values, so -1 always indicates that the item was not found. - - - - Adds a new item into the cache at the specified cache key only if the cache is empty. - - The key used to reference the item. - The object to be inserted into the cache. - - true if the item was successfully stored in the cache; false otherwise. - - The item does not expire unless it is removed due memory pressure. - - - - Sets an item into the cache at the cache key specified regardless if it already exists or not. - - - - - Replaces the item at the cachekey specified only if an items exists at the location already. - - - - - Invalidates all data on the cache. - - - - - Retrieves multiple items from the cache. - The default value of T is set for all keys that do not exist. - - The list of identifiers for the items to retrieve. - - a Dictionary holding all items indexed by their key. - - - - - Sets multiple items to the cache. - - - The values. - - - - Removes items from cache that have keys matching the specified wildcard pattern - - The wildcard, where "*" means any sequence of characters and "?" means any single character. - - - - Removes items from the cache based on the specified regular expression pattern - - Regular expression pattern to search cache keys - - - - A light interface over a cache client. - This interface was inspired by Enyim.Caching.MemcachedClient - - Only the methods that are intended to be used are required, if you require - extra functionality you can uncomment the unused methods below as they have been - implemented in DdnMemcachedClient - - - - - Removes the specified item from the cache. - - The identifier for the item to delete. - - true if the item was successfully removed from the cache; false otherwise. - - - - - Removes the cache for all the keys provided. - - The keys. - - - - Retrieves the specified item from the cache. - - The identifier for the item to retrieve. - - The retrieved item, or null if the key was not found. - - - - - Increments the value of the specified key by the given amount. The operation is atomic and happens on the server. - - The identifier for the item to increment. - The amount by which the client wants to increase the item. - - The new value of the item or -1 if not found. - - The item must be inserted into the cache before it can be changed. The item must be inserted as a . The operation only works with values, so -1 always indicates that the item was not found. - - - - Increments the value of the specified key by the given amount. The operation is atomic and happens on the server. - - The identifier for the item to increment. - The amount by which the client wants to decrease the item. - - The new value of the item or -1 if not found. - - The item must be inserted into the cache before it can be changed. The item must be inserted as a . The operation only works with values, so -1 always indicates that the item was not found. - - - - Inserts an item into the cache with a cache key to reference its location. - - The key used to reference the item. - The object to be inserted into the cache. - - true if the item was successfully stored in the cache; false otherwise. - - The item does not expire unless it is removed due memory pressure. - - - - Inserts an item into the cache with a cache key to reference its location. - - The key used to reference the item. - The object to be inserted into the cache. - The time when the item is invalidated in the cache. - true if the item was successfully stored in the cache; false otherwise. - - - - Removes all data from the cache. - - - - - Retrieves multiple items from the cache. - - The list of identifiers for the items to retrieve. - - a Dictionary holding all items indexed by their key. - - - - - A Users Session - - - - - Set a typed value at key - - - - - - - - Get a typed value at key - - - - - - - - Store any object at key - - - - - - - Retrieves a User Session - - - - - Gets the session for this request, creates one if it doesn't exist. - - - - - - - - Gets the session for this request, creates one if it doesn't exist. - Only for ASP.NET apps. Uses the HttpContext.Current singleton. - - - - - Allow delegation of dependencies to other IOC's - - - - - Resolve Property Dependency - - - - - - - Resolve Constructor Dependency - - - - - - - BelongToAttribute - Use to indicate that a join column belongs to another table. - - - - - Compute attribute. - Use to indicate that a property is a Calculated Field - - - - - Mark types that are to be excluded from specified features - - - - - Decimal length attribute. - - - - - Explicit foreign key name. If it's null, or empty, the FK name will be autogenerated as before. - - - - - IgnoreAttribute - Use to indicate that a property is not a field in the table - properties with this attribute are ignored when building sql sentences - - - - - Primary key attribute. - use to indicate that property is part of the pk - - - - - Used to indicate that property is a row version incremented automatically by the database - - - - - Used to annotate an Entity with its DB schema - - - - - - For providers that want a cleaner API with a little more perf - - - - - - Decorate any type or property with adhoc info - - - - - Contract indication that the Response DTO has a ResponseStatus - - - - - Creates a Debug Logger, that logs all messages to: System.Diagnostics.Debug - - Made public so its testable - - - - - Factory to create ILog instances - - - - - Gets the logger. - - - - - Gets the logger. - - - - - Default logger is to System.Diagnostics.Debug.WriteLine - - Made public so its testable - - - - - Logs a message in a running application - - - - - Logs a Debug message. - - The message. - - - - Logs a Debug message and exception. - - The message. - The exception. - - - - Logs a Debug format message. - - The format. - The args. - - - - Logs a Error message. - - The message. - - - - Logs a Error message and exception. - - The message. - The exception. - - - - Logs a Error format message. - - The format. - The args. - - - - Logs a Fatal message. - - The message. - - - - Logs a Fatal message and exception. - - The message. - The exception. - - - - Logs a Error format message. - - The format. - The args. - - - - Logs an Info message and exception. - - The message. - - - - Logs an Info message and exception. - - The message. - The exception. - - - - Logs an Info format message. - - The format. - The args. - - - - Logs a Warning message. - - The message. - - - - Logs a Warning message and exception. - - The message. - The exception. - - - - Logs a Warning format message. - - The format. - The args. - - - - Gets or sets a value indicating whether this instance is debug enabled. - - - true if this instance is debug enabled; otherwise, false. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - - - Logs the specified message. - - - - - Logs the format. - - - - - Logs the specified message. - - - - - Default logger is to System.Diagnostics.Debug.Print - - Made public so its testable - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - - - Logs the specified message. - - - - - Logs the format. - - - - - Logs the specified message. - - - - - Creates a Debug Logger, that logs all messages to: System.Diagnostics.Debug - - Made public so its testable - - - - - StringBuilderLog writes to shared StringBuffer. - Made public so its testable - - - - - Logs the specified message. - - - - - Logs the format. - - - - - Logs the specified message. - - The message. - - - - Creates a test Logger, that stores all log messages in a member list - - - - - Tests logger which stores all log messages in a member list which can be examined later - - Made public so its testable - - - - - Initializes a new instance of the class. - - The type. - - - - Initializes a new instance of the class. - - The type. - - - - Logs the specified message. - - The message. - The exception. - - - - Logs the format. - - The message. - The args. - - - - Logs the specified message. - - The message. - - - - Logging API for this library. You can inject your own implementation otherwise - will use the DebugLogFactory to write to System.Diagnostics.Debug - - - - - Gets the logger. - - - - - Gets the logger. - - - - - Gets or sets the log factory. - Use this to override the factory that is used to create loggers - - - - - Publish the specified message into the durable queue @queueName - - - - - Publish the specified message into the transient queue @queueName - - - - - Synchronous blocking get. - - - - - Non blocking get message - - - - - Acknowledge the message has been successfully received or processed - - - - - Negative acknowledgement the message was not processed correctly - - - - - Create a typed message from a raw MQ Response artefact - - - - - Create a temporary Queue for Request / Reply - - - - - - Simple definition of an MQ Host - - - - - Register DTOs and hanlders the MQ Host will process - - - - - - - Register DTOs and hanlders the MQ Host will process - - - - - - - - Get Total Current Stats for all Message Handlers - - - - - - Get the status of the service. Potential Statuses: Disposed, Stopped, Stopping, Starting, Started - - - - - - Get a Stats dump - - - - - - Start the MQ Host if not already started. - - - - - Stop the MQ Host if not already stopped. - - - - - Factory to create consumers and producers that work with this service - - - - - Get a list of all message types registered on this MQ Host - - - - - Basic implementation of IMessage[T] - - - - - - Util static generic class to create unique queue names for types - - - - - - Util class to create unique queue names for runtime types - - - - - For messaging exceptions that should by-pass the messaging service's configured - retry attempts and store the message straight into the DLQ - - - - - Wrap the common redis list operations under a IList[string] interface. - - - - - Redis transaction for typed client - - - - - - interface to queueable operation using typed redis client - - - - - - Interface to redis typed pipeline - - - - - Pipeline interface shared by typed and non-typed pipelines - - - - - Interface to operations that allow queued commands to be completed - - - - - Returns a high-level typed client API - - - - - - Returns a Read/Write client (The default) using the hosts defined in ReadWriteHosts - - - - - - Returns a ReadOnly client using the hosts defined in ReadOnlyHosts. - - - - - - Returns a Read/Write ICacheClient (The default) using the hosts defined in ReadWriteHosts - - - - - - Returns a ReadOnly ICacheClient using the hosts defined in ReadOnlyHosts. - - - - - - Returns a Read/Write client (The default) using the hosts defined in ReadWriteHosts - - - - - - Returns a ReadOnly client using the hosts defined in ReadOnlyHosts. - - - - - - Returns a Read/Write ICacheClient (The default) using the hosts defined in ReadWriteHosts - - - - - - Returns a ReadOnly ICacheClient using the hosts defined in ReadOnlyHosts. - - - - - - Subscribe to channels by name - - - - - - Subscribe to channels matching the supplied patterns - - - - - - The number of active subscriptions this client has - - - - - Registered handler called after client *Subscribes* to each new channel - - - - - Registered handler called when each message is received - - - - - Registered handler called when each channel is unsubscribed - - - - - Interface to redis transaction - - - - - Base transaction interface, shared by typed and non-typed transactions - - - - - interface to operation that can queue commands - - - - - Interface to redis pipeline - - - - - Gets or sets parameter name with which allowable values will be associated. - - - - - The overall description of an API. Used by Swagger. - - - - - Gets or sets verb to which applies attribute. By default applies to all verbs. - - - - - Gets or sets parameter type: It can be only one of the following: path, query, body, model, or header. - - - - - Gets or sets unique name for the parameter. Each name must be unique, even if they are associated with different paramType values. - - - - Other notes on the name field: - If paramType is body, the name is used only for UI and codegeneration. - If paramType is path, the name field must correspond to the associated path segment from the path field in the api object. - If paramType is query, the name field corresponds to the query param name. - - - - - - Gets or sets the human-readable description for the parameter. - - - - - For path, query, and header paramTypes, this field must be a primitive. For body, this can be a complex or container datatype. - - - - - For path, this is always true. Otherwise, this field tells the client whether or not the field must be supplied. - - - - - For query params, this specifies that a comma-separated list of values can be passed to the API. For path and body types, this field cannot be true. - - - - - Gets or sets route to which applies attribute, matches using StartsWith. By default applies to all routes. - - - - - The status code of a response - - - - - The description of a response status code - - - - - Marker interfaces - - - - - Implement on Request DTOs that need access to the raw Request Stream - - - - - The raw Http Request Input Stream - - - - - Resolve a dependency from the AppHost's IOC - - - - - - - This interface can be implemented by an attribute - which adds an request filter for the specific request DTO the attribute marked. - - - - - The request filter is executed before the service. - - The http request wrapper - The http response wrapper - The request DTO - - - - A new shallow copy of this filter is used on every request. - - - - - - Order in which Request Filters are executed. - <0 Executed before global request filters - >0 Executed after global request filters - - - - - This interface can be implemented by an attribute - which adds an response filter for the specific response DTO the attribute marked. - - - - - The response filter is executed after the service - - The http request wrapper - The http response wrapper - - - - A new shallow copy of this filter is used on every request. - - - - - - Order in which Response Filters are executed. - <0 Executed before global response filters - >0 Executed after global response filters - - - - - The HTTP Response Status - - - - - The HTTP Response Status Code - - - - - The HTTP Status Description - - - - - The HTTP Response ContentType - - - - - Additional HTTP Headers - - - - - Response DTO - - - - - if not provided, get's injected by ServiceStack - - - - - Holds the request call context - - - - - The padding length written with the body, to be added to ContentLength of body - - - - - A thin wrapper around ASP.NET or HttpListener's HttpRequest - - - - - A thin wrapper around each host's Request e.g: ASP.NET, HttpListener, MQ, etc - - - - - The entire string contents of Request.InputStream - - - - - - The underlying ASP.NET or HttpListener HttpRequest - - - - - The name of the service being called (e.g. Request DTO Name) - - - - - The Verb / HttpMethod or Action for this request - - - - - Optional preferences for the processing of this Request - - - - - The Request DTO, after it has been deserialized. - - - - - The request ContentType - - - - - The expected Response ContentType for this request - - - - - Whether the ResponseContentType has been explicitly overrided or whether it was just the default - - - - - Attach any data to this request that all filters and services can access. - - - - - Buffer the Request InputStream so it can be re-read - - - - - The Remote Ip as reported by Request.UserHostAddress - - - - - The Remote Ip as reported by X-Forwarded-For, X-Real-IP or Request.UserHostAddress - - - - - e.g. is https or not - - - - - Access to the multi-part/formdata files posted on this request - - - - - The value of the Referrer, null if not available - - - - - The HttpResponse - - - - - The HTTP Verb - - - - - The IP Address of the X-Forwarded-For header, null if null or empty - - - - - The Port number of the X-Forwarded-Port header, null if null or empty - - - - - The http or https scheme of the X-Forwarded-Proto header, null if null or empty - - - - - The value of the X-Real-IP header, null if null or empty - - - - - A thin wrapper around ASP.NET or HttpListener's HttpResponse - - - - - A thin wrapper around each host's Response e.g: ASP.NET, HttpListener, MQ, etc - - - - - Write once to the Response Stream then close it. - - - - - - Signal that this response has been handled and no more processing should be done. - When used in a request or response filter, no more filters or processing is done on this request. - - - - - Calls Response.End() on ASP.NET HttpResponse otherwise is an alias for Close(). - Useful when you want to prevent ASP.NET to provide it's own custom error page. - - - - - Response.Flush() and OutputStream.Flush() seem to have different behaviour in ASP.NET - - - - - The underlying ASP.NET or HttpListener HttpResponse - - - - - The Response DTO - - - - - Buffer the Response OutputStream so it can be written in 1 batch - - - - - Gets a value indicating whether this instance is closed. - - - - - Log every service request - - - - - Log a request - - The RequestContext - Request DTO - Response DTO or Exception - How long did the Request take - - - - View the most recent logs - - - - - - - Turn On/Off Session Tracking - - - - - Turn On/Off Raw Request Body Tracking - - - - - Turn On/Off Tracking of Responses - - - - - Turn On/Off Tracking of Exceptions - - - - - Limit access to /requestlogs service to role - - - - - Don't log requests of these types. - - - - - Don't log request bodys for services with sensitive information. - By default Auth and Registration requests are hidden. - - - - - Implement on services that need access to the RequestContext - - - - - Responsible for executing the operation within the specified context. - - The operation types. - - - - Returns the first matching RestPath - - - - - Executes the MQ DTO request. - - - - - Executes the MQ DTO request with the supplied requestContext - - - - - Executes the DTO request under the supplied requestContext. - - - - - Executes the DTO request with an empty RequestContext. - - - - - Allow the registration of user-defined routes for services - - - - - Maps the specified REST path to the specified request DTO. - - The type of request DTO to map - the path to. - The path to map the request DTO to. - See RouteAttribute.Path - for details on the correct format. - The same instance; - never . - - - - Maps the specified REST path to the specified request DTO, and - specifies the HTTP verbs supported by the path. - - The type of request DTO to map - the path to. - The path to map the request DTO to. - See RouteAttribute.Path - for details on the correct format. - - The comma-delimited list of HTTP verbs supported by the path, - such as "GET,PUT,DELETE". Specify empty or - to indicate that all verbs are supported. - - The same instance; - never . - - - - Maps the specified REST path to the specified request DTO, - specifies the HTTP verbs supported by the path, and indicates - the default MIME type of the returned response. - - - The type of request DTO to map the path to. - - The path to map the request DTO to. - See RouteAttribute.Path - for details on the correct format. - - The comma-delimited list of HTTP verbs supported by the path, - such as "GET,PUT,DELETE". - - The same instance; - never . - - - - Maps the specified REST path to the specified request DTO, - specifies the HTTP verbs supported by the path, and indicates - the default MIME type of the returned response. - - - Used to rank the precedences of route definitions in reverse routing. - i.e. Priorities below 0 are auto-generated have less precedence. - - - - - Maps the specified REST path to the specified request DTO, - specifies the HTTP verbs supported by the path, and indicates - the default MIME type of the returned response. - - - The type of request DTO to map the path to. - - The path to map the request DTO to. - See RouteAttribute.Path - for details on the correct format. - - The comma-delimited list of HTTP verbs supported by the path, - such as "GET,PUT,DELETE". - - - The short summary of what the REST does. - - - The longer text to explain the behaviour of the REST. - - The same instance; - never . - - - - Used to decorate Request DTO's to associate a RESTful request - path mapping with a service. Multiple attributes can be applied to - each request DTO, to map multiple paths to the service. - - - - - Initializes an instance of the class. - - - The path template to map to the request. See - RouteAttribute.Path - for details on the correct format. - - - - - Initializes an instance of the class. - - - The path template to map to the request. See - RouteAttribute.Path - for details on the correct format. - - A comma-delimited list of HTTP verbs supported by the - service. If unspecified, all verbs are assumed to be supported. - - - - Gets or sets the path template to be mapped to the request. - - - A value providing the path mapped to - the request. Never . - - - Some examples of valid paths are: - - - "/Inventory" - "/Inventory/{Category}/{ItemId}" - "/Inventory/{ItemPath*}" - - - Variables are specified within "{}" - brackets. Each variable in the path is mapped to the same-named property - on the request DTO. At runtime, ServiceStack will parse the - request URL, extract the variable values, instantiate the request DTO, - and assign the variable values into the corresponding request properties, - prior to passing the request DTO to the service object for processing. - - It is not necessary to specify all request properties as - variables in the path. For unspecified properties, callers may provide - values in the query string. For example: the URL - "http://services/Inventory?Category=Books&ItemId=12345" causes the same - request DTO to be processed as "http://services/Inventory/Books/12345", - provided that the paths "/Inventory" (which supports the first URL) and - "/Inventory/{Category}/{ItemId}" (which supports the second URL) - are both mapped to the request DTO. - - Please note that while it is possible to specify property values - in the query string, it is generally considered to be less RESTful and - less desirable than to specify them as variables in the path. Using the - query string to specify property values may also interfere with HTTP - caching. - - The final variable in the path may contain a "*" suffix - to grab all remaining segments in the path portion of the request URL and assign - them to a single property on the request DTO. - For example, if the path "/Inventory/{ItemPath*}" is mapped to the request DTO, - then the request URL "http://services/Inventory/Books/12345" will result - in a request DTO whose ItemPath property contains "Books/12345". - You may only specify one such variable in the path, and it must be positioned at - the end of the path. - - - - - Gets or sets short summary of what the route does. - - - - - Gets or sets longer text to explain the behaviour of the route. - - - - - Gets or sets a comma-delimited list of HTTP verbs supported by the service, such as - "GET,PUT,POST,DELETE". - - - A providing a comma-delimited list of HTTP verbs supported - by the service, or empty if all verbs are supported. - - - - - Used to rank the precedences of route definitions in reverse routing. - i.e. Priorities below 0 are auto-generated have less precedence. - - - - - Fallback routes have the lowest precedence, i.e. after normal Routes, static files or any matching Catch All Handlers. - - - - - Generic ResponseStatus for when Response Type can't be inferred. - In schemaless formats like JSON, JSV it has the same shape as a typed Response DTO - - - - - A log entry added by the IRequestLogger - - - - - Decorate on Request DTO's to alter the accessibility of a service and its visibility on /metadata pages - - - - - Restrict access and metadata visibility to any of the specified access scenarios - - The restrict access to scenarios. - - - - Restrict access and metadata visibility to any of the specified access scenarios - - The restrict access to scenarios. - - - - Returns the allowed set of scenarios based on the user-specified restrictions - - - - - - - Allow access but hide from metadata to requests from Localhost only - - - - - Allow access but hide from metadata to requests from Localhost and Local Intranet only - - - - - Restrict access and hide from metadata to requests from Localhost only - - - - - Restrict access and hide from metadata to requests from Localhost and Local Intranet only - - - - - Restrict access and hide from metadata to requests from External only - - - - - Sets a single access restriction - - Restrict Access to. - - - - Restrict access to any of the specified access scenarios - - Access restrictions - - - - Sets a single metadata Visibility restriction - - Restrict metadata Visibility to. - - - - Restrict metadata visibility to any of the specified access scenarios - - Visibility restrictions - - - - Converts from a User intended restriction to a flag with all the allowed attribute flags set, e.g: - - If No Network restrictions were specified all Network access types are allowed, e.g: - restrict EndpointAttributes.None => ... 111 - - If a Network restriction was specified, only it will be allowed, e.g: - restrict EndpointAttributes.LocalSubnet => ... 010 - - The returned Enum will have a flag with all the allowed attributes set - - - - - - - Error information pertaining to a particular named field. - Used for returning multiple field validation errors.s - - - - - Common ResponseStatus class that should be present on all response DTO's - - - - - Initializes a new instance of the class. - - A response status without an errorcode == success - - - - - Initializes a new instance of the class. - - A response status with an errorcode == failure - - - - - Initializes a new instance of the class. - - A response status with an errorcode == failure - - - - - Holds the custom ErrorCode enum if provided in ValidationException - otherwise will hold the name of the Exception type, e.g. typeof(Exception).Name - - A value of non-null means the service encountered an error while processing the request. - - - - - A human friendly error message - - - - - - - - - - For multiple detailed validation errors. - Can hold a specific error message for each named field. - - - - - Write a partial content result - - - - - Whether this HttpResult allows Partial Response - - - - - Sends the specified request. - - The request. - - - - diff --git a/lib/tests/ServiceStack.OrmLite.dll b/lib/tests/ServiceStack.OrmLite.dll deleted file mode 100644 index 3e57b18bf..000000000 Binary files a/lib/tests/ServiceStack.OrmLite.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.OrmLite.xml b/lib/tests/ServiceStack.OrmLite.xml deleted file mode 100644 index ce3527bf6..000000000 --- a/lib/tests/ServiceStack.OrmLite.xml +++ /dev/null @@ -1,2245 +0,0 @@ - - - - ServiceStack.OrmLite - - - - - Tell ServiceStack to use ThreadStatic Items Collection for Context Scoped items. - Warning: ThreadStatic Items aren't pinned to the same request in async services which callback on different threads. - - - - - Gets a list of items for this context. - - - - - Clear select expression. All properties will be selected. - - - - - set the specified selectExpression. - - - raw Select expression: "Select SomeField1, SomeField2 from SomeTable" - - - - - Fields to be selected. - - - x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} - - - objectWithProperties - - - - - Offset of the first row to return. The offset of the initial row is 0 - - - - - Number of rows returned by a SELECT statement - - - - - Set the specified offset and rows for SQL Limit clause. - - - Offset of the first row to return. The offset of the initial row is 0 - - - Number of rows returned by a SELECT statement - - - - - Set the specified offset and rows for SQL Limit clause where they exist. - - - Offset of the first row to return. The offset of the initial row is 0 - - - Number of rows returned by a SELECT statement - - - - - Set the specified rows for Sql Limit clause. - - - Number of rows returned by a SELECT statement - - - - - Clear Sql Limit clause - - - - - Clear Offset and Limit clauses. Alias for Limit() - - - - - - - Fields to be updated. - - - x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} - - - objectWithProperties - - - - - Clear UpdateFields list ( all fields will be updated) - - - - - Fields to be inserted. - - - x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} - - - objectWithProperties - - - - - fields to be inserted. - - - IList<string> containing Names of properties to be inserted - - - - - Clear InsertFields list ( all fields will be inserted) - - - - - Enables the efficient, dynamic composition of query predicates. - - - - - Creates a predicate that evaluates to true. - - - - - Creates a predicate that evaluates to false. - - - - - Creates a predicate expression from the specified lambda expression. - - - - - Combines the first predicate with the second using the logical "and". - - - - - Combines the first predicate with the second using the logical "or". - - - - - Negates the predicate. - - - - - Combines the first expression with the second using the specified merge function. - - - - - Create a new SqlExpression builder allowing typed LINQ-like queries. - - - - - Creates a new SqlExpression builder allowing typed LINQ-like queries. - Alias for SqlExpression. - - - - - Creates a new SqlExpression builder for the specified type using a user-defined FROM sql expression. - - - - - Open a Transaction in OrmLite - - - - - Open a Transaction in OrmLite - - - - - Create a managed OrmLite IDbCommand - - - - - Returns results from using a LINQ Expression. E.g: - db.Select<Person>(x => x.Age > 40) - - - - - Returns results from using an SqlExpression lambda. E.g: - db.Select<Person>(q => q.Where(x => x.Age > 40)) - - - - - Returns results from using an SqlExpression lambda. E.g: - db.Select(db.From<Person>().Where(x => x.Age > 40)) - - - - - Project results from a number of joined tables into a different model - - - - - Project results from a number of joined tables into a different model - - - - - Returns results from using an SqlExpression lambda. E.g: - db.Select(db.From<Person>().Where(x => x.Age > 40)) - - - - - Returns a single result from using a LINQ Expression. E.g: - db.Single<Person>(x => x.Age == 42) - - - - - Returns a single result from using an SqlExpression lambda. E.g: - db.Single<Person>(q => q.Where(x => x.Age == 42)) - - - - - Returns results from using an SqlExpression lambda. E.g: - db.Select<Person>(x => x.Age > 40) - - - - - Returns a scalar result from using an SqlExpression lambda. E.g: - db.Scalar<Person, int>(x => Sql.Max(x.Age)) - - - - - Returns a scalar result from using an SqlExpression lambda. E.g: - db.Scalar<Person, int>(x => Sql.Max(x.Age), , x => x.Age < 50) - - - - - Returns the count of rows that match the LINQ expression, E.g: - db.Count<Person>(x => x.Age < 50) - - - - - Returns the count of rows that match the SqlExpression lambda, E.g: - db.Count<Person>(q => q.Where(x => x.Age < 50)) - - - - - Returns the count of rows that match the supplied SqlExpression, E.g: - db.Count(db.From<Person>().Where(x => x.Age < 50)) - - - - - Return the number of rows returned by the supplied expression - - - - - Return the number of rows returned by the supplied sql - - - - - Returns results with references from using a LINQ Expression. E.g: - db.LoadSelect<Person>(x => x.Age > 40) - - - - - Returns results with references from using an SqlExpression lambda. E.g: - db.LoadSelect<Person>(q => q.Where(x => x.Age > 40)) - - - - - Returns results with references from using an SqlExpression lambda. E.g: - db.LoadSelect(db.From<Person>().Where(x => x.Age > 40)) - - - - - Project results with references from a number of joined tables into a different model - - - - - Use an SqlExpression to select which fields to update and construct the where expression, E.g: - - db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') - - What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: - - db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); - UPDATE "Person" SET "FirstName" = 'JJ' - - - - - Use an SqlExpression to select which fields to update and construct the where expression, E.g: - - var q = db.From>Person<()); - db.UpdateOnly(new Person { FirstName = "JJ" }, q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') - - What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: - - db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev.Update(p => p.FirstName)); - UPDATE "Person" SET "FirstName" = 'JJ' - - - - - Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: - - db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); - UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') - - db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName); - UPDATE "Person" SET "FirstName" = 'JJ' - - - - - Updates all non-default values set on item matching the where condition (if any). E.g - - db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.FirstName == "Jimi"); - UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') - - - - - Updates all values set on item matching the where condition (if any). E.g - - db.Update(new Person { Id = 1, FirstName = "JJ" }, p => p.LastName == "Hendrix"); - UPDATE "Person" SET "Id" = 1,"FirstName" = 'JJ',"LastName" = NULL,"Age" = 0 WHERE ("LastName" = 'Hendrix') - - - - - Updates all matching fields populated on anonymousType that matches where condition (if any). E.g: - - db.Update<Person>(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') - - - - - Flexible Update method to succinctly execute a free-text update statement using optional params. E.g: - - db.Update<Person>(set:"FirstName = {0}".Params("JJ"), where:"LastName = {0}".Params("Hendrix")); - UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' - - - - - Flexible Update method to succinctly execute a free-text update statement using optional params. E.g. - - db.Update(table:"Person", set: "FirstName = {0}".Params("JJ"), where: "LastName = {0}".Params("Hendrix")); - UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' - - - - - Insert only fields in POCO specified by the SqlExpression lambda. E.g: - db.InsertOnly(new Person { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })) - - - - - Using an SqlExpression to only Insert the fields specified, e.g: - - db.InsertOnly(new Person { FirstName = "Amy" }, q => q.Insert(p => new { p.FirstName })); - INSERT INTO "Person" ("FirstName") VALUES ('Amy'); - - - - - Delete the rows that matches the where expression, e.g: - - db.Delete<Person>(p => p.Age == 27); - DELETE FROM "Person" WHERE ("Age" = 27) - - - - - Delete the rows that matches the where expression, e.g: - - db.Delete<Person>(ev => ev.Where(p => p.Age == 27)); - DELETE FROM "Person" WHERE ("Age" = 27) - - - - - Delete the rows that matches the where expression, e.g: - - var q = db.From>Person<()); - db.Delete<Person>(q.Where(p => p.Age == 27)); - DELETE FROM "Person" WHERE ("Age" = 27) - - - - - Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. - - db.Delete<Person>(where:"Age = {0}".Params(27)); - DELETE FROM "Person" WHERE Age = 27 - - - - - Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. - - db.Delete(table:"Person", where: "Age = {0}".Params(27)); - DELETE FROM "Person" WHERE Age = 27 - - - - - Offset of the first row to return. The offset of the initial row is 0 - - - - - Number of rows returned by a SELECT statement - - - - - Set the specified offset and rows for SQL Limit clause. - - - Offset of the first row to return. The offset of the initial row is 0 - - - Number of rows returned by a SELECT statement - - - - - Set the specified offset and rows for SQL Limit clause where they exist. - - - Offset of the first row to return. The offset of the initial row is 0 - - - Number of rows returned by a SELECT statement - - - - - Set the specified rows for Sql Limit clause. - - - Number of rows returned by a SELECT statement - - - - - Clear Sql Limit clause - - - - - Returns results from the active connection. - - - - - Returns results from using sql. E.g: - db.Select<Person>("Age > 40") - db.Select<Person>("SELECT * FROM Person WHERE Age > 40") - - - - - Returns results from using a parameterized query. E.g: - db.Select<Person>("Age > @age", new { age = 40}) - db.Select<Person>("SELECT * FROM Person WHERE Age > @age", new { age = 40}) - - - - - Returns results from using a parameterized query. E.g: - db.Select<Person>("Age > @age", new Dictionary<string, object> { { "age", 40 } }) - db.Select<Person>("SELECT * FROM Person WHERE Age > @age", new Dictionary<string, object> { { "age", 40 } }) - - - - - Returns results from using an SqlFormat query. E.g: - db.SelectFmt<Person>("Age > {0}", 40) - db.SelectFmt<Person>("SELECT * FROM Person WHERE Age > {0}", 40) - - - - - Returns a partial subset of results from the specified tableType. E.g: - db.Select<EntityWithId>(typeof(Person)) - - - - - - Returns a partial subset of results from the specified tableType using a SqlFormat query. E.g: - db.SelectFmt<EntityWithId>(typeof(Person), "Age > {0}", 40) - - - - - Returns results from using a single name, value filter. E.g: - db.Where<Person>("Age", 27) - - - - - Returns results from using an anonymous type filter. E.g: - db.Where<Person>(new { Age = 27 }) - - - - - Returns results using the supplied primary key ids. E.g: - db.SelectByIds<Person>(new[] { 1, 2, 3 }) - - - - - Query results using the non-default values in the supplied partially populated POCO example. E.g: - db.SelectNonDefaults(new Person { Id = 1 }) - - - - - Query results using the non-default values in the supplied partially populated POCO example. E.g: - db.SelectNonDefaults("Age > @Age", new Person { Age = 42 }) - - - - - Returns a lazyily loaded stream of results. E.g: - db.SelectLazy<Person>() - - - - - Returns a lazyily loaded stream of results using a parameterized query. E.g: - db.SelectLazy<Person>("Age > @age", new { age = 40 }) - - - - - Returns a lazyily loaded stream of results using an SqlFilter query. E.g: - db.SelectLazyFmt<Person>("Age > {0}", 40) - - - - - Returns a stream of results that are lazily loaded using a parameterized query. E.g: - db.WhereLazy<Person>(new { Age = 27 }) - - - - - Returns the first result using a parameterized query. E.g: - db.Single<Person>(new { Age = 42 }) - - - - - Returns results from using a single name, value filter. E.g: - db.Single<Person>("Age = @age", new { age = 42 }) - - - - - Returns the first result using a SqlFormat query. E.g: - db.SingleFmt<Person>("Age = {0}", 42) - - - - - Returns the first result using a primary key id. E.g: - db.SingleById<Person>(1) - - - - - Returns the first result using a name, value filter. E.g: - db.SingleWhere<Person>("Age", 42) - - - - - Returns a single scalar value using an SqlExpression. E.g: - db.Column<int>(db.From<Persion>().Select(x => Sql.Count("*")).Where(q => q.Age > 40)) - - - - - Returns a single scalar value using a parameterized query. E.g: - db.Scalar<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }) - - - - - Returns a single scalar value using an SqlFormat query. E.g: - db.ScalarFmt<int>("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40) - - - - - Returns the distinct first column values in a HashSet using an SqlExpression. E.g: - db.Column<int>(db.From<Persion>().Select(x => x.LastName).Where(q => q.Age == 27)) - - - - - Returns the first column in a List using a SqlFormat query. E.g: - db.ColumnLazy<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) - - - - - Returns the distinct first column values in a HashSet using an SqlExpression. E.g: - db.ColumnLazy<int>(db.From<Persion>().Select(x => x.LastName).Where(q => q.Age == 27)) - - - - - Returns the first column in a List using a SqlFormat query. E.g: - db.Column<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) - - - - - Returns the first column in a List using a SqlFormat query. E.g: - db.ColumnFmt<string>("SELECT LastName FROM Person WHERE Age = {0}", 27) - - - - - - Returns the distinct first column values in a HashSet using an SqlFormat query. E.g: - db.ColumnDistinct<int>("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }) - - - - - Returns the distinct first column values in a HashSet using an SqlFormat query. E.g: - db.ColumnDistinctFmt<int>("SELECT Age FROM Person WHERE Age < {0}", 50) - - - - - - Returns an Dictionary<K, List<V>> grouping made from the first two columns using an parameterized query. E.g: - db.Lookup<int, string>("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }) - - - - - Returns an Dictionary<K, List<V>> grouping made from the first two columns using an SqlFormat query. E.g: - db.LookupFmt<int, string>("SELECT Age, LastName FROM Person WHERE Age < {0}", 50) - - - - - - Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using sql. E.g: - db.Dictionary<int, string>("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }) - - - - - Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlFormat query. E.g: - db.DictionaryFmt<int, string>("SELECT Id, LastName FROM Person WHERE Age < {0}", 50) - - - - - Returns true if the Query returns any records that match the LINQ expression, E.g: - db.Exists<Person>(x => x.Age < 50) - - - - - Returns true if the Query returns any records that match the SqlExpression lambda, E.g: - db.Exists<Person>(q => q.Where(x => x.Age < 50)) - - - - - Returns true if the Query returns any records that match the supplied SqlExpression, E.g: - db.Exists(db.From<Person>().Where(x => x.Age < 50)) - - - - - Returns true if the Query returns any records, using an SqlFormat query. E.g: - db.Exists<Person>(new { Age = 42 }) - - - - - Returns true if the Query returns any records, using a parameterized query. E.g: - db.Exists<Person>("Age = @age", new { age = 42 }) - db.Exists<Person>("SELECT * FROM Person WHERE Age = @age", new { age = 42 }) - - - - - Returns true if the Query returns any records, using an SqlFormat query. E.g: - db.ExistsFmt<Person>("Age = {0}", 42) - db.ExistsFmt<Person>("SELECT * FROM Person WHERE Age = {0}", 50) - - - - - Returns results from an arbitrary SqlExpression. E.g: - db.SqlList<Person>(db.From<Person>().Select("*").Where(q => q.Age < 50)) - - - - - Returns results from an arbitrary parameterized raw sql query. E.g: - db.SqlList<Person>("EXEC GetRockstarsAged @age", new { age = 50 }) - - - - - Returns results from an arbitrary parameterized raw sql query. E.g: - db.SqlList<Person>("EXEC GetRockstarsAged @age", new Dictionary<string, object> { { "age", 42 } }) - - - - - Returns results from an arbitrary parameterized raw sql query with a dbCmd filter. E.g: - db.SqlList<Person>("EXEC GetRockstarsAged @age", dbCmd => ...) - - - - - Prepare Stored Procedure with Input parameters, optionally populated with Input Params. E.g: - var cmd = db.SqlProc("GetRockstarsAged", new { age = 42 }) - - - - - - Returns the first column in a List using a parameterized query. E.g: - db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }) - - - - - Returns the first column in a List using a parameterized query. E.g: - db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } }) - - - - - Returns a single Scalar value using an SqlExpression. E.g: - db.SqlScalar<int>(db.From<Person>().Select(Sql.Count("*")).Where(q => q.Age < 50)) - - - - - Returns a single Scalar value using a parameterized query. E.g: - db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }) - - - - - Returns a single Scalar value using a parameterized query. E.g: - db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } }) - - - - - Returns the last insert Id made from this connection. - - - - - Executes a raw sql non-query using sql. E.g: - var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFormat("WaterHouse", 7)) - - number of rows affected - - - - Executes a raw sql non-query using a parameterized query. E.g: - var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }) - - number of rows affected - - - - Executes a raw sql non-query using a parameterized query. - - number of rows affected - - - - Returns results from a Stored Procedure, using a parameterized query. - - - - - Returns results from a Stored Procedure using an SqlFormat query. E.g: - - - - - - Returns the scalar result as a long. - - - - - Returns the first result with all its references loaded, using a primary key id. E.g: - db.LoadSingleById<Person>(1) - - - - - Loads all the related references onto the instance. E.g: - db.LoadReferences(customer) - - - - - Checks whether a Table Exists. E.g: - db.TableExists("Person") - - - - - Checks whether a Table Exists. E.g: - db.TableExists<Person>() - - - - - Create DB Tables from the schemas of runtime types. E.g: - db.CreateTables(typeof(Table1), typeof(Table2)) - - - - - Create DB Table from the schema of the runtime type. Use overwrite to drop existing Table. E.g: - db.CreateTable(true, typeof(Table)) - - - - - Only Create new DB Tables from the schemas of runtime types if they don't already exist. E.g: - db.CreateTableIfNotExists(typeof(Table1), typeof(Table2)) - - - - - Drop existing DB Tables and re-create them from the schemas of runtime types. E.g: - db.DropAndCreateTables(typeof(Table1), typeof(Table2)) - - - - - Create a DB Table from the generic type. Use overwrite to drop the existing table or not. E.g: - db.CreateTable<Person>(overwrite=false) //default - db.CreateTable<Person>(overwrite=true) - - - - - Only create a DB Table from the generic type if it doesn't already exist. E.g: - db.CreateTableIfNotExists<Person>() - - - - - Only create a DB Table from the runtime type if it doesn't already exist. E.g: - db.CreateTableIfNotExists(typeof(Person)) - - - - - Drop existing table if exists and re-create a DB Table from the generic type. E.g: - db.DropAndCreateTable<Person>() - - - - - Drop existing table if exists and re-create a DB Table from the runtime type. E.g: - db.DropAndCreateTable(typeof(Person)) - - - - - Drop any existing tables from their runtime types. E.g: - db.DropTables(typeof(Table1),typeof(Table2)) - - - - - Drop any existing tables from the runtime type. E.g: - db.DropTable(typeof(Person)) - - - - - Drop any existing tables from the generic type. E.g: - db.DropTable<Person>() - - - - - Get the last SQL statement that was executed. - - - - - Execute any arbitrary raw SQL. - - number of rows affected - - - - Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: - var id = db.Insert(new Person { Id = 1, FirstName = "Jimi }, selectIdentity:true) - - - - - Insert 1 or more POCOs in a transaction. E.g: - db.Insert(new Person { Id = 1, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, - new Person { Id = 2, FirstName = "Biggie", LastName = "Smalls", Age = 24 }) - - - - - Insert a collection of POCOs in a transaction. E.g: - db.InsertAll(new[] { new Person { Id = 9, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }) - - - - - Updates 1 POCO. All fields are updated except for the PrimaryKey which is used as the identity selector. E.g: - db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) - - - - - Updates 1 or more POCOs in a transaction. E.g: - db.Update(new Person { Id = 1, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, - new Person { Id = 2, FirstName = "Biggie", LastName = "Smalls", Age = 24 }) - - - - - Updates 1 or more POCOs in a transaction. E.g: - db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }) - - - - - Delete rows using an anonymous type filter. E.g: - db.Delete<Person>(new { FirstName = "Jimi", Age = 27 }) - - number of rows deleted - - - - Delete 1 or more rows in a transaction using an anonymous type filter. E.g: - db.Delete<Person>(new { FirstName = "Jimi", Age = 27 }, new { FirstName = "Janis", Age = 27 }) - - - - - Delete 1 row using all fields in the filter. E.g: - db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) - - number of rows deleted - - - - Delete 1 or more rows in a transaction using all fields in the filter. E.g: - db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) - - - - - Delete 1 or more rows using only field with non-default values in the filter. E.g: - db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }) - - number of rows deleted - - - - Delete 1 or more rows in a transaction using only field with non-default values in the filter. E.g: - db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }, - new Person { FirstName = "Janis", Age = 27 }) - - number of rows deleted - - - - Delete 1 row by the PrimaryKey. E.g: - db.DeleteById<Person>(1) - - number of rows deleted - - - - Delete 1 row by the PrimaryKey where the rowVersion matches the optimistic concurrency field. - Will throw RowModefiedExeption if the - row does not exist or has a different row version. - E.g: db.DeleteById<Person>(1) - - - - - Delete all rows identified by the PrimaryKeys. E.g: - db.DeleteById<Person>(new[] { 1, 2, 3 }) - - number of rows deleted - - - - Delete all rows in the generic table type. E.g: - db.DeleteAll<Person>() - - number of rows deleted - - - - Delete all rows in the runtime table type. E.g: - db.DeleteAll(typeof(Person)) - - number of rows deleted - - - - Delete rows using a SqlFormat filter. E.g: - - number of rows deleted - - - - Delete rows from the runtime table type using a SqlFormat filter. E.g: - - db.DeleteFmt(typeof(Person), "Age = {0}", 27) - number of rows deleted - - - - Insert a new row or update existing row. Returns true if a new row was inserted. - Optional references param decides whether to save all related references as well. E.g: - db.Save(customer, references:true) - - true if a row was inserted; false if it was updated - - - - Insert new rows or update existing rows. Return number of rows added E.g: - db.Save(new Person { Id = 10, FirstName = "Amy", LastName = "Winehouse", Age = 27 }) - - number of rows added - - - - Insert new rows or update existing rows. Return number of rows added E.g: - db.SaveAll(new [] { new Person { Id = 10, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }) - - number of rows added - - - - Populates all related references on the instance with its primary key and saves them. Uses '(T)Id' naming convention. E.g: - db.SaveAllReferences(customer) - - - - - Populates the related references with the instance primary key and saves them. Uses '(T)Id' naming convention. E.g: - db.SaveReference(customer, customer.Orders) - - - - - Populates the related references with the instance primary key and saves them. Uses '(T)Id' naming convention. E.g: - db.SaveReference(customer, customer.Orders) - - - - - Populates the related references with the instance primary key and saves them. Uses '(T)Id' naming convention. E.g: - db.SaveReferences(customer, customer.Orders) - - - - - Wrapper IDbConnection class to allow for connection sharing, mocking, etc. - - - - - Allow for mocking and unit testing by providing non-disposing - connection factory with injectable IDbCommand and IDbTransaction proxies - - - - - Force the IDbConnection to always return this IDbCommand - - - - - Force the IDbConnection to always return this IDbTransaction - - - - - Alias for OpenDbConnection - - - - - Alias for OpenDbConnection - - - - - Allow for code-sharing between OrmLite, IPersistenceProvider and ICacheClient - - - - - Quote the string so that it can be used inside an SQL-expression - Escape quotes inside the string - - - - - - - Populates row fields during re-hydration of results. - - - - Fmt - - - - Nice SqlBuilder class by @samsaffron from Dapper.Contrib: - http://samsaffron.com/archive/2011/09/05/Digging+ourselves+out+of+the+mess+Linq-2-SQL+created - Modified to work in .NET 3.5 - - - - - Additional state flags that control command behaviour - - - - - No additonal flags - - - - - Should data be buffered before returning? - - - - - Can async queries be pipelined? - - - - - Should the plan cache be bypassed? - - - - - Represents the key aspects of a sql operation - - - - - Initialize the command definition - - - - - The command (sql or a stored-procedure name) to execute - - - - - The parameters associated with the command - - - - - The active transaction for the command - - - - - The effective timeout for the command - - - - - The type of command that the command-text represents - - - - - Should data be buffered before returning? - - - - - Should the plan for this query be cached? - - - - - Additional state flags against this command - - - - - Can async queries be pipelined? - - - - - Dapper, a light weight object mapper for ADO.NET - - - - - Key used to indicate the type name associated with a DataTable - - - - - Purge the query cache - - - - - Return a count of all the cached queries by dapper - - - - - - Return a list of all the queries cached by dapper - - - - - - - Deep diagnostics only: find any hash collisions in the cache - - - - - - Clear the registered type handlers - - - - - Configire the specified type to be mapped to a given db-type - - - - - Configire the specified type to be processed by a custom handler - - - - - Configire the specified type to be processed by a custom handler - - - - - Configire the specified type to be processed by a custom handler - - - - - Get the DbType that maps to a given value - - - - - Execute parameterized SQL - - Number of rows affected - - - - Execute parameterized SQL - - Number of rows affected - - - - Execute parameterized SQL that selects a single value - - The first cell selected - - - - Execute parameterized SQL that selects a single value - - The first cell selected - - - - Execute parameterized SQL that selects a single value - - The first cell selected - - - - Execute parameterized SQL that selects a single value - - The first cell selected - - - - Execute parameterized SQL and return an - - An that can be used to iterate over the results of the SQL query. - - This is typically used when the results of a query are not processed by Dapper, for example, used to fill a DataTable or DataSet. - - - - - - - - - - Execute parameterized SQL and return an - - An that can be used to iterate over the results of the SQL query. - - This is typically used when the results of a query are not processed by Dapper, for example, used to fill a DataTable or DataSet. - - - - - Execute parameterized SQL and return an - - An that can be used to iterate over the results of the SQL query. - - This is typically used when the results of a query are not processed by Dapper, for example, used to fill a DataTable or DataSet. - - - - - Return a list of dynamic objects, reader is closed after the call - - - - - Executes a query, returning the data typed as per T - - the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - - - - - Executes a query, returning the data typed as per the Type suggested - - A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - - - - - Executes a query, returning the data typed as per T - - the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - - - - - Execute a command that returns multiple result sets, and access each in turn - - - - - Execute a command that returns multiple result sets, and access each in turn - - - - - Maps a query to objects - - The first type in the recordset - The second type in the recordset - The return type - - - - - - - The Field we should split and read the second object from (default: id) - Number of seconds before command execution timeout - Is it a stored proc or a batch? - - - - - Maps a query to objects - - - - - - - - - - - - The Field we should split and read the second object from (default: id) - Number of seconds before command execution timeout - - - - - - Perform a multi mapping query with 4 input parameters - - - - - - - - - - - - - - - - - - - - Perform a multi mapping query with 5 input parameters - - - - - - - - - - - - - - - - - - - - - Perform a multi mapping query with 6 input parameters - - - - - - - - - - - - - - - - - - - - - - Perform a multi mapping query with 7 input parameters - - - - - - - - - - - - - - - - - - - - - - - Perform a multi mapping query with arbitrary input parameters - - The return type - - - array of types in the recordset - - - - - The Field we should split and read the second object from (default: id) - Number of seconds before command execution timeout - Is it a stored proc or a batch? - - - - - Internal use only - - - - - - - Internal use only - - - - - Internal use only - - - - - Internal use only - - - - - Replace all literal tokens with their text form - - - - - Convert numeric values to their string form for SQL literal purposes - - - - - Internal use only - - - - - Gets type-map for the given type - - Type map implementation, DefaultTypeMap instance if no override present - - - - Set custom mapping for type deserializers - - Entity type to override - Mapping rules impementation, null to remove custom map - - - - Internal use only - - - - - - - - - - - Throws a data exception, only used internally - - - - - Called if the query cache is purged via PurgeQueryCache - - - - - How should connection strings be compared for equivalence? Defaults to StringComparer.Ordinal. - Providing a custom implementation can be useful for allowing multi-tenancy databases with identical - schema to share startegies. Note that usual equivalence rules apply: any equivalent connection strings - MUST yield the same hash-code. - - - - - Implement this interface to pass an arbitrary db specific set of parameters to Dapper - - - - - Add all the parameters needed to the command just before it executes - - The raw command prior to execution - Information about the query - - - - Extends IDynamicParameters providing by-name lookup of parameter values - - - - - Get the value of the specified parameter (return null if not found) - - - - - Extends IDynamicParameters with facitilies for executing callbacks after commands have completed - - - - - Invoked when the command has executed - - - - - Implement this interface to pass an arbitrary db specific parameter to Dapper - - - - - Add the parameter needed to the command before it executes - - The raw command prior to execution - Parameter name - - - - Implement this interface to perform custom type-based parameter handling and value parsing - - - - - Assign the value of a parameter before a command executes - - The parameter to configure - Parameter value - - - - Parse a database value back to a typed value - - The value from the database - The type to parse to - The typed value - - - - A type handler for data-types that are supported by the underlying provider, but which need - a well-known UdtTypeName to be specified - - - - - Creates a new instance of UdtTypeHandler with the specified UdtTypeName - - - - - Base-class for simple type-handlers - - - - - Assign the value of a parameter before a command executes - - The parameter to configure - Parameter value - - - - Parse a database value back to a typed value - - The value from the database - The typed value - - - - Implement this interface to change default mapping of reader columns to type memebers - - - - - Finds best constructor - - DataReader column names - DataReader column types - Matching constructor or default one - - - - Gets mapping for constructor parameter - - Constructor to resolve - DataReader column name - Mapping implementation - - - - Gets member mapping for column - - DataReader column name - Mapping implementation - - - - Implements this interface to provide custom member mapping - - - - - Source DataReader column name - - - - - Target member type - - - - - Target property - - - - - Target field - - - - - Target constructor parameter - - - - - This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - equality. The type is fully thread-safe. - - - - - Not intended for direct usage - - - - - Not intended for direct usage - - - - - Not intended for direct usage - - - - - Identity of a cached query in Dapper, used for extensability - - - - - Create an identity for use with DynamicParameters, internal use only - - - - - - - - - - - - - - The sql - - - - - The command type - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compare 2 Identity objects - - - - - - - Represents a placeholder for a value that should be replaced as a literal value in the resulting sql - - - - - The text in the original command that should be replaced - - - - - The name of the member referred to by the token - - - - - The grid reader provides interfaces for reading multiple result sets from a Dapper query - - - - - Read the next grid of results, returned as a dynamic object - - - - - Read the next grid of results - - - - - Read the next grid of results - - - - - Read multiple objects from a single recordset on the grid - - - - - Read multiple objects from a single recordset on the grid - - - - - Read multiple objects from a single record set on the grid - - - - - Read multiple objects from a single record set on the grid - - - - - Read multiple objects from a single record set on the grid - - - - - Read multiple objects from a single record set on the grid - - - - - Dispose the grid, closing and disposing both the underlying reader and command. - - - - - Has the underlying reader been consumed? - - - - - A bag of parameters that can be passed to the Dapper Query and Execute methods - - - - - construct a dynamic parameter bag - - - - - construct a dynamic parameter bag - - can be an anonymous type or a DynamicParameters bag - - - - Append a whole object full of params to the dynamic - EG: AddDynamicParams(new {A = 1, B = 2}) // will add property A and B to the dynamic - - - - - - Add a parameter to this dynamic parameter list - - - - - - - - - - Add all the parameters needed to the command just before it executes - - The raw command prior to execution - Information about the query - - - - Get the value of a parameter - - - - The value, note DBNull.Value is not returned, instead the value is returned as null - - - - Allows you to automatically populate a target property/field from output parameters. It actually - creates an InputOutput parameter, so you can still pass data in. - - - The object whose property/field you wish to populate. - A MemberExpression targeting a property/field of the target (or descendant thereof.) - - The size to set on the parameter. Defaults to 0, or DbString.DefaultLength in case of strings. - The DynamicParameters instance - - - - If true, the command-text is inspected and only values that are clearly used are included on the connection - - - - - All the names of the param in the bag, use Get to yank them out - - - - - This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar - - - - - A value to set the default value of strings - going through Dapper. Default is 4000, any value larger than this - field will not have the default value applied. - - - - - Create a new DbString - - - - - Add the parameter to the command... internal use only - - - - - - - Ansi vs Unicode - - - - - Fixed length - - - - - Length of the string -1 for max - - - - - The value of the string - - - - - Handles variances in features per DBMS - - - - - Gets the featureset based on the passed connection - - - - - True if the db supports array columns e.g. Postgresql - - - - - Represents simple memeber map for one of target parameter or property or field to source DataReader column - - - - - Creates instance for simple property mapping - - DataReader column name - Target property - - - - Creates instance for simple field mapping - - DataReader column name - Target property - - - - Creates instance for simple constructor parameter mapping - - DataReader column name - Target constructor parameter - - - - DataReader column name - - - - - Target member type - - - - - Target property - - - - - Target field - - - - - Target constructor parameter - - - - - Represents default type mapping strategy used by Dapper - - - - - Creates default type map - - Entity type - - - - Finds best constructor - - DataReader column names - DataReader column types - Matching constructor or default one - - - - Gets mapping for constructor parameter - - Constructor to resolve - DataReader column name - Mapping implementation - - - - Gets member mapping for column - - DataReader column name - Mapping implementation - - - - Should column names like User_Id be allowed to match properties/fields like UserId ? - - - - - Implements custom property mapping by user provided criteria (usually presence of some custom attribute with column to member mapping) - - - - - Creates custom property mapping - - Target entity type - Property selector based on target type and DataReader column name - - - - Always returns default constructor - - DataReader column names - DataReader column types - Default constructor - - - - Not impelmeneted as far as default constructor used for all cases - - - - - - - - Returns property based on selector strategy - - DataReader column name - Poperty member map - - - diff --git a/lib/tests/ServiceStack.Redis.dll b/lib/tests/ServiceStack.Redis.dll deleted file mode 100644 index 90b6a3bc3..000000000 Binary files a/lib/tests/ServiceStack.Redis.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Redis.xml b/lib/tests/ServiceStack.Redis.xml deleted file mode 100644 index 1b460938a..000000000 --- a/lib/tests/ServiceStack.Redis.xml +++ /dev/null @@ -1,1382 +0,0 @@ - - - - ServiceStack.Redis - - - - - Provides thread-safe retrievel of redis clients since each client is a new one. - Allows the configuration of different ReadWrite and ReadOnly hosts - - - BasicRedisClientManager for ICacheClient - - For more interoperabilty I'm also implementing the ICacheClient on - this cache client manager which has the affect of calling - GetCacheClient() for all write operations and GetReadOnlyCacheClient() - for the read ones. - - This works well for master-slave replication scenarios where you have - 1 master that replicates to multiple read slaves. - - - - - Hosts can be an IP Address or Hostname in the format: host[:port] - e.g. 127.0.0.1:6379 - default is: localhost:6379 - - The write hosts. - The read hosts. - - - - Returns a Read/Write client (The default) using the hosts defined in ReadWriteHosts - - - - - - Returns a ReadOnly client using the hosts defined in ReadOnlyHosts. - - - - - - Gets or sets object key prefix. - - - - - Courtesy of @marcgravell - http://code.google.com/p/protobuf-net/source/browse/trunk/protobuf-net/BufferPool.cs - - - - - Provides thread-safe pooling of redis client connections. - - - - - Returns a Read/Write client (The default) using the hosts defined in ReadWriteHosts - - - - - - Called within a lock - - - - - - Disposes the write client. - - The client. - - - - The client wraps the native redis operations into a more readable c# API. - - Where possible these operations are also exposed in common c# interfaces, - e.g. RedisClient.Lists => IList[string] - RedisClient.Sets => ICollection[string] - - - - - This class contains all the common operations for the RedisClient. - The client contains a 1:1 mapping of c# methods to redis operations of the same name. - - Not threadsafe use a pooled manager - - - - - Requires custom result parsing - - Number of results - - - - Command to set multuple binary safe arguments - - - - - - - reset buffer index in send buffer - - - - - Used to manage connection pooling - - - - - Gets or sets object key prefix. - - - - - Creates a new instance of the Redis Client from NewFactoryFn. - - - - - Alias for GetValue - - - - - Returns key with automatic object id detection in provided value with generic type. - - - - - - - Returns key with explicit object id. - - - - - - - Returns key with explicit object type and id. - - - - - - - - A complete redis command, with method to send command, receive response, and run callback on success or failure - - - - - Allows you to get Redis value operations to operate against POCO types. - - - - - - Use this to share the same redis connection with another - - The client. - - - - Pipeline for redis typed client - - - - - - Queue of commands for redis typed client - - - - - - Redis operation (transaction/pipeline) that allows queued commands to be completed - - - - - For interoperabilty GetCacheClient() and GetReadOnlyCacheClient() - return an ICacheClient wrapper around the redis manager which has the affect of calling - GetClient() for all write operations and GetReadOnlyClient() for the read ones. - - This works well for master-slave replication scenarios where you have - 1 master that replicates to multiple read slaves. - - - - - Ignore dispose on RedisClientsManager, which should be registered as a singleton - - - - - Useful wrapper IRedisClientsManager to cut down the boiler plate of most IRedisClient access - - - - - Creates a PubSubServer that uses a background thread to listen and process for - Redis Pub/Sub messages published to the specified channel. - Use optional callbacks to listen for message, error and life-cycle events. - Callbacks can be assigned later, then call Start() for PubSubServer to start listening for messages - - - - - A complete redis command, with method to send command, receive response, and run callback on success or failure - - - - - Redis command that does not get queued - - - - - Initialize channel and register client manager - - - - - - Check if GetValidSentinel should try the next sentinel server - - - This will be true if the failures is less than either RedisSentinel.MaxFailures or the # of sentinels, whatever is greater - - - - Raised if there is an error from a sentinel worker - - - - - - - Event that is fired when the sentinel subscription raises an event - - - - - - - Does a sentinel check for masters and slaves and either sets up or fails over to the new config - - - - - Takes output from sentinel slaves command and converts into a list of servers - - - - - - - Takes output from sentinel master command and converts into a list of servers - - - - - - - Provides a redis connection pool that can be sharded - - - - - Provides thread-safe pooling of redis client connections. - Allows load-balancing of master-write and read-slave hosts, ideal for - 1 master and multiple replicated read slaves. - - - - - Hosts can be an IP Address or Hostname in the format: host[:port] - e.g. 127.0.0.1:6379 - default is: localhost:6379 - - The write hosts. - The read hosts. - The config. - - - - Returns a Read/Write client (The default) using the hosts defined in ReadWriteHosts - - - - - - Called within a lock - - - - - - Returns a ReadOnly client using the hosts defined in ReadOnlyHosts. - - - - - - Called within a lock - - - - - - Disposes the read only client. - - The client. - - - - Disposes the write client. - - The client. - - - - Gets or sets object key prefix. - - - - - Manage a client acquired from the PooledRedisClientManager - Dispose method will release the client back to the pool. - - - - - wrap the acquired client - - - - - - release the wrapped client back to the pool - - - - - access the wrapped client - - - - - logical name - - - - - An arbitrary weight relative to other nodes - - - - logical name - An arbitrary weight relative to other nodes - redis nodes - - - - Provides sharding of redis client connections. - uses consistent hashing to distribute keys across connection pools - - - - - maps a key to a redis connection pool - - key to map - a redis connection pool - - - - Adds a node and maps points across the circle - - node to add - An arbitrary number, specifies how often it occurs relative to other targets. - - - - A variation of Binary Search algorithm. Given a number, matches the next highest number from the sorted array. - If a higher number does not exist, then the first number in the array is returned. - - a sorted array to perform the search - number to find the next highest number against - next highest number - - - - Given a key, generates an unsigned 64 bit hash code using MD5 - - - - - - - Provides access to the method reflection data as part of the before/after event - - - - - Stores details about the context in which an IRedisClient is allocated. - - - - - - Tracks each IRedisClient instance allocated from the IRedisClientsManager logging when they are allocated and disposed. - Periodically writes the allocated instances to the log for diagnostic purposes. - - - - - Distributed lock interface - - - - - Optimized implementation. Primitive types are manually serialized, the rest are serialized using binary serializer />. - - - - - serialize/deserialize arbitrary objects - (objects must be serializable) - - - - - Serialize object to buffer - - serializable object - - - - - Deserialize buffer to object - - byte array to deserialize - - - - - - - - - - - - - - - - - - - serialize value and wrap with - - - - - - - Unwrap object wrapped in - - - - - - - pop numProcessed items from queue and unlock queue for work item id that dequeued - items are associated with - - - - - - A dequeued work item has been processed. When all of the dequeued items have been processed, - all items will be popped from the queue,and the queue unlocked for the work item id that - the dequeued items are associated with - - - - - Update first unprocessed item with new work item. - - - - - - - - - - - distributed work item queue. Each message must have an associated - work item id. For a given id, all work items are guaranteed to be processed - in the order in which they are received. - - - - - distributed work item queue. Each message must have an associated - work item id. For a given id, all work items are guaranteed to be processed - in the order in which they are received. - - - - - - - distributed work item queue - - - - - Enqueue item in priority queue corresponding to workItemId identifier - - - - - - - Preprare next work item id for dequeueing - - - - - Dequeue up to maxBatchSize items from queue corresponding to workItemId identifier. - Once this method is called, or will not - return any items for workItemId until the dequeue lock returned is unlocked. - - - - - - - - Replace existing work item in workItemId queue - - - - - - - - Queue incoming messages - - - - - - - Must call this periodically to move work items from priority queue to pending queue - - - - - Replace existing work item in workItemId queue - - - - - - - - Pop items from list - - - - - - - Force release of locks held by crashed servers - - - - - release lock held by crashed server - - - - true if lock is released, either by this method or by another client; false otherwise - - - - Unlock work item id, so other servers can process items for this id - - - - - - - - - - - - - - - - - - - - - - - - - - - pop remaining items that were returned by dequeue, and unlock queue - - - - - - indicate that an item has been processed by the caller - - - - - Update first unprocessed work item - - - - - - wraps a serialized representation of an object - - - - - - Initializes a new instance of . - - Custom item data. - The serialized item. - - - - The data representing the item being stored/retireved. - - - - - Flags set for this instance. - - - - - distributed lock class that follows the Resource Allocation Is Initialization pattern - - - - - Lock - - - - in seconds - in seconds - - - - unlock - - - - - Enqueue item - - - - - - Dequeue up to maxBatchSize items from queue - - - - - - - distributed work item queue. Messages are processed in chronological order - - - - - Enqueue incoming messages - - - - - - - - Dequeue next batch of work items - - - - - - - - - simple distributed work item queue - - - - - - - Queue incoming messages - - - - - - Dequeue next batch of work items for processing. After this method is called, - no other work items with same id will be available for - dequeuing until PostDequeue is called - - KeyValuePair: key is work item id, and value is list of dequeued items. - - - - - Serialize object to buffer - - serializable object - - - - - - - array of serializable objects - - - - - Deserialize buffer to object - - byte array to deserialize - - - - - - customize the client serializer - - - - - Factory to create SerializingRedisClient objects - - - - - - - - - General purpose pipeline - - - - - - Flush send buffer, and read responses - - - - - Wrap the common redis set operations under a ICollection[string] interface. - - - - - Adds support for Redis Transactions (i.e. MULTI/EXEC/DISCARD operations). - - - - - Put "QUEUED" messages at back of queue - - - - - - Issue exec command (not queued) - - - - - callback for after result count is read in - - - - - - Wrap the common redis set operations under a ICollection[string] interface. - - - - - Wrap the common redis set operations under a ICollection[string] interface. - - - - - Wrap the common redis set operations under a ICollection[string] interface. - - - - - Redis-specific exception. Thrown if unable to connect to Redis server due to socket exception, for example. - - - - - Adds support for Redis Transactions (i.e. MULTI/EXEC/DISCARD operations). - - - - - Put "QUEUED" messages at back of queue - - - - - - Issue exec command (not queued) - - - - - callback for after result count is read in - - - - - - Provide the default factory implementation for creating a RedisClient that - can be mocked and used by different 'Redis Client Managers' - - - - - Wrap the common redis set operations under a ICollection[string] interface. - - - - - Provide the factory implementation for creating a RedisCacheClient that - can be mocked and used by different 'Redis Client Managers' - - - - - Wrap the common redis set operations under a ICollection[string] interface. - - - - - Wrap the common redis list operations under a IList[string] interface. - - - - - Represents a generic collection of key/value pairs that are ordered independently of the key and value. - - The type of the keys in the dictionary - The type of the values in the dictionary - - - - Adds an entry with the specified key and value into the IOrderedDictionary<TKey,TValue> collection with the lowest available index. - - The key of the entry to add. - The value of the entry to add. - The index of the newly added entry - - You can also use the property to add new elements by setting the value of a key that does not exist in the IOrderedDictionary<TKey,TValue> collection; however, if the specified key already exists in the IOrderedDictionary<TKey,TValue>, setting the property overwrites the old value. In contrast, the method does not modify existing elements. - An element with the same key already exists in the IOrderedDictionary<TKey,TValue> - The IOrderedDictionary<TKey,TValue> is read-only.
- -or-
- The IOrderedDictionary<TKey,TValue> has a fized size.
-
- - - Inserts a new entry into the IOrderedDictionary<TKey,TValue> collection with the specified key and value at the specified index. - - The zero-based index at which the element should be inserted. - The key of the entry to add. - The value of the entry to add. The value can be if the type of the values in the dictionary is a reference type. - is less than 0.
- -or-
- is greater than .
- An element with the same key already exists in the IOrderedDictionary<TKey,TValue>. - The IOrderedDictionary<TKey,TValue> is read-only.
- -or-
- The IOrderedDictionary<TKey,TValue> has a fized size.
-
- - - Gets or sets the value at the specified index. - - The zero-based index of the value to get or set. - The value of the item at the specified index. - is less than 0.
- -or-
- is equal to or greater than .
-
- - - Represents a generic collection of key/value pairs that are ordered independently of the key and value. - - The type of the keys in the dictionary - The type of the values in the dictionary - - - - Initializes a new instance of the OrderedDictionary<TKey,TValue> class. - - - - - Initializes a new instance of the OrderedDictionary<TKey,TValue> class using the specified initial capacity. - - The initial number of elements that the OrderedDictionary<TKey,TValue> can contain. - is less than 0 - - - - Initializes a new instance of the OrderedDictionary<TKey,TValue> class using the specified comparer. - - The IEqualityComparer<TKey> to use when comparing keys, or to use the default EqualityComparer<TKey> for the type of the key. - - - - Initializes a new instance of the OrderedDictionary<TKey,TValue> class using the specified initial capacity and comparer. - - The initial number of elements that the OrderedDictionary<TKey,TValue> collection can contain. - The IEqualityComparer<TKey> to use when comparing keys, or to use the default EqualityComparer<TKey> for the type of the key. - is less than 0 - - - - Converts the object passed as a key to the key type of the dictionary - - The key object to check - The key object, cast as the key type of the dictionary - is . - The key type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of . - - - - Converts the object passed as a value to the value type of the dictionary - - The object to convert to the value type of the dictionary - The value object, converted to the value type of the dictionary - is , and the value type of the OrderedDictionary<TKey,TValue> is a value type. - The value type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of . - - - - Inserts a new entry into the OrderedDictionary<TKey,TValue> collection with the specified key and value at the specified index. - - The zero-based index at which the element should be inserted. - The key of the entry to add. - The value of the entry to add. The value can be if the type of the values in the dictionary is a reference type. - is less than 0.
- -or-
- is greater than .
- is . - An element with the same key already exists in the OrderedDictionary<TKey,TValue>. -
- - - Inserts a new entry into the OrderedDictionary<TKey,TValue> collection with the specified key and value at the specified index. - - The zero-based index at which the element should be inserted. - The key of the entry to add. - The value of the entry to add. The value can be if the type of the values in the dictionary is a reference type. - is less than 0.
- -or-
- is greater than .
- is .
- -or-
- is , and the value type of the OrderedDictionary<TKey,TValue> is a value type.
- The key type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of .
- -or-
- The value type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of .
- -or-
- An element with the same key already exists in the OrderedDictionary<TKey,TValue>.
-
- - - Removes the entry at the specified index from the OrderedDictionary<TKey,TValue> collection. - - The zero-based index of the entry to remove. - is less than 0.
- -or-
- index is equal to or greater than .
-
- - - Adds an entry with the specified key and value into the OrderedDictionary<TKey,TValue> collection with the lowest available index. - - The key of the entry to add. - The value of the entry to add. This value can be . - A key cannot be , but a value can be. - You can also use the property to add new elements by setting the value of a key that does not exist in the OrderedDictionary<TKey,TValue> collection; however, if the specified key already exists in the OrderedDictionary<TKey,TValue>, setting the property overwrites the old value. In contrast, the method does not modify existing elements. - is - An element with the same key already exists in the OrderedDictionary<TKey,TValue> - - - - Adds an entry with the specified key and value into the OrderedDictionary<TKey,TValue> collection with the lowest available index. - - The key of the entry to add. - The value of the entry to add. This value can be . - The index of the newly added entry - A key cannot be , but a value can be. - You can also use the property to add new elements by setting the value of a key that does not exist in the OrderedDictionary<TKey,TValue> collection; however, if the specified key already exists in the OrderedDictionary<TKey,TValue>, setting the property overwrites the old value. In contrast, the method does not modify existing elements. - is - An element with the same key already exists in the OrderedDictionary<TKey,TValue> - - - - Adds an entry with the specified key and value into the OrderedDictionary<TKey,TValue> collection with the lowest available index. - - The key of the entry to add. - The value of the entry to add. This value can be . - is .
- -or-
- is , and the value type of the OrderedDictionary<TKey,TValue> is a value type.
- The key type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of .
- -or-
- The value type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of .
-
- - - Removes all elements from the OrderedDictionary<TKey,TValue> collection. - - The capacity is not changed as a result of calling this method. - - - - Determines whether the OrderedDictionary<TKey,TValue> collection contains a specific key. - - The key to locate in the OrderedDictionary<TKey,TValue> collection. - if the OrderedDictionary<TKey,TValue> collection contains an element with the specified key; otherwise, . - is - - - - Determines whether the OrderedDictionary<TKey,TValue> collection contains a specific key. - - The key to locate in the OrderedDictionary<TKey,TValue> collection. - if the OrderedDictionary<TKey,TValue> collection contains an element with the specified key; otherwise, . - is - The key type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of . - - - - Returns the zero-based index of the specified key in the OrderedDictionary<TKey,TValue> - - The key to locate in the OrderedDictionary<TKey,TValue> - The zero-based index of , if is found in the OrderedDictionary<TKey,TValue>; otherwise, -1 - This method performs a linear search; therefore it has a cost of O(n) at worst. - - - - Removes the entry with the specified key from the OrderedDictionary<TKey,TValue> collection. - - The key of the entry to remove - if the key was found and the corresponding element was removed; otherwise, - - - - Removes the entry with the specified key from the OrderedDictionary<TKey,TValue> collection. - - The key of the entry to remove - - - - Copies the elements of the OrderedDictionary<TKey,TValue> elements to a one-dimensional Array object at the specified index. - - The one-dimensional object that is the destination of the objects copied from the OrderedDictionary<TKey,TValue>. The must have zero-based indexing. - The zero-based index in at which copying begins. - The method preserves the order of the elements in the OrderedDictionary<TKey,TValue> - - - - Gets the value associated with the specified key. - - The key of the value to get. - When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of . This parameter can be passed uninitialized. - if the OrderedDictionary<TKey,TValue> contains an element with the specified key; otherwise, . - - - - Adds the specified value to the OrderedDictionary<TKey,TValue> with the specified key. - - The KeyValuePair<TKey,TValue> structure representing the key and value to add to the OrderedDictionary<TKey,TValue>. - - - - Determines whether the OrderedDictionary<TKey,TValue> contains a specific key and value. - - The KeyValuePair<TKey,TValue> structure to locate in the OrderedDictionary<TKey,TValue>. - if is found in the OrderedDictionary<TKey,TValue>; otherwise, . - - - - Copies the elements of the OrderedDictionary<TKey,TValue> to an array of type , starting at the specified index. - - The one-dimensional array of type KeyValuePair<TKey,TValue> that is the destination of the KeyValuePair<TKey,TValue> elements copied from the OrderedDictionary<TKey,TValue>. The array must have zero-based indexing. - The zero-based index in at which copying begins. - - - - Removes a key and value from the dictionary. - - The KeyValuePair<TKey,TValue> structure representing the key and value to remove from the OrderedDictionary<TKey,TValue>. - if the key and value represented by is successfully found and removed; otherwise, . This method returns if is not found in the OrderedDictionary<TKey,TValue>. - - - - Gets the dictionary object that stores the keys and values - - The dictionary object that stores the keys and values for the OrderedDictionary<TKey,TValue> - Accessing this property will create the dictionary object if necessary - - - - Gets the list object that stores the key/value pairs. - - The list object that stores the key/value pairs for the OrderedDictionary<TKey,TValue> - Accessing this property will create the list object if necessary. - - - - Gets or sets the value at the specified index. - - The zero-based index of the value to get or set. - The value of the item at the specified index. - is less than 0.
- -or-
- index is equal to or greater than .
-
- - - Gets or sets the value at the specified index. - - The zero-based index of the value to get or set. - The value of the item at the specified index. - is less than 0.
- -or-
- index is equal to or greater than .
- is a null reference, and the value type of the OrderedDictionary<TKey,TValue> is a value type. - The value type of the OrderedDictionary<TKey,TValue> is not in the inheritance hierarchy of . -
- - - Gets a value indicating whether the OrderedDictionary<TKey,TValue> has a fixed size. - - if the OrderedDictionary<TKey,TValue> has a fixed size; otherwise, . The default is . - - - - Gets a value indicating whether the OrderedDictionary<TKey,TValue> collection is read-only. - - if the OrderedDictionary<TKey,TValue> is read-only; otherwise, . The default is . - - A collection that is read-only does not allow the addition, removal, or modification of elements after the collection is created. - A collection that is read-only is simply a collection with a wrapper that prevents modification of the collection; therefore, if changes are made to the underlying collection, the read-only collection reflects those changes. - - - - - Gets an object containing the keys in the OrderedDictionary<TKey,TValue>. - - An object containing the keys in the OrderedDictionary<TKey,TValue>. - The returned object is not a static copy; instead, the collection refers back to the keys in the original OrderedDictionary<TKey,TValue>. Therefore, changes to the OrderedDictionary<TKey,TValue> continue to be reflected in the key collection. - - - - Gets an object containing the values in the OrderedDictionary<TKey,TValue> collection. - - An object containing the values in the OrderedDictionary<TKey,TValue> collection. - The returned object is not a static copy; instead, the refers back to the values in the original OrderedDictionary<TKey,TValue> collection. Therefore, changes to the OrderedDictionary<TKey,TValue> continue to be reflected in the . - - - - Gets or sets the value with the specified key. - - The key of the value to get or set. - The value associated with the specified key. If the specified key is not found, attempting to get it returns , and attempting to set it creates a new element using the specified key. - - - - Gets or sets the value with the specified key. - - The key of the value to get or set. - The value associated with the specified key. If the specified key is not found, attempting to get it returns , and attempting to set it creates a new element using the specified key. - - - - Gets the number of key/values pairs contained in the OrderedDictionary<TKey,TValue> collection. - - The number of key/value pairs contained in the OrderedDictionary<TKey,TValue> collection. - - - - Gets a value indicating whether access to the OrderedDictionary<TKey,TValue> object is synchronized (thread-safe). - - This method always returns false. - - - - Gets an object that can be used to synchronize access to the OrderedDictionary<TKey,TValue> object. - - An object that can be used to synchronize access to the OrderedDictionary<TKey,TValue> object. - - - - Gets an ICollection<TKey> object containing the keys in the OrderedDictionary<TKey,TValue>. - - An ICollection<TKey> object containing the keys in the OrderedDictionary<TKey,TValue>. - The returned ICollection<TKey> object is not a static copy; instead, the collection refers back to the keys in the original OrderedDictionary<TKey,TValue>. Therefore, changes to the OrderedDictionary<TKey,TValue> continue to be reflected in the key collection. - - - - Gets an ICollection<TValue> object containing the values in the OrderedDictionary<TKey,TValue>. - - An ICollection<TValue> object containing the values in the OrderedDictionary<TKey,TValue>. - The returned ICollection<TKey> object is not a static copy; instead, the collection refers back to the values in the original OrderedDictionary<TKey,TValue>. Therefore, changes to the OrderedDictionary<TKey,TValue> continue to be reflected in the value collection. - - - - acquire distributed, non-reentrant lock on key - - global key for this lock - timeout for acquiring lock - timeout for lock, in seconds (stored as value against lock key) - - - - - - unlock key - - - - - - - - - - - - - Locking strategy interface - - - - - This class manages a read lock for a local readers/writer lock, - using the Resource Acquisition Is Initialization pattern - - - - - RAII initialization - - - - - - RAII disposal - - - - - This class manages a write lock for a local readers/writer lock, - using the Resource Acquisition Is Initialization pattern - - - - - - RAII disposal - - - - - manages a "region" in the redis key space - namespace can be cleared by incrementing the generation - - - - - get current generation - - - - - - set new generation - - - - - - redis key for generation - - - - - - get redis key that holds all namespace keys - - - - - - get global cache key - - - - - - - get global key inside of this namespace - - - prefixes can be added for name deconfliction - - - - - replace UniqueCharacter with its double, to avoid name clash - - - - - - - - - - - - - - get locking strategy - - -
-
diff --git a/lib/tests/ServiceStack.Server.dll b/lib/tests/ServiceStack.Server.dll deleted file mode 100644 index 291d39ee1..000000000 Binary files a/lib/tests/ServiceStack.Server.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Server.xml b/lib/tests/ServiceStack.Server.xml deleted file mode 100644 index f8d1a686b..000000000 --- a/lib/tests/ServiceStack.Server.xml +++ /dev/null @@ -1,345 +0,0 @@ - - - - ServiceStack.Server - - - - - Base rcon class. - - - - - Rcon connection socket. Always set to null when not connected. - - - - - Unique ID for each message. - - - - - Registered callbacks. - - - - - Create a new instance of rcon. - - Endpoint to connect to, usually the game server with query port. - - - - Attempts to connect to the game server for rcon operations. - - True if connection established, false otherwise. - - - - Processes a received packet. - - The packet. - - - - Disconnects from rcon. - - - - - Sends message to the server. - - Words to send. - - - - Disconnected event. - - - - - Game server endpoint. - - - - - Last exception that occured during operation. - - - - - Connected? - - - - - Gets the next unique ID to be used for transmisson. Read this before sending to pair responses to sent messages. - - - - - Event delegate when disconnected from the server. - - - - - - Delegate for async callbacks. - - - - - - - Exception thrown when attempting to send on a non-connected service client. - - - - - True if the packet originated on the server. - - - - - True if the packet is a response from a sent packet. - - - - - Sequence identifier. Unique to the connection. - - - - - Words. - - - - - Contains methods required for encoding and decoding rcon packets. - - - - - Decodes a packet. - - The packet. - A packet object. - - - - Decodes the packet header. - - - - - - - Decodes words in a packet. - - - - - - - Encodes a packet for transmission to the server. - - - - - - - - - - Encodes a packet header. - - - - - - - - - Encodes words. - - - - - - - Processing client used to interface with ServiceStack and allow a message to be processed. - Not an actual client. - - - - - Publish the specified message into the durable queue @queueName - - - - - Publish the specified message into the transient queue @queueName - - - - - Synchronous blocking get. - - - - - Non blocking get message - - - - - Creates a Redis MQ Server that processes each message on its own background thread. - i.e. if you register 3 handlers it will create 7 background threads: - - 1 listening to the Redis MQ Subscription, getting notified of each new message - - 3x1 Normal InQ for each message handler - - 3x1 PriorityQ for each message handler (Turn off with DisablePriorityQueues) - - When RedisMqServer Starts it creates a background thread subscribed to the Redis MQ Topic that - listens for new incoming messages. It also starts 2 background threads for each message type: - - 1 for processing the services Priority Queue and 1 processing the services normal Inbox Queue. - - Priority Queue's can be enabled on a message-per-message basis by specifying types in the - OnlyEnablePriortyQueuesForTypes property. The DisableAllPriorityQueues property disables all Queues. - - The Start/Stop methods are idempotent i.e. It's safe to call them repeatedly on multiple threads - and the Redis MQ Server will only have Started or Stopped once. - - - - - Execute global transformation or custom logic before a request is processed. - Must be thread-safe. - - - - - Execute global transformation or custom logic on the response. - Must be thread-safe. - - - - - Execute global error handler logic. Must be thread-safe. - - - - - If you only want to enable priority queue handlers (and threads) for specific msg types - - - - - Don't listen on any Priority Queues - - - - - Opt-in to only publish responses on this white list. - Publishes all responses by default. - - - - - Transient message queues are a one-pass message queue service that starts - processing messages when Start() is called. Any subsequent Start() calls - while the service is running is ignored. - - The transient service will continue to run until all messages have been - processed after which time it will shutdown all processing until Start() is called again. - - - - - Hosting services via a binary-safe TCP-based protocol. - - - - - Register DTOs and hanlders the MQ Host will process - - - - - - - Get Total Current Stats for all Message Handlers - - - - - - Get a Stats dump - - - - - - Start the MQ Host. Stops the server and restarts if already started. - - - - - Stop the MQ Host if not already stopped. - - - - - Processes a received packet. - - The packet. - - - - Factory to create consumers and producers that work with this service - - - - - Understands how to store a to a MSSQL database. - - - - - Creates needed tables. Run this once on your database. - - - Works in sql server and sqlite (with documented removals). - - - - - Returns a new . - - - - - Stores to dbo.MiniProfilers under its ; - stores all child Timings and SqlTimings to their respective tables. - - - - - Loads the MiniProfiler identifed by 'id' from the database. - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Returns a connection to Sql Server. - - - - diff --git a/lib/tests/ServiceStack.Text.dll b/lib/tests/ServiceStack.Text.dll deleted file mode 100644 index d0f63073d..000000000 Binary files a/lib/tests/ServiceStack.Text.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.Text.xml b/lib/tests/ServiceStack.Text.xml deleted file mode 100644 index 6cf831f51..000000000 --- a/lib/tests/ServiceStack.Text.xml +++ /dev/null @@ -1,714 +0,0 @@ - - - - ServiceStack.Text - - - - - Utils to load types - - - - - Find the type from the name supplied - - [typeName] or [typeName, assemblyName] - - - - - The top-most interface of the given type, if any. - - - - - Find type if it exists - - - - The type if it exists - - - - Populate an object with Example data. - - - - - - - Populates the object with example data. - - - Tracks how deeply nested we are - - - - - If AlwaysUseUtc is set to true then convert all DateTime to UTC. - - - - - - - Repairs an out-of-spec XML date/time string which incorrectly uses a space instead of a 'T' to separate the date from the time. - These string are occasionally generated by SQLite and can cause errors in OrmLite when reading these columns from the DB. - - The XML date/time string to repair - The repaired string. If no repairs were made, the original string is returned. - - - - WCF Json format: /Date(unixts+0000)/ - - - - - - - WCF Json format: /Date(unixts+0000)/ - - - - - - - Get the type(string) constructor if exists - - The type. - - - - - micro optimizations: using flags instead of value.IndexOfAny(EscapeChars) - - - - - - - Class to hold - - - - - - A fast, standards-based, serialization-issue free DateTime serailizer. - - - - - Determines whether this serializer can create the specified type from a string. - - The type. - - true if this instance [can create from string] the specified type; otherwise, false. - - - - - Parses the specified value. - - The value. - - - - - Deserializes from reader. - - The reader. - - - - - Serializes to string. - - The value. - - - - - Serializes to writer. - - The value. - The writer. - - - - Sets which format to use when serializing TimeSpans - - - - - if the is configured - to take advantage of specification, - to support user-friendly serialized formats, ie emitting camelCasing for JSON - and parsing member names and enum values in a case-insensitive manner. - - - - - if the is configured - to support web-friendly serialized formats, ie emitting lowercase_underscore_casing for JSON - - - - - Define how property names are mapped during deserialization - - - - - Gets or sets a value indicating if the framework should throw serialization exceptions - or continue regardless of deserialization errors. If the framework - will throw; otherwise, it will parse as many fields as possible. The default is . - - - - - Gets or sets a value indicating if the framework should always convert to UTC format instead of local time. - - - - - Gets or sets a value indicating if the framework should always assume is in UTC format if Kind is Unspecified. - - - - - Gets or sets whether we should append the Utc offset when we serialize Utc dates. Defaults to no. - Only supported for when the JsConfig.DateHandler == JsonDateHandler.TimestampOffset - - - - - Gets or sets a value indicating if unicode symbols should be serialized as "\uXXXX". - - - - - If set to true, Interface types will be prefered over concrete types when serializing. - - - - - For extra serialization performance you can re-use a ThreadStatic StringBuilder - when serializing to a JSON String. - - - - - Sets the maximum depth to avoid circular dependencies - - - - - Set this to enable your own type construction provider. - This is helpful for integration with IoC containers where you need to call the container constructor. - Return null if you don't know how to construct the type and the parameterless constructor will be used. - - - - - If set to true, Interface types will be prefered over concrete types when serializing. - - - - - Always emit type info for this type. Takes precedence over ExcludeTypeInfo - - - - - Never emit type info for this type - - - - - if the is configured - to take advantage of specification, - to support user-friendly serialized formats, ie emitting camelCasing for JSON - and parsing member names and enum values in a case-insensitive manner. - - - - - Define custom serialization fn for BCL Structs - - - - - Define custom raw serialization fn - - - - - Define custom serialization hook - - - - - Define custom after serialization hook - - - - - Define custom deserialization fn for BCL Structs - - - - - Define custom raw deserialization fn for objects - - - - - Exclude specific properties of this type from being serialized - - - - - Opt-in flag to set some Value Types to be treated as a Ref Type - - - - - Whether there is a fn (raw or otherwise) - - - - - The property names on target types must match property names in the JSON source - - - - - The property names on target types may not match the property names in the JSON source - - - - - Uses the xsd format like PT15H10M20S - - - - - Uses the standard .net ToString method of the TimeSpan class - - - - - Get JSON string value converted to T - - - - - Get JSON string value - - - - - Get unescaped string value - - - - - Get unescaped string value - - - - - Write JSON Array, Object, bool or number values as raw string - - - - - Get JSON string value - - - - - Creates an instance of a Type from a string value - - - - - Parses the specified value. - - The value. - - - - - Shortcut escape when we're sure value doesn't contain any escaped chars - - - - - - - Given a character as utf32, returns the equivalent string provided that the character - is legal json. - - - - - - - micro optimizations: using flags instead of value.IndexOfAny(EscapeChars) - - - - - - - Implement the serializer using a more static approach - - - - - - Implement the serializer using a more static approach - - - - - - Public Code API to register commercial license for ServiceStack. - - - - - Internal Utilities to verify licensing - - - - - Pretty Thread-Safe cache class from: - http://code.google.com/p/dapper-dot-net/source/browse/Dapper/SqlMapper.cs - - This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - equality. The type is fully thread-safe. - - - - - Represents an individual object, allowing access to members by-name - - - - - Use the target types definition of equality - - - - - Obtain the hash of the target object - - - - - Use the target's definition of a string representation - - - - - Wraps an individual object, allowing by-name access to that instance - - - - - Get or Set the value of a named member for the underlying object - - - - - The object represented by this instance - - - - - Provides by-name member-access to objects of a given type - - - - - Create a new instance of this type - - - - - Provides a type-specific accessor, allowing by-name access for all objects of that type - - The accessor is cached internally; a pre-existing accessor may be returned - - - - Does this type support new instances via a parameterless constructor? - - - - - Get or set the value of a named member on the target instance - - - - - Maps the path of a file in the context of a VS project - - the relative path - the absolute path - Assumes static content is two directories above the /bin/ directory, - eg. in a unit test scenario the assembly would be in /bin/Debug/. - - - - Maps the path of a file in a self-hosted scenario - - the relative path - the absolute path - Assumes static content is copied to /bin/ folder with the assemblies - - - - Maps the path of a file in an Asp.Net hosted scenario - - the relative path - the absolute path - Assumes static content is in the parent folder of the /bin/ directory - - - - Implement the serializer using a more static approach - - - - - - Creates a new instance of type. - First looks at JsConfig.ModelFactory before falling back to CreateInstance - - - - - Creates a new instance of type. - First looks at JsConfig.ModelFactory before falling back to CreateInstance - - - - - Creates a new instance from the default constructor of type - - - - - Add a Property attribute at runtime. - Not threadsafe, should only add attributes on Startup. - - - - - Add a Property attribute at runtime. - Not threadsafe, should only add attributes on Startup. - - - - - @jonskeet: Collection of utility methods which operate on streams. - r285, February 26th 2009: http://www.yoda.arachsys.com/csharp/miscutil/ - - - - - Reads the given stream up to the end, returning the data as a byte - array. - - - - - Reads the given stream up to the end, returning the data as a byte - array, using the given buffer size. - - - - - Reads the given stream up to the end, returning the data as a byte - array, using the given buffer for transferring data. Note that the - current contents of the buffer is ignored, so the buffer needn't - be cleared beforehand. - - - - - Copies all the data from one stream into another. - - - - - Copies all the data from one stream into another, using a buffer - of the given size. - - - - - Copies all the data from one stream into another, using the given - buffer for transferring data. Note that the current contents of - the buffer is ignored, so the buffer needn't be cleared beforehand. - - - - - Reads exactly the given number of bytes from the specified stream. - If the end of the stream is reached before the specified amount - of data is read, an exception is thrown. - - - - - Reads into a buffer, filling it completely. - - - - - Reads exactly the given number of bytes from the specified stream, - into the given buffer, starting at position 0 of the array. - - - - - Reads exactly the given number of bytes from the specified stream, - into the given buffer, starting at position 0 of the array. - - - - - Same as ReadExactly, but without the argument checks. - - - - - Converts from base: 0 - 62 - - The source. - From. - To. - - - - - Skip the encoding process for 'safe strings' - - - - - - - A class to allow the conversion of doubles to string representations of - their exact decimal values. The implementation aims for readability over - efficiency. - - Courtesy of @JonSkeet - http://www.yoda.arachsys.com/csharp/DoubleConverter.cs - - - - - - - - How many digits are *after* the decimal point - - - - - Constructs an arbitrary decimal expansion from the given long. - The long must not be negative. - - - - - Multiplies the current expansion by the given amount, which should - only be 2 or 5. - - - - - Shifts the decimal point; a negative value makes - the decimal expansion bigger (as fewer digits come after the - decimal place) and a positive value makes the decimal - expansion smaller. - - - - - Removes leading/trailing zeroes from the expansion. - - - - - Converts the value to a proper decimal string representation. - - - - - Creates an instance of a Type from a string value - - - - - Determines whether the specified type is convertible from string. - - The type. - - true if the specified type is convertible from string; otherwise, false. - - - - - Parses the specified value. - - The value. - - - - - Parses the specified type. - - The type. - The value. - - - - - Useful extension method to get the Dictionary[string,string] representation of any POCO type. - - - - - - Recursively prints the contents of any POCO object in a human-friendly, readable format - - - - - - Print Dump to Console.WriteLine - - - - - Print string.Format to Console.WriteLine - - - - - Parses the specified value. - - The value. - - - - diff --git a/lib/tests/ServiceStack.dll b/lib/tests/ServiceStack.dll deleted file mode 100644 index 9c9c52284..000000000 Binary files a/lib/tests/ServiceStack.dll and /dev/null differ diff --git a/lib/tests/ServiceStack.xml b/lib/tests/ServiceStack.xml deleted file mode 100644 index db778e00a..000000000 --- a/lib/tests/ServiceStack.xml +++ /dev/null @@ -1,8267 +0,0 @@ - - - - ServiceStack - - - - - Base class to create request filter attributes only for specific HTTP methods (GET, POST...) - - - - - Creates a new - - Defines when the filter should be executed - - - - This method is only executed if the HTTP method matches the property. - - The http request wrapper - The http response wrapper - The request DTO - - - - Create a ShallowCopy of this instance. - - - - - - Inherit from this class if you want to host your web services inside a - Console Application, Windows Service, etc. - - Usage of HttpListener allows you to host webservices on the same port (:80) as IIS - however it requires admin user privillages. - - - - - Wrapper class for the HTTPListener to allow easier access to the - server, for start and stop management and event routing of the actual - inbound requests. - - - - - ASP.NET or HttpListener ServiceStack host - - - - - Register dependency in AppHost IOC on Startup - - - - - AutoWired Registration of an interface with a concrete type in AppHost IOC on Startup. - - - - - Allows the clean up for executed autowired services and filters. - Calls directly after services and filters are executed. - - - - - Called at the end of each request. Enables Request Scope. - - - - - Register an Adhoc web service on Startup - - - - - Apply plugins to this AppHost - - - - - Create a service runner for IService actions - - - - - Resolve the absolute url for this request - - - - - Resolve localized text, returns itself by default. - The Request is provided when exists. - - - - - Register user-defined custom routes. - - - - - Inferred Metadata available from existing services - - - - - Register custom ContentType serializers - - - - - Add Request Filters, to be applied before the dto is deserialized - - - - - Add Request Filters for HTTP Requests - - - - - Add Response Filters for HTTP Responses - - - - - Add Request Filters for MQ/TCP Requests - - - - - Add Response Filters for MQ/TCP Responses - - - - - Add alternative HTML View Engines - - - - - Provide an exception handler for unhandled exceptions - - - - - Provide an exception handler for un-caught exceptions - - - - - Provide callbacks to be fired after the AppHost has finished initializing - - - - - Provide callbacks to be fired when AppHost is being disposed - - - - - Skip the ServiceStack Request Pipeline and process the returned IHttpHandler instead - - - - - Provide a catch-all handler that doesn't match any routes - - - - - Use a fall-back Error Handler for handling global errors - - - - - Use a Custom Error Handler for handling specific error HttpStatusCodes - - - - - Provide a custom model minder for a specific Request DTO - - - - - The AppHost config - - - - - The AppHost AppSettings. Defaults to App or Web.config appSettings. - - - - - List of pre-registered and user-defined plugins to be enabled in this AppHost - - - - - Virtual access to file resources - - - - - Funqlets are a set of components provided as a package - to an existing container (like a module). - - - - - Configure the given container with the - registrations provided by the funqlet. - - Container to register. - - - - Retain the same behavior as ASP.NET and redirect requests to directores - without a trailing '/' - - - - - Executed immediately before a Service is executed. Use return to change the request DTO used, must be of the same type. - - - - - Executed immediately after a service is executed. Use return to change response used. - - - - - Occurs when the Service throws an Exception. - - - - - Occurs when an exception is thrown whilst processing a request. - - - - - Apply PreRequest Filters for participating Custom Handlers, e.g. RazorFormat, MarkdownFormat, etc - - - - - Applies the raw request filters. Returns whether or not the request has been handled - and no more processing should be done. - - - - - - Applies the request filters. Returns whether or not the request has been handled - and no more processing should be done. - - - - - - Applies the response filters. Returns whether or not the request has been handled - and no more processing should be done. - - - - - - The AppHost.Container. Note: it is not thread safe to register dependencies after AppStart. - - - - - Starts the Web Service - - - A Uri that acts as the base that the server is listening on. - Format should be: http://127.0.0.1:8080/ or http://127.0.0.1:8080/somevirtual/ - Note: the trailing slash is required! For more info see the - HttpListener.Prefixes property on MSDN. - - - - - Shut down the Web Service - - - - - Overridable method that can be used to implement a custom hnandler - - - - - - Reserves the specified URL for non-administrator users and accounts. - http://msdn.microsoft.com/en-us/library/windows/desktop/cc307223(v=vs.85).aspx - - Reserved Url if the process completes successfully - - - - Default redirct URL if [Authenticate] attribute doesn't permit access. - - - - - Default redirct URL if Required Role or Permission attributes doesn't permit access. - - - - - Provides a common interface for Settings providers such as - ConfigurationManager or Azure's RoleEnvironment. The only - requirement is that if the implementation cannot find the - specified key, the return value must be null - - The key for the setting - The string value of the specified key, or null if the key - was invalid - - - - Return all keys in this configuration source. - - - - - - Typed UserSession - - - - - Dynamic Session Bag - - - - - Remove the Users Session - - - - - - - - The entry point for all AuthProvider providers. Runs inside the AuthService so exceptions are treated normally. - Overridable so you can provide your own Auth implementation. - - - - - Determine if the current session is already authenticated with this AuthProvider - - - - - Allows specifying a global fallback config that if exists is formatted with the Provider as the first arg. - E.g. this appSetting with the TwitterAuthProvider: - oauth.CallbackUrl="http://localhost:11001/auth/{0}" - Would result in: - oauth.CallbackUrl="http://localhost:11001/auth/twitter" - - - - - - Remove the Users Session - - - - - - - - Saves the Auth Tokens for this request. Called in OnAuthenticated(). - Overrideable, the default behaviour is to call IUserAuthRepository.CreateOrMergeAuthSession(). - - - - - Specify all roles to be used by this application - - - - - Only allow access to users in specified roles - - - - - Conveneint base class with empty virtual methods so subclasses only need to override the hooks they need. - - - - - Create Odnoklassniki App at: http://www.odnoklassniki.ru/devaccess - The Callback URL for your app should match the CallbackUrl provided. - - NB: They claim they use OAuth 2.0, but they in fact don't. - http://apiok.ru/wiki/display/api/Authorization+OAuth+2.0 - - - - - The entry point for all AuthProvider providers. Runs inside the AuthService so exceptions are treated normally. - Overridable so you can provide your own Auth implementation. - - - - - - - - - Sets the CallbackUrl and session.ReferrerUrl if not set and initializes the session tokens for this AuthProvider - - - - - - - - - Create VK App at: http://vk.com/editapp?act=create - The Callback URL for your app should match the CallbackUrl provided. - - - - - If previous attemts failes, the subsequential calls - build up code value like "code1,code2,code3" - so we need the last one only - - - - - - - Create Yandex App at: https://oauth.yandex.ru/client/new - The Callback URL for your app should match the CallbackUrl provided. - - - - - Create an App at: https://github.com/settings/applications/new - The Callback URL for your app should match the CallbackUrl provided. - - - - - Calling to Github API without defined Useragent throws - exception "The server committed a protocol violation. Section=ResponseStatusLine" - - - - - Creates the required missing tables or DB schema - - - - - Generic + Useful IService base class - - - - - Resolve an alternate Web Service from ServiceStack's IOC container. - - - - - - - Dynamic Session Bag - - - - - Typed UserSession - - - - - Redirect to the https:// version of this url if not already. - - - - - Don't redirect when in DebugMode - - - - - Don't redirect if the request was a forwarded request, e.g. from a Load Balancer - - - - - Encapsulates creating a new message handler - - - - - Processes all messages in a Normal and Priority Queue. - Expects to be called in 1 thread. i.e. Non Thread-Safe. - - - - - - A convenient repository base class you can inherit from to reduce the boilerplate - with accessing a managed IDbConnection - - - - - A convenient base class for your injected service dependencies that reduces the boilerplate - with managed access to ServiceStack's built-in providers - - - - - Only generate specified Verb entries for "ANY" routes - - - - - Tell ServiceStack to use ThreadStatic Items Collection for RequestScoped items. - Warning: ThreadStatic Items aren't pinned to the same request in async services which callback on different threads. - - - - - Track any IDisposable's to dispose of at the end of the request in IAppHost.OnEndRequest() - - - - - - Gets a list of items for this request. - - This list will be cleared on every request and is specific to the original thread that is handling the request. - If a handler uses additional threads, this data will not be available on those threads. - - - - - This class stores the caller call context in order to restore - it when the work item is executed in the thread pool environment. - - - - - Constructor - - - - - Captures the current thread context - - - - - - Applies the thread context stored earlier - - - - - - EventWaitHandleFactory class. - This is a static class that creates AutoResetEvent and ManualResetEvent objects. - In WindowCE the WaitForMultipleObjects API fails to use the Handle property - of XxxResetEvent. It can use only handles that were created by the CreateEvent API. - Consequently this class creates the needed XxxResetEvent and replaces the handle if - it's a WindowsCE OS. - - - - - Create a new AutoResetEvent object - - Return a new AutoResetEvent object - - - - Create a new ManualResetEvent object - - Return a new ManualResetEvent object - - - - Represents an exception in case IWorkItemResult.GetResult has been canceled - - - Represents an exception in case IWorkItemResult.GetResult has been canceled - - - - - Represents an exception in case IWorkItemResult.GetResult has been timed out - - - Represents an exception in case IWorkItemResult.GetResult has been timed out - - - - - Represents an exception in case IWorkItemResult.GetResult has been timed out - - - Represents an exception in case IWorkItemResult.GetResult has been timed out - - - - - A delegate that represents the method to run as the work item - - A state object for the method to run - - - - A delegate to call after the WorkItemCallback completed - - The work item result object - - - - A delegate to call after the WorkItemCallback completed - - The work item result object - - - - A delegate to call when a WorkItemsGroup becomes idle - - A reference to the WorkItemsGroup that became idle - - - - A delegate to call after a thread is created, but before - it's first use. - - - - - A delegate to call when a thread is about to exit, after - it is no longer belong to the pool. - - - - - Defines the availeable priorities of a work item. - The higher the priority a work item has, the sooner - it will be executed. - - - - - IWorkItemsGroup interface - Created by SmartThreadPool.CreateWorkItemsGroup() - - - - - Get an array with all the state objects of the currently running items. - The array represents a snap shot and impact performance. - - - - - Starts to execute work items - - - - - Cancel all the work items. - Same as Cancel(false) - - - - - Cancel all work items using thread abortion - - True to stop work items by raising ThreadAbortException - - - - Wait for all work item to complete. - - - - - Wait for all work item to complete, until timeout expired - - How long to wait for the work items to complete - Returns true if work items completed within the timeout, otherwise false. - - - - Wait for all work item to complete, until timeout expired - - How long to wait for the work items to complete in milliseconds - Returns true if work items completed within the timeout, otherwise false. - - - - Queue a work item - - A callback to execute - Returns a work item result - - - - Queue a work item - - A callback to execute - The priority of the work item - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - The work item priority - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - The work item priority - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Indicates on which cases to call to the post execute callback - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Indicates on which cases to call to the post execute callback - The work item priority - Returns a work item result - - - - Queue a work item - - Work item info - A callback to execute - Returns a work item result - - - - Queue a work item - - Work item information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - Returns a work item result - - - - Queue a work item. - - Returns a IWorkItemResult object, but its GetResult() will always return null - - - - Queue a work item. - - Returns a IWorkItemResult object, but its GetResult() will always return null - - - - Queue a work item. - - Returns a IWorkItemResult object, but its GetResult() will always return null - - - - Queue a work item. - - Returns a IWorkItemResult object, but its GetResult() will always return null - - - - Queue a work item. - - Returns a IWorkItemResult object, but its GetResult() will always return null - - - - Queue a work item. - - Returns a IWorkItemResult<TResult> object. - its GetResult() returns a TResult object - - - - Queue a work item. - - Returns a IWorkItemResult<TResult> object. - its GetResult() returns a TResult object - - - - Queue a work item. - - Returns a IWorkItemResult<TResult> object. - its GetResult() returns a TResult object - - - - Queue a work item. - - Returns a IWorkItemResult<TResult> object. - its GetResult() returns a TResult object - - - - Queue a work item. - - Returns a IWorkItemResult<TResult> object. - its GetResult() returns a TResult object - - - - Get/Set the name of the WorkItemsGroup - - - - - Get/Set the maximum number of workitem that execute cocurrency on the thread pool - - - - - Get the number of work items waiting in the queue. - - - - - Get the WorkItemsGroup start information - - - - - IsIdle is true when there are no work items running or queued. - - - - - This event is fired when all work items are completed. - (When IsIdle changes to true) - This event only work on WorkItemsGroup. On SmartThreadPool - it throws the NotImplementedException. - - - - - Never call to the PostExecute call back - - - - - Call to the PostExecute only when the work item is cancelled - - - - - Call to the PostExecute only when the work item is not cancelled - - - - - Always call to the PostExecute - - - - - The common interface of IWorkItemResult and IWorkItemResult<T> - - - - - This method intent is for internal use. - - - - - - This method intent is for internal use. - - - - - - IWorkItemResult interface. - Created when a WorkItemCallback work item is queued. - - - - - IWorkItemResult<TResult> interface. - Created when a Func<TResult> work item is queued. - - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits. - - The result of the work item - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout. - - The result of the work item - On timeout throws WorkItemTimeoutException - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout. - - The result of the work item - On timeout throws WorkItemTimeoutException - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. - - Timeout in milliseconds, or -1 for infinite - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the blocking if needed - The result of the work item - On timeout throws WorkItemTimeoutException - On cancel throws WorkItemCancelException - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. - - The result of the work item - On timeout throws WorkItemTimeoutException - On cancel throws WorkItemCancelException - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits. - - Filled with the exception if one was thrown - The result of the work item - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout. - - - - Filled with the exception if one was thrown - The result of the work item - On timeout throws WorkItemTimeoutException - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout. - - - Filled with the exception if one was thrown - - The result of the work item - On timeout throws WorkItemTimeoutException - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. - - Timeout in milliseconds, or -1 for infinite - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the blocking if needed - Filled with the exception if one was thrown - The result of the work item - On timeout throws WorkItemTimeoutException - On cancel throws WorkItemCancelException - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled. - - The result of the work item - - Filled with the exception if one was thrown - - - On timeout throws WorkItemTimeoutException - On cancel throws WorkItemCancelException - - - - Same as Cancel(false). - - - - - Cancel the work item execution. - If the work item is in the queue then it won't execute - If the work item is completed, it will remain completed - If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled - property to check if the work item has been cancelled. If the abortExecution is set to true then - the Smart Thread Pool will send an AbortException to the running thread to stop the execution - of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException. - If the work item is already cancelled it will remain cancelled - - When true send an AbortException to the executing thread. - Returns true if the work item was not completed, otherwise false. - - - - Gets an indication whether the asynchronous operation has completed. - - - - - Gets an indication whether the asynchronous operation has been canceled. - - - - - Gets the user-defined object that contains context data - for the work item method. - - - - - Get the work item's priority - - - - - Return the result, same as GetResult() - - - - - Returns the exception if occured otherwise returns null. - - - - - An internal delegate to call when the WorkItem starts or completes - - - - - This method is intent for internal use. - - - - - PriorityQueue class - This class is not thread safe because we use external lock - - - - - The number of queues, there is one for each type of priority - - - - - Work items queues. There is one for each type of priority - - - - - The total number of work items within the queues - - - - - Use with IEnumerable interface - - - - - Enqueue a work item. - - A work item - - - - Dequeque a work item. - - Returns the next work item - - - - Find the next non empty queue starting at queue queueIndex+1 - - The index-1 to start from - - The index of the next non empty queue or -1 if all the queues are empty - - - - - Clear all the work items - - - - - Returns an enumerator to iterate over the work items - - Returns an enumerator - - - - The number of work items - - - - - The class the implements the enumerator - - - - - Smart thread pool class. - - - - - Contains the name of this instance of SmartThreadPool. - Can be changed by the user. - - - - - Cancel all the work items. - Same as Cancel(false) - - - - - Wait for the SmartThreadPool/WorkItemsGroup to be idle - - - - - Wait for the SmartThreadPool/WorkItemsGroup to be idle - - - - - Queue a work item - - A callback to execute - Returns a work item result - - - - Queue a work item - - A callback to execute - The priority of the work item - Returns a work item result - - - - Queue a work item - - Work item info - A callback to execute - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - The work item priority - Returns a work item result - - - - Queue a work item - - Work item information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - The work item priority - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Indicates on which cases to call to the post execute callback - Returns a work item result - - - - Queue a work item - - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Indicates on which cases to call to the post execute callback - The work item priority - Returns a work item result - - - - Get/Set the name of the SmartThreadPool/WorkItemsGroup instance - - - - - IsIdle is true when there are no work items running or queued. - - - - - Default minimum number of threads the thread pool contains. (0) - - - - - Default maximum number of threads the thread pool contains. (25) - - - - - Default idle timeout in milliseconds. (One minute) - - - - - Indicate to copy the security context of the caller and then use it in the call. (false) - - - - - Indicate to copy the HTTP context of the caller and then use it in the call. (false) - - - - - Indicate to dispose of the state objects if they support the IDispose interface. (false) - - - - - The default option to run the post execute (CallToPostExecute.Always) - - - - - The default work item priority (WorkItemPriority.Normal) - - - - - The default is to work on work items as soon as they arrive - and not to wait for the start. (false) - - - - - The default thread priority (ThreadPriority.Normal) - - - - - The default thread pool name. (SmartThreadPool) - - - - - The default fill state with params. (false) - It is relevant only to QueueWorkItem of Action<...>/Func<...> - - - - - The default thread backgroundness. (true) - - - - - The default apartment state of a thread in the thread pool. - The default is ApartmentState.Unknown which means the STP will not - set the apartment of the thread. It will use the .NET default. - - - - - The default post execute method to run. (None) - When null it means not to call it. - - - - - The default name to use for the performance counters instance. (null) - - - - - The default Max Stack Size. (SmartThreadPool) - - - - - Dictionary of all the threads in the thread pool. - - - - - Queue of work items. - - - - - Count the work items handled. - Used by the performance counter. - - - - - Number of threads that currently work (not idle). - - - - - Stores a copy of the original STPStartInfo. - It is used to change the MinThread and MaxThreads - - - - - Total number of work items that are stored in the work items queue - plus the work items that the threads in the pool are working on. - - - - - Signaled when the thread pool is idle, i.e. no thread is busy - and the work items queue is empty - - - - - An event to signal all the threads to quit immediately. - - - - - A flag to indicate if the Smart Thread Pool is now suspended. - - - - - A flag to indicate the threads to quit. - - - - - Counts the threads created in the pool. - It is used to name the threads. - - - - - Indicate that the SmartThreadPool has been disposed - - - - - Holds all the WorkItemsGroup instaces that have at least one - work item int the SmartThreadPool - This variable is used in case of Shutdown - - - - - A common object for all the work items int the STP - so we can mark them to cancel in O(1) - - - - - Windows STP performance counters - - - - - Local STP performance counters - - - - - Constructor - - - - - Constructor - - Idle timeout in milliseconds - - - - Constructor - - Idle timeout in milliseconds - Upper limit of threads in the pool - - - - Constructor - - Idle timeout in milliseconds - Upper limit of threads in the pool - Lower limit of threads in the pool - - - - Constructor - - A SmartThreadPool configuration that overrides the default behavior - - - - Waits on the queue for a work item, shutdown, or timeout. - - - Returns the WaitingCallback or null in case of timeout or shutdown. - - - - - Put a new work item in the queue - - A work item to queue - - - - Inform that the current thread is about to quit or quiting. - The same thread may call this method more than once. - - - - - Starts new threads - - The number of threads to start - - - - A worker thread method that processes work items from the work items queue. - - - - - Force the SmartThreadPool to shutdown - - - - - Force the SmartThreadPool to shutdown with timeout - - - - - Empties the queue of work items and abort the threads in the pool. - - - - - Wait for all work items to complete - - Array of work item result objects - - true when every work item in workItemResults has completed; otherwise false. - - - - - Wait for all work items to complete - - Array of work item result objects - The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - - true when every work item in workItemResults has completed; otherwise false. - - - - - Wait for all work items to complete - - Array of work item result objects - The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the wait if needed - - true when every work item in workItemResults has completed; otherwise false. - - - - - Wait for all work items to complete - - Array of work item result objects - The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - - true when every work item in workItemResults has completed; otherwise false. - - - - - Wait for all work items to complete - - Array of work item result objects - The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the wait if needed - - true when every work item in workItemResults has completed; otherwise false. - - - - - Waits for any of the work items in the specified array to complete, cancel, or timeout - - Array of work item result objects - - The array index of the work item result that satisfied the wait, or WaitTimeout if any of the work items has been canceled. - - - - - Waits for any of the work items in the specified array to complete, cancel, or timeout - - Array of work item result objects - The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - - The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. - - - - - Waits for any of the work items in the specified array to complete, cancel, or timeout - - Array of work item result objects - The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the wait if needed - - The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. - - - - - Waits for any of the work items in the specified array to complete, cancel, or timeout - - Array of work item result objects - The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - - The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. - - - - - Waits for any of the work items in the specified array to complete, cancel, or timeout - - Array of work item result objects - The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the wait if needed - - The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. - - - - - Creates a new WorkItemsGroup. - - The number of work items that can be run concurrently - A reference to the WorkItemsGroup - - - - Creates a new WorkItemsGroup. - - The number of work items that can be run concurrently - A WorkItemsGroup configuration that overrides the default behavior - A reference to the WorkItemsGroup - - - - Checks if the work item has been cancelled, and if yes then abort the thread. - Can be used with Cancel and timeout - - - - - Get an array with all the state objects of the currently running items. - The array represents a snap shot and impact performance. - - - - - Start the thread pool if it was started suspended. - If it is already running, this method is ignored. - - - - - Cancel all work items using thread abortion - - True to stop work items by raising ThreadAbortException - - - - Wait for the thread pool to be idle - - - - - Executes all actions in parallel. - Returns when they all finish. - - Actions to execute - - - - Executes all actions in parallel. - Returns when they all finish. - - Actions to execute - - - - Executes all actions in parallel - Returns when the first one completes - - Actions to execute - - - - Executes all actions in parallel - Returns when the first one completes - - Actions to execute - - - - Executes actions in sequence asynchronously. - Returns immediately. - - A state context that passes - Actions to execute in the order they should run - - - - Executes actions in sequence asynchronously. - Returns immediately. - - - Actions to execute in the order they should run - - - - An event to call after a thread is created, but before - it's first use. - - - - - An event to call when a thread is about to exit, after - it is no longer belong to the pool. - - - - - A reference to the current work item a thread from the thread pool - is executing. - - - - - This event is fired when a thread is created. - Use it to initialize a thread before the work items use it. - - - - - This event is fired when a thread is terminating. - Use it for cleanup. - - - - - Get/Set the lower limit of threads in the pool. - - - - - Get/Set the upper limit of threads in the pool. - - - - - Get the number of threads in the thread pool. - Should be between the lower and the upper limits. - - - - - Get the number of busy (not idle) threads in the thread pool. - - - - - Returns true if the current running work item has been cancelled. - Must be used within the work item's callback method. - The work item should sample this value in order to know if it - needs to quit before its completion. - - - - - Thread Pool start information (readonly) - - - - - Return the local calculated performance counters - Available only if STPStartInfo.EnableLocalPerformanceCounters is true. - - - - - Get/Set the maximum number of work items that execute cocurrency on the thread pool - - - - - Get the number of work items in the queue. - - - - - WorkItemsGroup start information (readonly) - - - - - This event is fired when all work items are completed. - (When IsIdle changes to true) - This event only work on WorkItemsGroup. On SmartThreadPool - it throws the NotImplementedException. - - - - - The thread creation time - The value is stored as UTC value. - - - - - The last time this thread has been running - It is updated by IAmAlive() method - The value is stored as UTC value. - - - - - A reference from each thread in the thread pool to its SmartThreadPool - object container. - With this variable a thread can know whatever it belongs to a - SmartThreadPool. - - - - - A reference to the current work item a thread from the thread pool - is executing. - - - - - Summary description for STPPerformanceCounter. - - - - - Summary description for STPStartInfo. - - - - - Summary description for WIGStartInfo. - - - - - Get a readonly version of this WIGStartInfo - - Returns a readonly reference to this WIGStartInfoRO - - - - Get/Set if to use the caller's security context - - - - - Get/Set if to use the caller's HTTP context - - - - - Get/Set if to dispose of the state object of a work item - - - - - Get/Set the run the post execute options - - - - - Get/Set the default post execute callback - - - - - Get/Set if the work items execution should be suspended until the Start() - method is called. - - - - - Get/Set the default priority that a work item gets when it is enqueued - - - - - Get/Set the if QueueWorkItem of Action<...>/Func<...> fill the - arguments as an object array into the state of the work item. - The arguments can be access later by IWorkItemResult.State. - - - - - Get a readonly version of this STPStartInfo. - - Returns a readonly reference to this STPStartInfo - - - - Get/Set the idle timeout in milliseconds. - If a thread is idle (starved) longer than IdleTimeout then it may quit. - - - - - Get/Set the lower limit of threads in the pool. - - - - - Get/Set the upper limit of threads in the pool. - - - - - Get/Set the scheduling priority of the threads in the pool. - The Os handles the scheduling. - - - - - Get/Set the thread pool name. Threads will get names depending on this. - - - - - Get/Set the performance counter instance name of this SmartThreadPool - The default is null which indicate not to use performance counters at all. - - - - - Enable/Disable the local performance counter. - This enables the user to get some performance information about the SmartThreadPool - without using Windows performance counters. (Useful on WindowsCE, Silverlight, etc.) - The default is false. - - - - - Get/Set backgroundness of thread in thread pool. - - - - - Get/Set the apartment state of threads in the thread pool - - - - - Get/Set the max stack size of threads in the thread pool - - - - - Holds a callback delegate and the state for that delegate. - - - - - Callback delegate for the callback. - - - - - State with which to call the callback delegate. - - - - - Stores the caller's context - - - - - Holds the result of the mehtod - - - - - Hold the exception if the method threw it - - - - - Hold the state of the work item - - - - - A ManualResetEvent to indicate that the result is ready - - - - - A reference count to the _workItemCompleted. - When it reaches to zero _workItemCompleted is Closed - - - - - Represents the result state of the work item - - - - - Work item info - - - - - A reference to an object that indicates whatever the - WorkItemsGroup has been canceled - - - - - A reference to an object that indicates whatever the - SmartThreadPool has been canceled - - - - - The work item group this work item belong to. - - - - - The thread that executes this workitem. - This field is available for the period when the work item is executed, before and after it is null. - - - - - The absulote time when the work item will be timeout - - - - - Stores how long the work item waited on the stp queue - - - - - Stores how much time it took the work item to execute after it went out of the queue - - - - - Initialize the callback holding object. - - The workItemGroup of the workitem - The WorkItemInfo of te workitem - Callback delegate for the callback. - State with which to call the callback delegate. - - We assume that the WorkItem object is created within the thread - that meant to run the callback - - - - Change the state of the work item to in progress if it wasn't canceled. - - - Return true on success or false in case the work item was canceled. - If the work item needs to run a post execute then the method will return true. - - - - - Execute the work item and the post execute - - - - - Execute the work item - - - - - Runs the post execute callback - - - - - Set the result of the work item to return - - The result of the work item - The exception that was throw while the workitem executed, null - if there was no exception. - - - - Returns the work item result - - The work item result - - - - Wait for all work items to complete - - Array of work item result objects - The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the wait if needed - - true when every work item in waitableResults has completed; otherwise false. - - - - - Waits for any of the work items in the specified array to complete, cancel, or timeout - - Array of work item result objects - The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely. - - true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false. - - A cancel wait handle to interrupt the wait if needed - - The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled. - - - - - Fill an array of wait handles with the work items wait handles. - - An array of work item results - An array of wait handles to fill - - - - Release the work items' wait handles - - An array of work item results - - - - Sets the work item's state - - The state to set the work item to - - - - Signals that work item has been completed or canceled - - Indicates that the work item has been canceled - - - - Cancel the work item if it didn't start running yet. - - Returns true on success or false if the work item is in progress or already completed - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits for the result, timeout, or cancel. - In case of error the method throws and exception - - The result of the work item - - - - Get the result of the work item. - If the work item didn't run yet then the caller waits for the result, timeout, or cancel. - In case of error the e argument is filled with the exception - - The result of the work item - - - - A wait handle to wait for completion, cancel, or timeout - - - - - Called when the WorkItem starts - - - - - Called when the WorkItem completes - - - - - Returns true when the work item has completed or canceled - - - - - Returns true when the work item has canceled - - - - - Returns the priority of the work item - - - - - Indicates the state of the work item in the thread pool - - - - - A back reference to the work item - - - - - Return the result, same as GetResult() - - - - - Returns the exception if occured otherwise returns null. - This value is valid only after the work item completed, - before that it is always null. - - - - - Create a new work item - - The WorkItemsGroup of this workitem - Work item group start information - A callback to execute - Returns a work item - - - - Create a new work item - - The WorkItemsGroup of this workitem - Work item group start information - A callback to execute - The priority of the work item - Returns a work item - - - - Create a new work item - - The WorkItemsGroup of this workitem - Work item group start information - Work item info - A callback to execute - Returns a work item - - - - Create a new work item - - The WorkItemsGroup of this workitem - Work item group start information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - Returns a work item - - - - Create a new work item - - The work items group - Work item group start information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - The work item priority - Returns a work item - - - - Create a new work item - - The work items group - Work item group start information - Work item information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - Returns a work item - - - - Create a new work item - - The work items group - Work item group start information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Returns a work item - - - - Create a new work item - - The work items group - Work item group start information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - The work item priority - Returns a work item - - - - Create a new work item - - The work items group - Work item group start information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Indicates on which cases to call to the post execute callback - Returns a work item - - - - Create a new work item - - The work items group - Work item group start information - A callback to execute - - The context object of the work item. Used for passing arguments to the work item. - - - A delegate to call after the callback completion - - Indicates on which cases to call to the post execute callback - The work item priority - Returns a work item - - - - Summary description for WorkItemInfo. - - - - - Get/Set if to use the caller's security context - - - - - Get/Set if to use the caller's HTTP context - - - - - Get/Set if to dispose of the state object of a work item - - - - - Get/Set the run the post execute options - - - - - Get/Set the post execute callback - - - - - Get/Set the work item's priority - - - - - Get/Set the work item's timout in milliseconds. - This is a passive timout. When the timout expires the work item won't be actively aborted! - - - - - Summary description for WorkItemsGroup. - - - - - A reference to the SmartThreadPool instance that created this - WorkItemsGroup. - - - - - A flag to indicate if the Work Items Group is now suspended. - - - - - Defines how many work items of this WorkItemsGroup can run at once. - - - - - Priority queue to hold work items before they are passed - to the SmartThreadPool. - - - - - Indicate how many work items are waiting in the SmartThreadPool - queue. - This value is used to apply the concurrency. - - - - - Indicate how many work items are currently running in the SmartThreadPool. - This value is used with the Cancel, to calculate if we can send new - work items to the STP. - - - - - WorkItemsGroup start information - - - - - Signaled when all of the WorkItemsGroup's work item completed. - - - - - A common object for all the work items that this work items group - generate so we can mark them to cancel in O(1) - - - - - Start the Work Items Group if it was started suspended - - - - - Wait for the thread pool to be idle - - - - - The OnIdle event - - - - - WorkItemsGroup start information - - - - - WorkItemsQueue class. - - - - - Waiters queue (implemented as stack). - - - - - Waiters count - - - - - Work items queue - - - - - Indicate that work items are allowed to be queued - - - - - A flag that indicates if the WorkItemsQueue has been disposed. - - - - - Enqueue a work item to the queue. - - - - - Waits for a work item or exits on timeout or cancel - - Timeout in milliseconds - Cancel wait handle - Returns true if the resource was granted - - - - Cleanup the work items queue, hence no more work - items are allowed to be queue - - - - - Returns the WaiterEntry of the current thread - - - In order to avoid creation and destuction of WaiterEntry - objects each thread has its own WaiterEntry object. - - - - Push a new waiter into the waiter's stack - - A waiter to put in the stack - - - - Pop a waiter from the waiter's stack - - Returns the first waiter in the stack - - - - Remove a waiter from the stack - - A waiter entry to remove - If true the waiter count is always decremented - - - - Each thread in the thread pool keeps its own waiter entry. - - - - - Returns the current number of work items in the queue - - - - - Returns the current number of waiters - - - - - Event to signal the waiter that it got the work item. - - - - - Flag to know if this waiter already quited from the queue - because of a timeout. - - - - - Flag to know if the waiter was signaled and got a work item. - - - - - A work item that passed directly to the waiter withou going - through the queue - - - - - Signal the waiter that it got a work item. - - Return true on success - The method fails if Timeout() preceded its call - - - - Mark the wait entry that it has been timed out - - Return true on success - The method fails if Signal() preceded its call - - - - Reset the wait entry so it can be used again - - - - - Free resources - - - - - Respond with a 'Soft redirect' so smart clients (e.g. ajax) have access to the response and - can decide whether or not they should redirect - - - - - Decorate the response with an additional client-side event to instruct participating - smart clients (e.g. ajax) with hints to transparently invoke client-side functionality - - - - - Shortcut to get the ResponseDTO whether it's bare or inside a IHttpResult - - - - - - - Alias of AsDto - - - - - Shortcut to get the ResponseDTO whether it's bare or inside a IHttpResult - - - TResponse if found; otherwise null - - - - Alias of AsDto - - - - - Whether the response is an IHttpError or Exception - - - - - rangeHeader should be of the format "bytes=0-" or "bytes=0-12345" or "bytes=123-456" - - - - - Adds 206 PartialContent Status, Content-Range and Content-Length headers - - - - - Writes partial range as specified by start-end, from fromStream to toStream. - - - - - Service error logs are kept in 'urn:ServiceErrors:{ServiceName}' - - - - - Combined service error logs are maintained in 'urn:ServiceErrors:All' - - - - - RequestLogs service Route, default is /requestlogs - - - - - Turn On/Off Session Tracking - - - - - Turn On/Off Logging of Raw Request Body, default is Off - - - - - Turn On/Off Tracking of Responses - - - - - Turn On/Off Tracking of Exceptions - - - - - Size of InMemoryRollingRequestLogger circular buffer - - - - - Limit access to /requestlogs service to these roles - - - - - Change the RequestLogger provider. Default is InMemoryRollingRequestLogger - - - - - Don't log requests of these types. By default RequestLog's are excluded - - - - - Don't log request bodys for services with sensitive information. - By default Auth and Registration requests are hidden. - - - - - Indicates that the request dto, which is associated with this attribute, - requires authentication. - - - - - Restrict authentication to a specific . - For example, if this attribute should only permit access - if the user is authenticated with , - you should set this property to . - - - - - Redirect the client to a specific URL if authentication failed. - If this property is null, simply `401 Unauthorized` is returned. - - - - - Enable the authentication feature and configure the AuthService. - - - - - Inject logic into existing services by introspecting the request and injecting your own - validation logic. Exceptions thrown will have the same behaviour as if the service threw it. - - If a non-null object is returned the request will short-circuit and return that response. - - The instance of the service - GET,POST,PUT,DELETE - - Response DTO; non-null will short-circuit execution and return that response - - - - Public API entry point to authenticate via code - - - null; if already autenticated otherwise a populated instance of AuthResponse - - - - The specified may change as a side-effect of this method. If - subsequent code relies on current data be sure to reload - the session istance via . - - - - - Base class for entity validator classes. - - The type of the object being validated - - - - Defines a validator for a particualr type. - - - - - - Defines a validator for a particular type. - - - - - Validates the specified instance - - - A ValidationResult containing any validation failures - - - - Validates the specified instance. - - A ValidationContext - A ValidationResult object containy any validation failures. - - - - Creates a hook to access various meta data properties - - A IValidatorDescriptor object which contains methods to access metadata - - - - Checks to see whether the validator can validate objects of the specified type - - - - - Validates the specified instance. - - The instance to validate - A ValidationResult object containing any validation failures. - - - - Sets the cascade mode for all rules within this validator. - - - - - Validates the specified instance - - The object to validate - A ValidationResult object containing any validation failures - - - - Validates the specified instance. - - Validation Context - A ValidationResult object containing any validation failures. - - - - Adds a rule to the current validator. - - - - - - Creates a that can be used to obtain metadata about the current validator. - - - - - Defines a validation rule for a specify property. - - - RuleFor(x => x.Surname)... - - The type of property being validated - The expression representing the property to validate - an IRuleBuilder instance on which validators can be defined - - - - Defines a custom validation rule using a lambda expression. - If the validation rule fails, it should return a instance of a ValidationFailure - If the validation rule succeeds, it should return null. - - A lambda that executes custom validation rules. - - - - Defines a custom validation rule using a lambda expression. - If the validation rule fails, it should return an instance of ValidationFailure - If the validation rule succeeds, it should return null. - - A lambda that executes custom validation rules - - - - Defines a RuleSet that can be used to group together several validators. - - The name of the ruleset. - Action that encapsulates the rules in the ruleset. - - - - Defines a RuleSet that can be used to provide specific validation rules for specific HTTP methods (GET, POST...) - - The HTTP methods where this rule set should be used. - Action that encapuslates the rules in the ruleset. - - - - Defines a condition that applies to several rules - - The condition that should apply to multiple rules - Action that encapsulates the rules. - - - - - Defiles an inverse condition that applies to several rules - - The condition that should be applied to multiple rules - Action that encapsulates the rules - - - - Returns an enumerator that iterates through the collection of validation rules. - - - A that can be used to iterate through the collection. - - 1 - - - - Sets the cascade mode for all rules within this validator. - - - - - Create a Facebook App at: https://developers.facebook.com/apps - The Callback URL for your app should match the CallbackUrl provided. - - - - - Download Yammer User Info given its ID. - - - The Yammer User ID. - - - The User info in JSON format. - - - - Yammer provides a method to retrieve current user information via - "https://www.yammer.com/api/v1/users/current.json". - - - However, to ensure consistency with the rest of the Auth codebase, - the explicit URL will be used, where [:id] denotes the User ID: - "https://www.yammer.com/api/v1/users/[:id].json" - - - Refer to: https://developer.yammer.com/restapi/ for full documentation. - - - - - - Thread-safe In memory UserAuth data store so it can be used without a dependency on Redis. - - - - - Creates the required missing tables or DB schema - - - - - Update an existing registraiton - - - - - Create new Registration - - - - - Logic to update UserAuth from Registration info, not enabled on PUT because of security. - - - - - Thank you Martijn - http://www.dijksterhuis.org/creating-salted-hash-values-in-c/ - - - - - Create an app at https://dev.twitter.com/apps to get your ConsumerKey and ConsumerSecret for your app. - The Callback URL for your app should match the CallbackUrl provided. - - - - - The ServiceStack Yammer OAuth provider. - - - - This provider is loosely based on the existing ServiceStack's Facebook OAuth provider. - - - For the full info on Yammer's OAuth2 authentication flow, refer to: - https://developer.yammer.com/authentication/#a-oauth2 - - - Note: Add these to your application / web config settings under appSettings and replace - values as appropriate. - - - - - - - - - ]]> - - - - - - The OAuth provider name / identifier. - - - - - Initializes a new instance of the class. - - - The application settings (in web.config). - - - - - Authenticate against Yammer OAuth endpoint. - - - The auth service. - - - The session. - - - The request. - - - The . - - - - - Load the UserAuth info into the session. - - - The User session. - - - The OAuth tokens. - - - The auth info. - - - - - Load the UserOAuth info into the session. - - - The auth session. - - - The OAuth tokens. - - - - - Gets or sets the Yammer OAuth client id. - - - - - Gets or sets the Yammer OAuth client secret. - - - - - Gets or sets the Yammer OAuth pre-auth url. - - - - - The Yammer User's email addresses. - - - - - Gets or sets the email address type (e.g. primary). - - - - - Gets or sets the email address. - - - - - Removes items from cache that have keys matching the specified wildcard pattern - - Cache client - The wildcard, where "*" means any sequence of characters and "?" means any single character. - - - - Removes items from the cache based on the specified regular expression pattern - - Cache client - Regular expression pattern to search cache keys - - - - Stores The value with key only if such key doesn't exist at the server yet. - - - - - Adds or replaces the value with key. - - - - - Adds or replaces the value with key. - - - - - Replace the value with specified key if it exists. - - - - - Add the value with key to the cache, set to never expire. - - - - - Add or replace the value with key to the cache, set to never expire. - - - - - Replace the value with key in the cache, set to never expire. - - - - - Add the value with key to the cache, set to expire at specified DateTime. - - This method examines the DateTimeKind of expiresAt to determine if conversion to - universal time is needed. The version of Add that takes a TimeSpan expiration is faster - than using this method with a DateTime of Kind other than Utc, and is not affected by - ambiguous local time during daylight savings/standard time transition. - - - - Add or replace the value with key to the cache, set to expire at specified DateTime. - - This method examines the DateTimeKind of expiresAt to determine if conversion to - universal time is needed. The version of Set that takes a TimeSpan expiration is faster - than using this method with a DateTime of Kind other than Utc, and is not affected by - ambiguous local time during daylight savings/standard time transition. - - - - Replace the value with key in the cache, set to expire at specified DateTime. - - This method examines the DateTimeKind of expiresAt to determine if conversion to - universal time is needed. The version of Replace that takes a TimeSpan expiration is faster - than using this method with a DateTime of Kind other than Utc, and is not affected by - ambiguous local time during daylight savings/standard time transition. - - - - Add the value with key to the cache, set to expire after specified TimeSpan. - - - - - Add or replace the value with key to the cache, set to expire after specified TimeSpan. - - - - - Replace the value with key in the cache, set to expire after specified TimeSpan. - - - - - Create new instance of CacheEntry. - - - - UTC time at which CacheEntry expires. - - - - Would've preferred to use [assembly: ContractNamespace] attribute but it is not supported in Mono - - - - - More familiar name for the new crowd. - - - - - The tier lets you specify a retrieving a setting with the tier prefix first before falling back to the original key. - E.g a tier of 'Live' looks for 'Live.{Key}' or if not found falls back to '{Key}'. - - - - - Returns string if exists, otherwise null - - - - - - - Gets the nullable app setting. - - - - - Gets the app setting. - - - - - Determines wheter the Config section identified by the sectionName exists. - - - - - Returns AppSetting[key] if exists otherwise defaultValue - - - - - Returns AppSetting[key] if exists otherwise defaultValue, for non-string values - - - - - Gets the connection string setting. - - - - - Gets the connection string. - - - - - Gets the list from app setting. - - - - - Gets the dictionary from app setting. - - - - - Get the static Parse(string) method on the type supplied - - - - - Gets the constructor info for T(string) if exists. - - - - - Returns the value returned by the 'T.Parse(string)' method if exists otherwise 'new T(string)'. - e.g. if T was a TimeSpan it will return TimeSpan.Parse(textValue). - If there is no Parse Method it will attempt to create a new instance of the destined type - - - - - Plugin adds support for Cross-origin resource sharing (CORS, see http://www.w3.org/TR/access-control/). - CORS allows to access resources from different domain which usually forbidden by origin policy. - - - - - Represents a default constructor with Allow Origin equals to "*", Allowed GET, POST, PUT, DELETE, OPTIONS request and allowed "Content-Type" header. - - - - - Attribute marks that specific response class has support for Cross-origin resource sharing (CORS, see http://www.w3.org/TR/access-control/). CORS allows to access resources from different domain which usually forbidden by origin policy. - - - - - Represents a default constructor with Allow Origin equals to "*", Allowed GET, POST, PUT, DELETE, OPTIONS request and allowed "Content-Type" header. - - - - - Change the default HTML view or template used for the HTML response of this service - - - - - Class that can be used to find all the validators from a collection of types. - - - - - Creates a scanner that works on a sequence of types. - - - - - Finds all the validators in the specified assembly. - - - - - Finds all the validators in the assembly containing the specified type. - - - - - Performs the specified action to all of the assembly scan results. - - - - - Returns an enumerator that iterates through the collection. - - - A that can be used to iterate through the collection. - - 1 - - - - Result of performing a scan. - - - - - Creates an instance of an AssemblyScanResult. - - - - - Validator interface type, eg IValidator<Foo> - - - - - Concrete type that implements the InterfaceType, eg FooValidator. - - - - - Implementation of IValidatorFactory that looks for ValidatorAttribute instances on the specified type in order to provide the validator instance. - - - - - Gets validators for a particular type. - - - - - Gets the validator for the specified type. - - - - - Gets the validator for the specified type. - - - - - Gets a validator for the appropriate type. - - - - - Gets a validator for the appropriate type. - - - - - Validator attribute to define the class that will describe the Validation rules - - - - - Creates an instance of the ValidatorAttribute allowing a validator type to be specified. - - - - - The type of the validator used to validate the current type. - - - - - Associates an instance of IValidator with the current property rule and is used to validate each item within the collection. - - The validator to use - - - - Rule builder - - - - - - - Rule builder - - - - - - - Associates a validator with this the property for this rule builder. - - The validator to set - - - - - Associates an instance of IValidator with the current property rule. - - The validator to use - - - - Represents an object that is configurable. - - Type of object being configured - Return type - - - - Configures the current object. - - Action to configure the object. - - - - - Extension methods that provide the default set of validators. - - - - - Defines a 'not null' validator on the current rule builder. - Validation will fail if the property is null. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - - - - - Defines a 'not empty' validator on the current rule builder. - Validation will fail if the property is null, an empty or the default value for the type (for example, 0 for integers) - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - - - - - Defines a length validator on the current rule builder, but only for string properties. - Validation will fail if the length of the string is outside of the specifed range. The range is inclusive. - - Type of object being validated - The rule builder on which the validator should be defined - - - - - Defines a length validator on the current rule builder, but only for string properties. - Validation will fail if the length of the string is not equal to the length specified. - - Type of object being validated - The rule builder on which the validator should be defined - - - - - Defines a regular expression validator on the current rule builder, but only for string properties. - Validation will fail if the value returned by the lambda does not match the regular expression. - - Type of object being validated - The rule builder on which the validator should be defined - The regular expression to check the value against. - - - - - Defines a regular expression validator on the current rule builder, but only for string properties. - Validation will fail if the value returned by the lambda is not a valid email address. - - Type of object being validated - The rule builder on which the validator should be defined - - - - - Defines a 'not equal' validator on the current rule builder. - Validation will fail if the specified value is equal to the value of the property. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value to compare - Equality comparer to use - - - - - Defines a 'not equal' validator on the current rule builder using a lambda to specify the value. - Validation will fail if the value returned by the lambda is equal to the value of the property. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - A lambda expression to provide the comparison value - Equality Comparer to use - - - - - Defines an 'equals' validator on the current rule builder. - Validation will fail if the specified value is not equal to the value of the property. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value to compare - Equality Comparer to use - - - - - Defines an 'equals' validator on the current rule builder using a lambda to specify the comparison value. - Validation will fail if the value returned by the lambda is not equal to the value of the property. - - The type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - A lambda expression to provide the comparison value - Equality comparer to use - - - - - Defines a predicate validator on the current rule builder using a lambda expression to specify the predicate. - Validation will fail if the specified lambda returns false. - Validation will succeed if the specifed lambda returns true. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - A lambda expression specifying the predicate - - - - - Defines a predicate validator on the current rule builder using a lambda expression to specify the predicate. - Validation will fail if the specified lambda returns false. - Validation will succeed if the specifed lambda returns true. - This overload accepts the object being validated in addition to the property being validated. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - A lambda expression specifying the predicate - - - - - Defines a predicate validator on the current rule builder using a lambda expression to specify the predicate. - Validation will fail if the specified lambda returns false. - Validation will succeed if the specifed lambda returns true. - This overload accepts the object being validated in addition to the property being validated. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - A lambda expression specifying the predicate - - - - - Defines a 'less than' validator on the current rule builder. - The validation will succeed if the property value is less than the specified value. - The validation will fail if the property value is greater than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than' validator on the current rule builder. - The validation will succeed if the property value is less than the specified value. - The validation will fail if the property value is greater than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than or equal' validator on the current rule builder. - The validation will succeed if the property value is less than or equal to the specified value. - The validation will fail if the property value is greater than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than or equal' validator on the current rule builder. - The validation will succeed if the property value is less than or equal to the specified value. - The validation will fail if the property value is greater than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'greater than' validator on the current rule builder. - The validation will succeed if the property value is greater than the specified value. - The validation will fail if the property value is less than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'greater than' validator on the current rule builder. - The validation will succeed if the property value is greater than the specified value. - The validation will fail if the property value is less than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'greater than or equal' validator on the current rule builder. - The validation will succeed if the property value is greater than or equal the specified value. - The validation will fail if the property value is less than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'greater than or equal' validator on the current rule builder. - The validation will succeed if the property value is greater than or equal the specified value. - The validation will fail if the property value is less than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is less than the specified value. - The validation will fail if the property value is greater than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - A lambda that should return the value being compared - - - - - Defines a 'less than' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is less than the specified value. - The validation will fail if the property value is greater than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - A lambda that should return the value being compared - - - - - Defines a 'less than or equal' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is less than or equal to the specified value. - The validation will fail if the property value is greater than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than or equal' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is less than or equal to the specified value. - The validation will fail if the property value is greater than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is greater than the specified value. - The validation will fail if the property value is less than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is greater than the specified value. - The validation will fail if the property value is less than or equal to the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is greater than or equal the specified value. - The validation will fail if the property value is less than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Defines a 'less than' validator on the current rule builder using a lambda expression. - The validation will succeed if the property value is greater than or equal the specified value. - The validation will fail if the property value is less than the specified value. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The value being compared - - - - - Validates certain properties of the specified instance. - - The current validator - The object to validate - Expressions to specify the properties to validate - A ValidationResult object containing any validation failures - - - - Validates certain properties of the specified instance. - - The object to validate - The names of the properties to validate. - A ValidationResult object containing any validation failures. - - - - Performs validation and then throws an exception if validation fails. - - - - - Defines an 'inclusive between' validator on the current rule builder, but only for properties of types that implement IComparable. - Validation will fail if the value of the property is outside of the specifed range. The range is inclusive. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The lowest allowed value - The highest allowed value - - - - - Defines an 'inclusive between' validator on the current rule builder, but only for properties of types that implement IComparable. - Validation will fail if the value of the property is outside of the specifed range. The range is inclusive. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The lowest allowed value - The highest allowed value - - - - - Defines an 'exclusive between' validator on the current rule builder, but only for properties of types that implement IComparable. - Validation will fail if the value of the property is outside of the specifed range. The range is exclusive. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The lowest allowed value - The highest allowed value - - - - - Defines an 'exclusive between' validator on the current rule builder, but only for properties of types that implement IComparable. - Validation will fail if the value of the property is outside of the specifed range. The range is exclusive. - - Type of object being validated - Type of property being validated - The rule builder on which the validator should be defined - The lowest allowed value - The highest allowed value - - - - - Defines a credit card validator for the current rule builder that ensures that the specified string is a valid credit card number. - - - - - Default options that can be used to configure a validator. - - - - - Specifies the cascade mode for failures. - If set to 'Stop' then execution of the rule will stop once the first validator in the chain fails. - If set to 'Continue' then all validators in the chain will execute regardless of failures. - - - - - Specifies a custom action to be invoked when the validator fails. - - - - - - - - - - Specifies a custom error message to use if validation fails. - - The current rule - The error message to use - - - - - Specifies a custom error message to use if validation fails. - - The current rule - The error message to use - Additional arguments to be specified when formatting the custom error message. - - - - - Specifies a custom error message to use if validation fails. - - The current rule - The error message to use - Additional property values to be included when formatting the custom error message. - - - - - Specifies a custom error message resource to use when validation fails. - - The current rule - The resource to use as an expression, eg () => Messages.MyResource - - - - - Specifies a custom error message resource to use when validation fails. - - The current rule - The resource to use as an expression, eg () => Messages.MyResource - Custom message format args - - - - - Specifies a custom error message resource to use when validation fails. - - The current rule - The resource to use as an expression, eg () => Messages.MyResource - Custom message format args - - - - - Specifies a custom error message resource to use when validation fails. - - The current rule - The resource to use as an expression, eg () => Messages.MyResource - The resource accessor builder to use. - - - - - Specifies a custom error code to use when validation fails - - The current rule - The error code to use - - - - - Specifies a condition limiting when the validator should run. - The validator will only be executed if the result of the lambda returns true. - - The current rule - A lambda expression that specifies a condition for when the validator should run - Whether the condition should be applied to the current rule or all rules in the chain - - - - - Specifies a condition limiting when the validator should not run. - The validator will only be executed if the result of the lambda returns false. - - The current rule - A lambda expression that specifies a condition for when the validator should not run - Whether the condition should be applied to the current rule or all rules in the chain - - - - - Specifies a custom property name to use within the error message. - - The current rule - The property name to use - - - - - Specifies a localized name for the error message. - - The current rule - The resource to use as an expression, eg () => Messages.MyResource - Resource accessor builder to use - - - - Overrides the name of the property associated with this rule. - NOTE: This is a considered to be an advanced feature. 99% of the time that you use this, you actually meant to use WithName. - - The current rule - The property name to use - - - - - Specifies custom state that should be stored alongside the validation message when validation fails for this rule. - - - - - - - - - - Specifies how rules should cascade when one fails. - - - - - When a rule fails, execution continues to the next rule. - - - - - When a rule fails, validation is stopped and all other rules in the chain will not be executed. - - - - - Specifies where a When/Unless condition should be applied - - - - - Applies the condition to all validators declared so far in the chain. - - - - - Applies the condition to the current validator only. - - - - - Validator implementation that allows rules to be defined without inheriting from AbstractValidator. - - - - public class Customer { - public int Id { get; set; } - public string Name { get; set; } - - public static readonly InlineValidator<Customer> Validator = new InlineValidator<Customer> { - v => v.RuleFor(x => x.Name).NotNull(), - v => v.RuleFor(x => x.Id).NotEqual(0), - } - } - - - - - - - Allows configuration of the validator. - - - - - Delegate that specifies configuring an InlineValidator. - - - - - Default validator selector that will execute all rules that do not belong to a RuleSet. - - - - - Determines whether or not a rule should execute. - - - - - Determines whether or not a rule should execute. - - The rule - Property path (eg Customer.Address.Line1) - Contextual information - Whether or not the validator can execute. - - - - Determines whether or not a rule should execute. - - The rule - Property path (eg Customer.Address.Line1) - Contextual information - Whether or not the validator can execute. - - - - Custom IValidationRule for performing custom logic. - - - - - - Defines a rule associated with a property which can have multiple validators. - - - - - Performs validation using a validation context and returns a collection of Validation Failures. - - Validation Context - A collection of validation failures - - - - The validators that are grouped under this rule. - - - - - Name of the rule-set to which this rule belongs. - - - - - Creates a new DelegateValidator using the specified function to perform validation. - - - - - Creates a new DelegateValidator using the specified function to perform validation. - - - - - Performs validation using a validation context and returns a collection of Validation Failures. - - Validation Context - A collection of validation failures - - - - Performs validation using a validation context and returns a collection of Validation Failures. - - Validation Context - A collection of validation failures - - - - Rule set to which this rule belongs. - - - - - The validators that are grouped under this rule. - - - - - Useful extensions - - - - - Gets a MemberInfo from a member expression. - - - - - Gets a MemberInfo from a member expression. - - - - - Splits pascal case, so "FooBar" would become "Foo Bar" - - - - - Helper method to construct a constant expression from a constant. - - Type of object being validated - Type of property being validated - The value being compared - - - - - Based on a child validator and a propery rule, infers whether the validator should be wrapped in a ChildValidatorAdaptor or a CollectionValidatorAdaptor - - - - - Instancace cache. - TODO: This isn't actually completely thread safe. It would be much better to use ConcurrentDictionary, but this isn't available in Silverlight/WP7. - - - - - Gets or creates an instance using Activator.CreateInstance - - The type to instantiate - The instantiated object - - - - Gets or creates an instance using a custom factory - - The type to instantiate - The custom factory - The instantiated object - - - - Selects validators that are associated with a particular property. - - - - - Creates a new instance of MemberNameValidatorSelector. - - - - - Determines whether or not a rule should execute. - - The rule - Property path (eg Customer.Address.Line1) - Contextual information - Whether or not the validator can execute. - - - - Creates a MemberNameValidatorSelector from a collection of expressions. - - - - - Assists in the construction of validation messages. - - - - - Default Property Name placeholder. - - - - - Adds a value for a validation message placeholder. - - - - - - - - Appends a property name to the message. - - The name of the property - - - - - Adds additional arguments to the message for use with standard string placeholders. - - Additional arguments - - - - - Constructs the final message from the specified template. - - Message template - The message with placeholders replaced with their appropriate values - - - - Represents a chain of properties - - - - - Creates a new PropertyChain. - - - - - Creates a new PropertyChain based on another. - - - - - Adds a MemberInfo instance to the chain - - Member to add - - - - Adds a property name to the chain - - Name of the property to add - - - - Adds an indexer to the property chain. For example, if the following chain has been constructed: - Parent.Child - then calling AddIndexer(0) would convert this to: - Parent.Child[0] - - - - - - Creates a string representation of a property chain. - - - - - Checks if the current chain is the child of another chain. - For example, if chain1 were for "Parent.Child" and chain2 were for "Parent.Child.GrandChild" then - chain2.IsChildChainOf(chain1) would be true. - - The parent chain to compare - True if the current chain is the child of the other chain, otherwise false - - - - Builds a property path. - - - - - Defines a rule associated with a property. - - - - - Creates a new property rule. - - Property - Function to get the property value - Lambda expression used to create the rule - Function to get the cascade mode. - Type to validate - Container type that owns the property - - - - Creates a new property rule from a lambda expression. - - - - - Creates a new property rule from a lambda expression. - - - - - Adds a validator to the rule. - - - - - Replaces a validator in this rule. Used to wrap validators. - - - - - Display name for the property. - - - - - Performs validation using a validation context and returns a collection of Validation Failures. - - Validation Context - A collection of validation failures - - - - Invokes a property validator using the specified validation context. - - - - - Property associated with this rule. - - - - - Function that can be invoked to retrieve the value of the property. - - - - - Expression that was used to create the rule. - - - - - String source that can be used to retrieve the display name (if null, falls back to the property name) - - - - - Rule set that this rule belongs to (if specified) - - - - - Function that will be invoked if any of the validators associated with this rule fail. - - - - - The current validator being configured by this rule. - - - - - Type of the property being validated - - - - - Cascade mode for this rule. - - - - - Validators associated with this rule. - - - - - Returns the property name for the property being validated. - Returns null if it is not a property being validated (eg a method call) - - - - - Builds a validation rule and constructs a validator. - - Type of object being validated - Type of property being validated - - - - Rule builder that starts the chain - - - - - - - Creates a new instance of the RuleBuilder class. - - - - - Sets the validator associated with the rule. - - The validator to set - - - - - Sets the validator associated with the rule. Use with complex properties where an IValidator instance is already declared for the property type. - - The validator to set - - - - The rule being created by this RuleBuilder. - - - - - Selects validators that belong to the specified rulesets. - - - - - Creates a new instance of the RulesetValidatorSelector. - - - - - Determines whether or not a rule should execute. - - The rule - Property path (eg Customer.Address.Line1) - Contextual information - Whether or not the validator can execute. - - - - Provides metadata about a validator. - - - - - Gets the name display name for a property. - - - - - Gets a collection of validators grouped by property. - - - - - Gets validators for a particular property. - - - - - Gets rules for a property. - - - - - Builds a delegate for retrieving a localised resource from a resource type and property name. - - - - - Gets a function that can be used to retrieve a message from a resource type and resource name. - - - - - Builds a delegate for retrieving a localised resource from a resource type and property name. - - - - - Builds a function used to retrieve the resource. - - - - - Gets the PropertyInfo for a resource. - ResourceType and ResourceName are ref parameters to allow derived types - to replace the type/name of the resource before the delegate is constructed. - - - - - Implemenetation of IResourceAccessorBuilder that can fall back to the default resource provider. - - - - - Gets the PropertyInfo for a resource. - ResourceType and ResourceName are ref parameters to allow derived types - to replace the type/name of the resource before the delegate is constructed. - - - - - Provides error message templates - - - - - Construct the error message template - - Error message template - - - - The name of the resource if localized. - - - - - The type of the resource provider if localized. - - - - - Represents a localized string. - - - - - Creates a new instance of the LocalizedErrorMessageSource class using the specified resource name and resource type. - - The resource type - The resource name - Strategy used to construct the resource accessor - - - - Creates an IErrorMessageSource from an expression: () => MyResources.SomeResourceName - - The expression - Strategy used to construct the resource accessor - Error message source - - - - Construct the error message template - - Error message template - - - - The name of the resource if localized. - - - - - The type of the resource provider if localized. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to '{PropertyName}' is not a valid credit card number.. - - - - - Looks up a localized string similar to '{PropertyName}' is not a valid email address.. - - - - - Looks up a localized string similar to '{PropertyName}' should be equal to '{PropertyValue}'.. - - - - - Looks up a localized string similar to '{PropertyName}' must be {MaxLength} characters in length. You entered {TotalLength} characters.. - - - - - Looks up a localized string similar to '{PropertyName}' must be between {From} and {To} (exclusive). You entered {Value}.. - - - - - Looks up a localized string similar to '{PropertyName}' must be greater than '{ComparisonValue}'.. - - - - - Looks up a localized string similar to '{PropertyName}' must be greater than or equal to '{ComparisonValue}'.. - - - - - Looks up a localized string similar to '{PropertyName}' must be between {From} and {To}. You entered {Value}.. - - - - - Looks up a localized string similar to '{PropertyName}' must be between {MinLength} and {MaxLength} characters. You entered {TotalLength} characters.. - - - - - Looks up a localized string similar to '{PropertyName}' must be less than '{ComparisonValue}'.. - - - - - Looks up a localized string similar to '{PropertyName}' must be less than or equal to '{ComparisonValue}'.. - - - - - Looks up a localized string similar to '{PropertyName}' should not be empty.. - - - - - Looks up a localized string similar to '{PropertyName}' should not be equal to '{PropertyValue}'.. - - - - - Looks up a localized string similar to '{PropertyName}' must not be empty.. - - - - - Looks up a localized string similar to The specified condition was not met for '{PropertyName}'.. - - - - - Looks up a localized string similar to '{PropertyName}' is not in the correct format.. - - - - - Represents a static string. - - - - - Creates a new StringErrorMessageSource using the specified error message as the error template. - - The error message template. - - - - Construct the error message template - - Error message template - - - - The name of the resource if localized. - - - - - The type of the resource provider if localized. - - - - - Creates a new validation failure. - - - - - Creates a new ValidationFailure. - - - - - Creates a textual representation of the failure. - - - - - The name of the property. - - - - - The error message - - - - - The error code - - - - - The property value that caused the failure. - - - - - Custom state associated with the failure. - - - - - Used for providing metadata about a validator. - - - - - A custom property validator. - This interface should not be implemented directly in your code as it is subject to change. - Please inherit from PropertyValidator instead. - - - - - Creates an error validation result for this validator. - - The validator context - Returns an error validation result. - - - - Ensures that the property value is a valid credit card number. - - - - - Provides access to the anti-forgery system, which provides protection against - Cross-site Request Forgery (XSRF, also called CSRF) attacks. - - - - - Generates an anti-forgery token for this request. This token can - be validated by calling the Validate() method. - - An HTML string corresponding to an <input type="hidden"> - element. This element should be put inside a <form>. - - This method has a side effect: it may set a response cookie. - - - - - Generates an anti-forgery token pair (cookie and form token) for this request. - This method is similar to GetHtml(), but this method gives the caller control - over how to persist the returned values. To validate these tokens, call the - appropriate overload of Validate. - - The anti-forgery token - if any - that already existed - for this request. May be null. The anti-forgery system will try to reuse this cookie - value when generating a matching form token. - Will contain a new cookie value if the old cookie token - was null or invalid. If this value is non-null when the method completes, the caller - must persist this value in the form of a response cookie, and the existing cookie value - should be discarded. If this value is null when the method completes, the existing - cookie value was valid and needn't be modified. - The value that should be stored in the <form>. The caller - should take care not to accidentally swap the cookie and form tokens. - - Unlike the GetHtml() method, this method has no side effect. The caller - is responsible for setting the response cookie and injecting the returned - form token as appropriate. - - - - - Validates an anti-forgery token that was supplied for this request. - The anti-forgery token may be generated by calling GetHtml(). - - - Throws an HttpAntiForgeryException if validation fails. - - - - - Validates an anti-forgery token pair that was generated by the GetTokens method. - - The token that was supplied in the request cookie. - The token that was supplied in the request form body. - - Throws an HttpAntiForgeryException if validation fails. - - - - - Provides programmatic configuration for the anti-forgery token system. - - - - - Specifies an object that can provide additional data to put into all - generated tokens and that can validate additional data in incoming - tokens. - - - - - Specifies the name of the cookie that is used by the anti-forgery - system. - - - If an explicit name is not provided, the system will automatically - generate a name. - - - - - Specifies whether SSL is required for the anti-forgery system - to operate. If this setting is 'true' and a non-SSL request - comes into the system, all anti-forgery APIs will fail. - - - - - Specifies whether the anti-forgery system should skip checking - for conditions that might indicate misuse of the system. Please - use caution when setting this switch, as improper use could open - security holes in the application. - - - Setting this switch will disable several checks, including: - - Identity.IsAuthenticated = true without Identity.Name being set - - special-casing claims-based identities - - - - - If claims-based authorization is in use, specifies the claim - type from the identity that is used to uniquely identify the - user. If this property is set, all claims-based identities - must return unique values for this claim type. - - - If claims-based authorization is in use and this property has - not been set, the anti-forgery system will automatically look - for claim types "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" - and "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider". - - - - - Allows providing or validating additional custom data for anti-forgery tokens. - For example, the developer could use this to supply a nonce when the token is - generated, then he could validate the nonce when the token is validated. - - - The anti-forgery system already embeds the client's username within the - generated tokens. This interface provides and consumes supplemental - data. If an incoming anti-forgery token contains supplemental data but no - additional data provider is configured, the supplemental data will not be - validated. - - - - - Provides additional data to be stored for the anti-forgery tokens generated - during this request. - - Information about the current request. - Supplemental data to embed within the anti-forgery token. - - - - Validates additional data that was embedded inside an incoming anti-forgery - token. - - Information about the current request. - Supplemental data that was embedded within the token. - True if the data is valid; false if the data is invalid. - - - - Initializes a new instance of the class. - - The base scope. - - The dictionary to use as a storage. Since the dictionary would be used as-is, we expect the implementer to - use the same key-value comparison logic as we do here. - - - - - Custom comparer for the context dictionaries - The comparer treats strings as a special case, performing case insesitive comparison. - This guaratees that we remain consistent throughout the chain of contexts since PageData dictionary - behaves in this manner. - - - - - End a ServiceStack Request - - - - - End a ServiceStack Request - - - - - End a HttpHandler Request - - - - - End a HttpHandler Request - - - - - End a ServiceStack Request with no content - - - - - Main container class for components, supporting container hierarchies and - lifetime management of instances. - - - - - Initializes a new empty container. - - - - - Creates a child container of the current one, which exposes its - current service registration to the new child container. - - - - - Disposes the container and all instances owned by it (see - ), as well as all child containers - created through . - - - - - Registers a service instance with the container. This instance - will have and - behavior. - Service instance to use. - - - - Registers a named service instance with the container. This instance - will have and - behavior. - Name of the service to register.Service instance to use. - - - - Retrieves a function that can be used to lazily resolve an instance - of the service when needed. - Type of the service to retrieve.The function that can resolve to the service instance when invoked.The requested service has not been registered previously. - - - - - - - - - - - - - - - - - - - - - - Retrieves a function that can be used to lazily resolve an instance - of the service with the given name when needed. - Type of the service to retrieve.Name of the service to retrieve.The function that can resolve to the service instance with the given name when invoked.The requested service with the given name has not been registered previously. - - - - Retrieves a function that can be used to lazily resolve an instance - of the service of the given type, name and service constructor arguments when needed. - Name of the service to retrieve.The function that can resolve to the service instance with the given and service constructor arguments name when invoked.The requested service with the given name and constructor arguments has not been registered previously. - - - - Retrieves a function that can be used to lazily resolve an instance - of the service of the given type, name and service constructor arguments when needed. - Name of the service to retrieve.The function that can resolve to the service instance with the given and service constructor arguments name when invoked.The requested service with the given name and constructor arguments has not been registered previously. - - - - Retrieves a function that can be used to lazily resolve an instance - of the service of the given type, name and service constructor arguments when needed. - Name of the service to retrieve.The function that can resolve to the service instance with the given and service constructor arguments name when invoked.The requested service with the given name and constructor arguments has not been registered previously. - - - - Retrieves a function that can be used to lazily resolve an instance - of the service of the given type, name and service constructor arguments when needed. - Name of the service to retrieve.The function that can resolve to the service instance with the given and service constructor arguments name when invoked.The requested service with the given name and constructor arguments has not been registered previously. - - - - Retrieves a function that can be used to lazily resolve an instance - of the service of the given type, name and service constructor arguments when needed. - Name of the service to retrieve.The function that can resolve to the service instance with the given and service constructor arguments name when invoked.The requested service with the given name and constructor arguments has not been registered previously. - - - - Retrieves a function that can be used to lazily resolve an instance - of the service of the given type, name and service constructor arguments when needed. - Name of the service to retrieve.The function that can resolve to the service instance with the given and service constructor arguments name when invoked.The requested service with the given name and constructor arguments has not been registered previously. - - - - Registers the given service by providing a factory delegate to - instantiate it. - The service type to register.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.Fourth argument that should be passed to the factory delegate to create the instace.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.Fourth argument that should be passed to the factory delegate to create the instace.Fifth argument that should be passed to the factory delegate to create the instace.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.Fourth argument that should be passed to the factory delegate to create the instace.Fifth argument that should be passed to the factory delegate to create the instace.Sixth argument that should be passed to the factory delegate to create the instace.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given named service by providing a factory delegate to - instantiate it. - The service type to register.A name used to differenciate this service registration.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given named service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.A name used to differenciate this service registration.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given named service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.A name used to differenciate this service registration.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given named service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.A name used to differenciate this service registration.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given named service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.Fourth argument that should be passed to the factory delegate to create the instace.A name used to differenciate this service registration.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given named service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.Fourth argument that should be passed to the factory delegate to create the instace.Fifth argument that should be passed to the factory delegate to create the instace.A name used to differenciate this service registration.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Registers the given named service by providing a factory delegate that receives arguments to - instantiate it. - The service type to register.First argument that should be passed to the factory delegate to create the instace.Second argument that should be passed to the factory delegate to create the instace.Third argument that should be passed to the factory delegate to create the instace.Fourth argument that should be passed to the factory delegate to create the instace.Fifth argument that should be passed to the factory delegate to create the instace.Sixth argument that should be passed to the factory delegate to create the instace.A name used to differenciate this service registration.The factory delegate to initialize new instances of the service when needed.The registration object to perform further configuration via its fluent interface. - - - - Resolves the given service by type, without passing any arguments for - its construction. - Type of the service to retrieve.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace.Sixth argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type and name, without passing arguments for its initialization. - Type of the service to retrieve.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type and name, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type and name, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type and name, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type and name, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type and name, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Resolves the given service by type and name, passing the given arguments - for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace.Sixth argument to pass to the factory delegate that may create the instace.The resolved service instance.The given service could not be resolved. - - - - Attempts to resolve the given service by type, without passing arguments for its initialization. - Type of the service to retrieve. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace.Sixth argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type and name, without passing - arguments arguments for its initialization. - Type of the service to retrieve. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type and name, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type and name, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type and name, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type and name, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type and name, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Attempts to resolve the given service by type and name, passing the - given arguments arguments for its initialization. - Type of the service to retrieve.First argument to pass to the factory delegate that may create the instace.Second argument to pass to the factory delegate that may create the instace.Third argument to pass to the factory delegate that may create the instace.Fourth argument to pass to the factory delegate that may create the instace.Fifth argument to pass to the factory delegate that may create the instace.Sixth argument to pass to the factory delegate that may create the instace. - The resolved service instance or if it cannot be resolved. - - - - - Register an autowired dependency - - - - - - Register an autowired dependency as a separate type - - - - - - Alias for RegisterAutoWiredAs - - - - - - Auto-wires an existing instance, - ie all public properties are tried to be resolved. - - - - - - Generates a function which creates and auto-wires . - - - - - - - - Auto-wires an existing instance of a specific type. - The auto-wiring progress is also cached to be faster - when calling next time with the same type. - - - - - - Default owner for new registrations. by default. - - - - - Default reuse scope for new registrations. by default. - - - - - Enable the Registration feature and configure the RegistrationService. - - - - - Registers the type in the IoC container and - adds auto-wiring to the specified type. - - - - - - - Registers the type in the IoC container and - adds auto-wiring to the specified type. - The reuse scope is set to none (transient). - - - - - - Registers the types in the IoC container and - adds auto-wiring to the specified types. - The reuse scope is set to none (transient). - - - - - - Register a singleton instance as a runtime type - - - - - Encapsulates a method that has five parameters and returns a value of the - type specified by the parameter. - - - - - Encapsulates a method that has six parameters and returns a value of the - type specified by the parameter. - - - - - Encapsulates a method that has seven parameters and returns a value of the - type specified by the parameter. - - - - - Helper interface used to hide the base - members from the fluent API to make for much cleaner - Visual Studio intellisense experience. - - - - - - - - - - - - - - - - - Interface used by plugins to contribute registrations - to an existing container. - - - - - Determines who is responsible for disposing instances - registered with a container. - - - - - Container should dispose provided instances when it is disposed. This is the - default. - - - - - Container does not dispose provided instances. - - - - - Default owner, which equals . - - - - - Exception thrown by the container when a service cannot be resolved. - - - - - Initializes the exception with the service that could not be resolved. - - - - - Initializes the exception with the service (and its name) that could not be resolved. - - - - - Initializes the exception with an arbitrary message. - - - - - Determines visibility and reuse of instances provided by the container. - - - - - Instances are reused within a container hierarchy. Instances - are created (if necessary) in the container where the registration - was performed, and are reused by all descendent containers. - - - - - Instances are reused only at the given container. Descendent - containers do not reuse parent container instances and get - a new instance at their level. - - - - - Each request to resolve the dependency will result in a new - instance being returned. - - - - - Instaces are reused within the given request - - - - - Default scope, which equals . - - - - - Fluent API for customizing the registration of a service. - - - - - Fluent API that exposes both - and owner (). - - - - - Fluent API that allows specifying the reuse instances. - - - - - Specifies how instances are reused within a container or hierarchy. Default - scope is . - - - - - Fluent API that allows specifying the owner of instances - created from a registration. - - - - - Specifies the owner of instances created from this registration. Default - owner is . - - - - - Ownership setting for the service. - - - - - Reuse scope setting for the service. - - - - - The container where the entry was registered. - - - - - Specifies the owner for instances, which determines how - they will be disposed. - - - - - Specifies the scope for instances, which determines - visibility of instances across containers and hierarchies. - - - - - Fluent API for customizing the registration of a service. - - - - - Fluent API that allows registering an initializer for the - service. - - - - - Specifies an initializer that should be invoked after - the service instance has been created by the factory. - - - - - The Func delegate that creates instances of the service. - - - - - The cached service instance if the scope is or - . - - - - - The Func delegate that initializes the object after creation. - - - - - Clones the service entry assigning the to the - . Does not copy the . - - - - - BaseProfilerProvider. This providers some helper methods which provide access to - internals not otherwise available. - To use, override the , and - methods. - - - - - A provider used to create instances and maintain the current instance. - - - - - Starts a new MiniProfiler and sets it to be current. By the end of this method - should return the new MiniProfiler. - - - - - Ends the current profiling session, if one exists. - - - When true, clears the for this HttpContext, allowing profiling to - be prematurely stopped and discarded. Useful for when a specific route does not need to be profiled. - - - - - Returns the current MiniProfiler. This is used by . - - - - - - Starts a new MiniProfiler and sets it to be current. By the end of this method - should return the new MiniProfiler. - - - - - Stops the current MiniProfiler (if any is currently running). - should be called if is false - - If true, any current results will be thrown away and nothing saved - - - - Returns the current MiniProfiler. This is used by . - - - - - - Sets to be active (read to start profiling) - This should be called once a new MiniProfiler has been created. - - The profiler to set to active - If is null - - - - Stops the profiler and marks it as inactive. - - The profiler to stop - True if successful, false if Stop had previously been called on this profiler - If is null - - - - Calls to save the current - profiler using the current storage settings - - - - - - Categories of sql statements. - - - - - Unknown - - - - - DML statements that alter database state, e.g. INSERT, UPDATE - - - - - Statements that return a single record - - - - - Statements that iterate over a result set - - - - - A callback for ProfiledDbConnection and family - - - - - Called when a command starts executing - - - - - - - Called when a reader finishes executing - - - - - - - - Called when a reader is done iterating through the data - - - - - - Called when an error happens during execution of a command - - - - - - - - True if the profiler instance is active - - - - - This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - equality. The type is fully thread-safe. - - - - - If the underlying command supports BindByName, this sets/clears the underlying - implementation accordingly. This is required to support OracleCommand from dapper-dot-net - - - - - Wraps a database connection, allowing sql execution timings to be collected when a session is started. - - - - - This will be made private; use - - - - - This will be made private; use - - - - - Returns a new that wraps , - providing query execution profiling. If profiler is null, no profiling will occur. - - Your provider-specific flavor of connection, e.g. SqlConnection, OracleConnection - The currently started or null. - Determines whether the ProfiledDbConnection will dispose the underlying connection. - - - - The underlying, real database connection to your db provider. - - - - - The current profiler instance; could be null. - - - - - The raw connection this is wrapping - - - - - Wrapper for a db provider factory to enable profiling - - - - - Every provider factory must have an Instance public field - - - - - Used for db provider apis internally - - - - - Allow to re-init the provider factory. - - - - - - - proxy - - - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - Common extension methods to use only in this project - - - - - Answers true if this String is either null or empty. - - - - - Answers true if this String is neither null or empty. - - - - - Removes trailing / characters from a path and leaves just one - - - - - Removes any leading / characters from a path - - - - - Removes any leading / characters from a path - - - - - Serializes to a json string. - - - - - Gets part of a stack trace containing only methods we care about. - - - - - Gets the current formatted and filted stack trace. - - Space separated list of methods - - - - Identifies users based on ip address. - - - - - Provides functionality to identify which user is profiling a request. - - - - - Returns a string to identify the user profiling the current 'request'. - - The current HttpRequest being profiled. - - - - Returns the paramter HttpRequest's client ip address. - - - - - A single MiniProfiler can be used to represent any number of steps/levels in a call-graph, via Step() - - Totally baller. - - - - Starts when this profiler is instantiated. Each step will use this Stopwatch's current ticks as - their starting time. - - - - - Creates and starts a new MiniProfiler for the root , filtering steps to . - - - - - Returns the 's and this profiler recorded. - - - - - Returns true if Ids match. - - - - - Returns hashcode of Id. - - - - - Obsolete - used for serialization. - - - - - Walks the hierarchy contained in this profiler, starting with , and returns each Timing found. - - - - - Returns milliseconds based on Stopwatch's Frequency. - - - - - Starts a new MiniProfiler based on the current . This new profiler can be accessed by - - - - - - Ends the current profiling session, if one exists. - - - When true, clears the for this HttpContext, allowing profiling to - be prematurely stopped and discarded. Useful for when a specific route does not need to be profiled. - - - - - Returns an that will time the code between its creation and disposal. Use this method when you - do not wish to include the MvcMiniProfiler namespace for the extension method. - - A descriptive name for the code that is encapsulated by the resulting IDisposable's lifetime. - This step's visibility level; allows filtering when is called. - - - - Returns the css and javascript includes needed to display the MiniProfiler results UI. - - Which side of the page the profiler popup button should be displayed on (defaults to left) - Whether to show trivial timings by default (defaults to false) - Whether to show time the time with children column by default (defaults to false) - The maximum number of trace popups to show before removing the oldest (defaults to 15) - xhtml rendering mode, ensure script tag is closed ... etc - when true, shows buttons to minimize and clear MiniProfiler results - Script and link elements normally; an empty string when there is no active profiling session. - - - - Renders the current to json. - - - - - Renders the parameter to json. - - - - - Deserializes the json string parameter to a . - - - - - Create a DEEP clone of this object - - - - - - Returns all currently open commands on this connection - - - - - Returns all results contained in all child steps. - - - - - Contains any sql statements that are executed, along with how many times those statements are executed. - - - - - Adds to the current . - - - - - Returns the number of sql statements of that were executed in all s. - - - - - Identifies this Profiler so it may be stored/cached. - - - - - A display name for this profiling session. - - - - - When this profiler was instantiated. - - - - - Where this profiler was run. - - - - - Allows filtering of steps based on what - the steps are created with. - - - - - The first that is created and started when this profiler is instantiated. - All other s will be children of this one. - - - - - A string identifying the user/client that is profiling this request. Set - with an -implementing class to provide a custom value. - - - If this is not set manually at some point, the implementation will be used; - by default, this will be the current request's ip address. - - - - - Returns true when this MiniProfiler has been viewed by the that recorded it. - - - Allows POSTs that result in a redirect to be profiled. implementation - will keep a list of all profilers that haven't been fetched down. - - - - - For unit testing, returns the timer. - - - - - Milliseconds, to one decimal place, that this MiniProfiler ran. - - - - - Returns true when or any of its are . - - - - - Returns true when all child s are . - - - - - Any Timing step with a duration less than or equal to this will be hidden by default in the UI; defaults to 2.0 ms. - - - - - Ticks since this MiniProfiler was started. - - - - - Json representing the collection of CustomTimings relating to this Profiler - - - Is used when storing the Profiler in SqlStorage - - - - - Points to the currently executing Timing. - - - - - Gets the currently running MiniProfiler for the current HttpContext; null if no MiniProfiler was ed. - - - - - Contains information about queries executed during this profiling session. - - - - - Milliseconds, to one decimal place, that this MiniProfiler was executing sql. - - - - - Returns true when we have profiled queries. - - - - - Returns true when any child Timings have duplicate queries. - - - - - How many sql data readers were executed in all steps. - - - - - How many sql scalar queries were executed in all steps. - - - - - How many sql non-query statements were executed in all steps. - - - - - Various configuration properties. - - - - - Excludes the specified assembly from the stack trace output. - - The short name of the assembly. AssemblyName.Name - - - - Excludes the specified type from the stack trace output. - - The System.Type name to exclude - - - - Excludes the specified method name from the stack trace output. - - The name of the method - - - - Make sure we can at least store profiler results to the http runtime cache. - - - - - Assemblies to exclude from the stack trace report. - - - - - Types to exclude from the stack trace report. - - - - - Methods to exclude from the stack trace report. - - - - - The max length of the stack string to report back; defaults to 120 chars. - - - - - Any Timing step with a duration less than or equal to this will be hidden by default in the UI; defaults to 2.0 ms. - - - - - Dictates if the "time with children" column is displayed by default, defaults to false. - For a per-page override you can use .RenderIncludes(showTimeWithChildren: true/false) - - - - - Dictates if trivial timings are displayed by default, defaults to false. - For a per-page override you can use .RenderIncludes(showTrivial: true/false) - - - - - Determines how many traces to show before removing the oldest; defaults to 15. - For a per-page override you can use .RenderIncludes(maxTracesToShow: 10) - - - - - Dictates on which side of the page the profiler popup button is displayed; defaults to left. - For a per-page override you can use .RenderIncludes(position: RenderPosition.Left/Right) - - - - - Determines if min-max, clear, etc are rendered; defaults to false. - For a per-page override you can use .RenderIncludes(showControls: true/false) - - - - - By default, SqlTimings will grab a stack trace to help locate where queries are being executed. - When this setting is true, no stack trace will be collected, possibly improving profiler performance. - - - - - When is called, if the current request url contains any items in this property, - no profiler will be instantiated and no results will be displayed. - Default value is { "/ssr-", "/content/", "/scripts/", "/favicon.ico" }. - - - - - The path under which ALL routes are registered in, defaults to the application root. For example, "~/myDirectory/" would yield - "/myDirectory/ssr-includes.js" rather than just "/mini-profiler-includes.js" - Any setting here should be in APP RELATIVE FORM, e.g. "~/myDirectory/" - - - - - Understands how to save and load MiniProfilers. Used for caching between when - a profiling session ends and results can be fetched to the client, and for showing shared, full-page results. - - - The normal profiling session life-cycle is as follows: - 1) request begins - 2) profiler is started - 3) normal page/controller/request execution - 4) profiler is stopped - 5) profiler is cached with 's implementation of - 6) request ends - 7) page is displayed and profiling results are ajax-fetched down, pulling cached results from - 's implementation of - - - - - The formatter applied to the SQL being rendered (used only for UI) - - - - - Assembly version of this dank MiniProfiler. - - - - - The provider used to provider the current instance of a provider - This is also - - - - - A function that determines who can access the MiniProfiler results url. It should return true when - the request client has access, false for a 401 to be returned. HttpRequest parameter is the current request and - MiniProfiler parameter is the results that were profiled. - - - Both the HttpRequest and MiniProfiler parameters that will be passed into this function should never be null. - - - - - Allows switching out stopwatches for unit testing. - - - - - Categorizes individual steps to allow filtering. - - - - - Default level given to Timings. - - - - - Useful when profiling many items in a loop, but you don't wish to always see this detail. - - - - - Dictates on which side of the page the profiler popup button is displayed; defaults to left. - - - - - Profiler popup button is displayed on the left. - - - - - Profiler popup button is displayed on the right. - - - - - Contains helper methods that ease working with null s. - - - - - Wraps in a call and executes it, returning its result. - - The current profiling session or null. - Method to execute and profile. - The step name used to label the profiler results. - - - - - Returns an that will time the code between its creation and disposal. - - The current profiling session or null. - A descriptive name for the code that is encapsulated by the resulting IDisposable's lifetime. - This step's visibility level; allows filtering when is called. - - - - Adds 's hierarchy to this profiler's current Timing step, - allowing other threads, remote calls, etc. to be profiled and joined into this profiling session. - - - - - Returns an html-encoded string with a text-representation of ; returns "" when profiler is null. - - The current profiling session or null. - - - - Formats any SQL query with inline parameters, optionally including the value type - - - - - Takes a SqlTiming and returns a formatted SQL string, for parameter replacement, etc. - - - - - Return SQL the way you want it to look on the in the trace. Usually used to format parameters - - - Formatted SQL - - - - Creates a new Inline SQL Formatter, optionally including the parameter type info in comments beside the replaced value - - whether to include a comment after the value, indicating the type, e.g. /* @myParam DbType.Int32 */ - - - - Formats the SQL in a generic frieldly format, including the parameter type information in a comment if it was specified in the InlineFormatter constructor - - The SqlTiming to format - A formatted SQL string - - - - Returns a string representation of the parameter's value, including the type - - The parameter to get a value for - - - - - NOT IMPLEMENTED - will format statements with paramters in an Oracle friendly way - - - - - Does NOTHING, implement me! - - - - - Formats SQL server queries with a DECLARE up top for parameter values - - - - - Formats the SQL in a SQL-Server friendly way, with DECLARE statements for the parameters up top. - - The SqlTiming to format - A formatted SQL string - - - - Contains helper code to time sql statements. - - - - - Returns a new SqlProfiler to be used in the 'profiler' session. - - - - - Tracks when 'command' is started. - - - - - Returns all currently open commands on this connection - - - - - Finishes profiling for 'command', recording durations. - - - - - Called when 'reader' finishes its iterations and is closed. - - - - - The profiling session this SqlProfiler is part of. - - - - - Helper methods that allow operation on SqlProfilers, regardless of their instantiation. - - - - - Tracks when 'command' is started. - - - - - Finishes profiling for 'command', recording durations. - - - - - Called when 'reader' finishes its iterations and is closed. - - - - - Profiles a single sql execution. - - - - - Creates a new SqlTiming to profile 'command'. - - - - - Obsolete - used for serialization. - - - - - Returns a snippet of the sql command and the duration. - - - - - Returns true if Ids match. - - - - - Returns hashcode of Id. - - - - - Called when command execution is finished to determine this SqlTiming's duration. - - - - - Called when database reader is closed, ending profiling for SqlTimings. - - - - - To help with display, put some space around sammiched commas - - - - - Unique identifier for this SqlTiming. - - - - - Category of sql statement executed. - - - - - The sql that was executed. - - - - - The command string with special formatting applied based on MiniProfiler.Settings.SqlFormatter - - - - - Roughly where in the calling code that this sql was executed. - - - - - Offset from main MiniProfiler start that this sql began. - - - - - How long this sql statement took to execute. - - - - - When executing readers, how long it took to come back initially from the database, - before all records are fetched and reader is closed. - - - - - Stores any parameter names and values used by the profiled DbCommand. - - - - - Id of the Timing this statement was executed in. - - - Needed for database deserialization. - - - - - The Timing step that this sql execution occurred in. - - - - - True when other identical sql statements have been executed during this MiniProfiler session. - - - - - Information about a DbParameter used in the sql statement profiled by SqlTiming. - - - - - Returns true if this has the same parent , and as . - - - - - Returns the XOR of certain properties. - - - - - Which SqlTiming this Parameter was executed with. - - - - - Parameter name, e.g. "@routeName" - - - - - The value submitted to the database. - - - - - System.Data.DbType, e.g. "String", "Bit" - - - - - How large the type is, e.g. for string, size could be 4000 - - - - - Understands how to save MiniProfiler results to a MSSQL database, allowing more permanent storage and - querying of slow results. - - - - - Provides saving and loading s to a storage medium. - - - - - Stores under its . - - The results of a profiling session. - - Should also ensure the profiler is stored as being unviewed by its profiling . - - - - - Returns a from storage based on , which should map to . - - - Should also update that the resulting profiler has been marked as viewed by its profiling . - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Returns a new SqlServerDatabaseStorage object that will insert into the database identified by connectionString. - - - - - Saves 'profiler' to a database under its . - - - - - Returns the MiniProfiler identified by 'id' from the database or null when no MiniProfiler exists under that 'id'. - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Returns a DbConnection for your specific provider. - - - - - Returns a DbConnection already opened for execution. - - - - - How we connect to the database used to save/load MiniProfiler results. - - - - - Understands how to store a to the with absolute expiration. - - - - - The string that prefixes all keys that MiniProfilers are saved under, e.g. - "mini-profiler-ecfb0050-7ce8-4bf1-bf82-2cb38e90e31e". - - - - - Returns a new HttpRuntimeCacheStorage class that will cache MiniProfilers for the specified duration. - - - - - Saves to the HttpRuntime.Cache under a key concated with - and the parameter's . - - - - - Returns the saved identified by . Also marks the resulting - profiler to true. - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Syncs access to runtime cache when adding a new list of ids for a user. - - - - - How long to cache each for (i.e. the absolute expiration parameter of - ) - - - - - An individual profiling step that can contain child steps. - - - - - Rebuilds all the parent timings on deserialization calls - - - - - Offset from parent MiniProfiler's creation that this Timing was created. - - - - - Creates a new Timing named 'name' in the 'profiler's session, with 'parent' as this Timing's immediate ancestor. - - - - - Obsolete - used for serialization. - - - - - Returns this Timing's Name. - - - - - Returns true if Ids match. - - - - - Returns hashcode of Id. - - - - - Adds arbitrary string 'value' under 'key', allowing custom properties to be stored in this Timing step. - - - - - Completes this Timing's duration and sets the MiniProfiler's Head up one level. - - - - - Add the parameter 'timing' to this Timing's Children collection. - - - Used outside this assembly for custom deserialization when creating an implementation. - - - - - Adds the parameter 'sqlTiming' to this Timing's SqlTimings collection. - - A sql statement profiling that was executed in this Timing step. - - Used outside this assembly for custom deserialization when creating an implementation. - - - - - Returns the number of sql statements of that were executed in this . - - - - - Unique identifer for this timing; set during construction. - - - - - Text displayed when this Timing is rendered. - - - - - How long this Timing step took in ms; includes any Timings' durations. - - - - - The offset from the start of profiling. - - - - - All sub-steps that occur within this Timing step. Add new children through - - - - - Stores arbitrary key/value strings on this Timing step. Add new tuples through . - - - - - Any queries that occurred during this Timing step. - - - - - Needed for database deserialization and JSON serialization. - - - - - Which Timing this Timing is under - the duration that this step takes will be added to its parent's duration. - - This will be null for the root (initial) Timing. - - - - Gets the elapsed milliseconds in this step without any children's durations. - - - - - Gets the aggregate elapsed milliseconds of all SqlTimings executed in this Timing, excluding Children Timings. - - - - - Returns true when this is less than the configured - , by default 2.0 ms. - - - - - Reference to the containing profiler, allowing this Timing to affect the Head and get Stopwatch readings. - - - - - Returns true when this Timing has inner Timing steps. - - - - - Returns true if this Timing step collected sql execution timings. - - - - - Returns true if any s executed in this step are detected as duplicate statements. - - - - - Returns true when this Timing is the first one created in a MiniProfiler session. - - - - - How far away this Timing is from the Profiler's Root. - - - - - How many sql data readers were executed in this Timing step. Does not include queries in any child Timings. - - - - - How many sql scalar queries were executed in this Timing step. Does not include queries in any child Timings. - - - - - How many sql non-query statements were executed in this Timing step. Does not include queries in any child Timings. - - - - - Understands how to route and respond to MiniProfiler UI urls. - - - - - Returns either includes' css/javascript or results' html. - - - - - Handles rendering static content files. - - - - - Handles rendering a previous MiniProfiler session, identified by its "?id=GUID" on the query. - - - - - Embedded resource contents keyed by filename. - - - - - Helper method that sets a proper 404 response code. - - - - - Try to keep everything static so we can easily be reused. - - - - - HttpContext based profiler provider. This is the default provider to use in a web context. - The current profiler is associated with a HttpContext.Current ensuring that profilers are - specific to a individual HttpRequest. - - - - - Public constructor. This also registers any UI routes needed to display results - - - - - Starts a new MiniProfiler and associates it with the current . - - - - - Ends the current profiling session, if one exists. - - - When true, clears the for this HttpContext, allowing profiling to - be prematurely stopped and discarded. Useful for when a specific route does not need to be profiled. - - - - - Makes sure 'profiler' has a Name, pulling it from route data or url. - - - - - Returns the current profiler - - - - - - Gets the currently running MiniProfiler for the current HttpContext; null if no MiniProfiler was ed. - - - - - WebRequestProfilerProvider specific configurations - - - - - Provides user identification for a given profiling request. - - - - - Indicates that the request dto, which is associated with this attribute, - can only execute, if the user has specific permissions. - - - - - Indicates that the request dto, which is associated with this attribute, - can only execute, if the user has specific roles. - - - - - Check all session is in all supplied roles otherwise a 401 HttpError is thrown - - - - - - - Indicates that the request dto, which is associated with this attribute, - can only execute, if the user has specific permissions. - - - - - Indicates that the request dto, which is associated with this attribute, - can only execute, if the user has any of the specified roles. - - - - - Check all session is in any supplied roles otherwise a 401 HttpError is thrown - - - - - - - Base class to create response filter attributes only for specific HTTP methods (GET, POST...) - - - - - Creates a new - - Defines when the filter should be executed - - - - This method is only executed if the HTTP method matches the property. - - The http request wrapper - The http response wrapper - The response DTO - - - - Create a ShallowCopy of this instance. - - - - - - If they don't have an ICacheClient configured use an In Memory one. - - - - - Creates instance using straight Resolve approach. - This will throw an exception if resolution fails - - - - - Creates instance using the TryResolve approach if tryResolve = true. - Otherwise uses Resolve approach, which will throw an exception if resolution fails - - - - - Sets a persistent cookie which never expires - - - - - Sets a session cookie which expires after the browser session closes - - - - - Deletes a specified cookie by setting its value to empty and expiration to -1 days - - - - - Lets you Register new Services and the optional restPaths will be registered against - this default Request Type - - - - - Naming convention for the ResponseStatus property name on the response DTO - - - - - Create an instance of the service response dto type and inject it with the supplied responseStatus - - - - - - - - - - - - - - - - - Override to provide additional/less context about the Service Exception. - By default the request is serialized and appended to the ResponseStatus StackTrace. - - - - - Scans the supplied Assemblies to infer REST paths and HTTP verbs. - - The instance. - - The assemblies with REST services. - - The same instance; - never . - - - - Configure ServiceStack to have ISession support - - - - - Create the active Session or Permanent Session Id cookie. - - - - - - Create both Permanent and Session Id cookies and return the active sessionId - - - - - - This class interecepts 401 requests and changes them to 402 errors. When this happens the FormAuthentication module - will no longer hijack it and redirect back to login because it is a 402 error, not a 401. - When the request ends, this class sets the status code back to 401 and everything works as it should. - - PathToSupress is the path inside your website where the above swap should happen. - - If you can build for .net 4.5, you do not have to do this swap. You can take advantage of a new flag (SuppressFormsAuthenticationRedirect) - that tells the FormAuthenticationModule to not redirect, which also means you will not need the EndRequest code. - - - - - Converts the validation result to an error result which will be serialized by ServiceStack in a clean and human-readable way. - - The validation result - - - - - Converts the validation result to an error exception which will be serialized by ServiceStack in a clean and human-readable way - if the returned exception is thrown. - - The validation result - - - - - Creates a new instance of the RulesetValidatorSelector. - - - - - Determines whether or not a rule should execute. - - The rule - Property path (eg Customer.Address.Line1) - Contextual information - Whether or not the validator can execute. - - - - Activate the validation mechanism, so every request DTO with an existing validator - will be validated. - - The app host - - - - Override to provide additional/less context about the Service Exception. - By default the request is serialized and appended to the ResponseStatus StackTrace. - - - - - Auto-scans the provided assemblies for a - and registers it in the provided IoC container. - - The IoC container - The assemblies to scan for a validator - - - - In Memory repository for files. Useful for testing. - - - - - Context to capture IService action - - - - - Get an IAppHost container. - Note: Registering dependencies should only be done during setup/configuration - stage and remain immutable there after for thread-safety. - - - - - - - Ensure the same instance is used for subclasses - - - - - Called before page is executed - - - - - Called after page is executed but before it's merged with the - website template if any. - - - - - Don't HTML encode safe output - - - - - - - Return the output of a different view with the specified name - using the supplied model - - - - - - - - Resolve registered Assemblies - - - - - - Reference to MarkdownViewEngine - - - - - The AppHost so you can access configuration and resolve dependencies, etc. - - - - - This precompiled Markdown page with Metadata - - - - - ASP.NET MVC's HtmlHelper - - - - - All variables passed to and created by your page. - The Response DTO is stored and accessible via the 'Model' variable. - - All variables and outputs created are stored in ScopeArgs which is what's available - to your website template. The Generated page is stored in the 'Body' variable. - - - - - Whether HTML or Markdown output is requested - - - - - The Response DTO - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to Container service is built-in and read-only.. - - - - - Looks up a localized string similar to Service type {0} does not inherit or implement {1}.. - - - - - Looks up a localized string similar to Required dependency of type {0} named '{1}' could not be resolved.. - - - - - Looks up a localized string similar to Required dependency of type {0} could not be resolved.. - - - - - Looks up a localized string similar to Unknown scope.. - - - - - Gets string value from Items[name] then Cookies[name] if exists. - Useful when *first* setting the users response cookie in the request filter. - To access the value for this initial request you need to set it in Items[]. - - string value or null if it doesn't exist - - - - Gets request paramater string value by looking in the following order: - - QueryString[name] - - FormData[name] - - Cookies[name] - - Items[name] - - string value or null if it doesn't exist - - - * - Input: http://localhost:96/Cambia3/Temp/Test.aspx/path/info?q=item#fragment - - Some HttpRequest path and URL properties: - Request.ApplicationPath: /Cambia3 - Request.CurrentExecutionFilePath: /Cambia3/Temp/Test.aspx - Request.FilePath: /Cambia3/Temp/Test.aspx - Request.Path: /Cambia3/Temp/Test.aspx/path/info - Request.PathInfo: /path/info - Request.PhysicalApplicationPath: D:\Inetpub\wwwroot\CambiaWeb\Cambia3\ - Request.QueryString: /Cambia3/Temp/Test.aspx/path/info?query=arg - Request.Url.AbsolutePath: /Cambia3/Temp/Test.aspx/path/info - Request.Url.AbsoluteUri: http://localhost:96/Cambia3/Temp/Test.aspx/path/info?query=arg - Request.Url.Fragment: - Request.Url.Host: localhost - Request.Url.LocalPath: /Cambia3/Temp/Test.aspx/path/info - Request.Url.PathAndQuery: /Cambia3/Temp/Test.aspx/path/info?query=arg - Request.Url.Port: 96 - Request.Url.Query: ?query=arg - Request.Url.Scheme: http - Request.Url.Segments: / - Cambia3/ - Temp/ - Test.aspx/ - path/ - info - * - - - - Use this to treat Request.Items[] as a cache by returning pre-computed items to save - calculating them multiple times. - - - - - Sets a persistent cookie which never expires - - - - - Sets a session cookie which expires after the browser session closes - - - - - Sets a persistent cookie which expires after the given time - - - - - Sets a persistent cookie with an expiresAt date - - - - - Deletes a specified cookie by setting its value to empty and expiration to -1 days - - - - - Returns the optimized result for the IRequestContext. - Does not use or store results in any cache. - - - - - - - - Overload for the method returning the most - optimized result based on the MimeType and CompressionType from the IRequestContext. - - - - - Overload for the method returning the most - optimized result based on the MimeType and CompressionType from the IRequestContext. - How long to cache for, null is no expiration - - - - - Clears all the serialized and compressed caches set - by the 'Resolve' method for the cacheKey provided - - - - - - - - Store an entry in the IHttpRequest.Items Dictionary - - - - - Get an entry from the IHttpRequest.Items Dictionary - - - - - For performance withPathInfoParts should already be a lower case string - to minimize redundant matching operations. - - - - - - - - For performance withPathInfoParts should already be a lower case string - to minimize redundant matching operations. - - - - - - - - - The number of segments separated by '/' determinable by path.Split('/').Length - e.g. /path/to/here.ext == 3 - - - - - The total number of segments after subparts have been exploded ('.') - e.g. /path/to/here.ext == 4 - - - - - Provide for quick lookups based on hashes that can be determined from a request url - - - - - Execute MQ - - - - - Execute MQ with requestContext - - - - - Execute using empty RequestContext - - - - - Execute HTTP - - - - - Gets the name of the base most type in the heirachy tree with the same. - - We get an exception when trying to create a schema with multiple types of the same name - like when inheriting from a DataContract with the same name. - - The type. - - - - - Inherit from this class if you want to host your web services inside an - ASP.NET application. - - - - - Exécute les tâches définies par l'application associées à la libération ou à la redéfinition des ressources non managées. - - 2 - - - - Load Embedded Resource Templates in ServiceStack. - To get ServiceStack to use your own instead just add a copy of one or more of the following to your Web Root: - ~/Templates/IndexOperations.html - ~/Templates/OperationControl.html - ~/Templates/HtmlFormat.html - - - - - when true, (most) bare plain URLs are auto-hyperlinked - WARNING: this is a significant deviation from the markdown spec - - - - - when true, RETURN becomes a literal newline - WARNING: this is a significant deviation from the markdown spec - - - - - use ">" for HTML output, or " />" for XHTML output - - - - - when true, problematic URL characters like [, ], (, and so forth will be encoded - WARNING: this is a significant deviation from the markdown spec - - - - - when false, email addresses will never be auto-linked - WARNING: this is a significant deviation from the markdown spec - - - - - when true, bold and italic require non-word characters on either side - WARNING: this is a significant deviation from the markdown spec - - - - - Markdown is a text-to-HTML conversion tool for web writers. - Markdown allows you to write using an easy-to-read, easy-to-write plain text format, - then convert it to structurally valid XHTML (or HTML). - - - - - Tabs are automatically converted to spaces as part of the transform - this constant determines how "wide" those tabs become in spaces - - - - - Create a new Markdown instance using default options - - - - - Create a new Markdown instance and optionally load options from a configuration - file. There they should be stored in the appSettings section, available options are: - - Markdown.StrictBoldItalic (true/false) - Markdown.EmptyElementSuffix (">" or " />" without the quotes) - Markdown.LinkEmails (true/false) - Markdown.AutoNewLines (true/false) - Markdown.AutoHyperlink (true/false) - Markdown.EncodeProblemUrlCharacters (true/false) - - - - - - Create a new Markdown instance and set the options from the MarkdownOptions object. - - - - - maximum nested depth of [] and () supported by the transform; implementation detail - - - - - In the static constuctor we'll initialize what stays the same across all transforms. - - - - - Transforms the provided Markdown-formatted text to HTML; - see http://en.wikipedia.org/wiki/Markdown - - - The order in which other subs are called here is - essential. Link and image substitutions need to happen before - EscapeSpecialChars(), so that any *'s or _'s in the a - and img tags get encoded. - - - - - Perform transformations that form block-level tags like paragraphs, headers, and list items. - - - - - Perform transformations that occur *within* block-level tags like paragraphs, headers, and list items. - - - - - splits on two or more newlines, to form "paragraphs"; - each paragraph is then unhashed (if it is a hash and unhashing isn't turned off) or wrapped in HTML p tag - - - - - Reusable pattern to match balanced [brackets]. See Friedl's - "Mastering Regular Expressions", 2nd Ed., pp. 328-331. - - - - - Reusable pattern to match balanced (parens). See Friedl's - "Mastering Regular Expressions", 2nd Ed., pp. 328-331. - - - - - Strips link definitions from text, stores the URLs and titles in hash references. - - - ^[id]: url "optional title" - - - - - derived pretty much verbatim from PHP Markdown - - - - - replaces any block-level HTML blocks with hash entries - - - - - returns an array of HTML tokens comprising the input string. Each token is - either a tag (possibly with nested, tags contained therein, such - as <a href="<MTFoo>">, or a run of text between tags. Each element of the - array is a two-element array; the first is either 'tag' or 'text'; the second is - the actual value. - - - - - Turn Markdown link shortcuts into HTML anchor tags - - - [link text](url "title") - [link text][id] - [id] - - - - - Turn Markdown image shortcuts into HTML img tags. - - - ![alt text][id] - ![alt text](url "optional title") - - - - - Turn Markdown headers into HTML header tags - - - Header 1 - ======== - - Header 2 - -------- - - # Header 1 - ## Header 2 - ## Header 2 with closing hashes ## - ... - ###### Header 6 - - - - - Turn Markdown horizontal rules into HTML hr tags - - - *** - * * * - --- - - - - - - - - - Turn Markdown lists into HTML ul and ol and li tags - - - - - Process the contents of a single ordered or unordered list, splitting it - into individual list items. - - - - - /// Turn Markdown 4-space indented code into HTML pre code blocks - - - - - Turn Markdown `code spans` into HTML code tags - - - - - Turn Markdown *italics* and **bold** into HTML strong and em tags - - - - - Turn markdown line breaks (two space at end of line) into HTML break tags - - - - - Turn Markdown > quoted blocks into HTML blockquote blocks - - - - - Turn angle-delimited URLs into HTML anchor tags - - - <http://www.example.com> - - - - - Remove one level of line-leading spaces - - - - - encodes email address randomly - roughly 10% raw, 45% hex, 45% dec - note that @ is always encoded and : never is - - - - - Encode/escape certain Markdown characters inside code blocks and spans where they are literals - - - - - Encode any ampersands (that aren't part of an HTML entity) and left or right angle brackets - - - - - Encodes any escaped characters such as \`, \*, \[ etc - - - - - swap back in all the special characters we've hidden - - - - - escapes Bold [ * ] and Italic [ _ ] characters - - - - - hex-encodes some unusual "problem" chars in URLs to avoid URL detection problems - - - - - Within tags -- meaning between < and > -- encode [\ ` * _] so they - don't conflict with their use in Markdown for code, italics and strong. - We're replacing each such character with its corresponding hash - value; this is likely overkill, but it should prevent us from colliding - with the escape values by accident. - - - - - convert all tabs to _tabWidth spaces; - standardizes line endings from DOS (CR LF) or Mac (CR) to UNIX (LF); - makes sure text ends with a couple of newlines; - removes any blank lines (only spaces) in the text - - - - - this is to emulate what's evailable in PHP - - - - - use ">" for HTML output, or " />" for XHTML output - - - - - when false, email addresses will never be auto-linked - WARNING: this is a significant deviation from the markdown spec - - - - - when true, bold and italic require non-word characters on either side - WARNING: this is a significant deviation from the markdown spec - - - - - when true, RETURN becomes a literal newline - WARNING: this is a significant deviation from the markdown spec - - - - - when true, (most) bare plain URLs are auto-hyperlinked - WARNING: this is a significant deviation from the markdown spec - - - - - when true, problematic URL characters like [, ], (, and so forth will be encoded - WARNING: this is a significant deviation from the markdown spec - - - - - current version of MarkdownSharp; - see http://code.google.com/p/markdownsharp/ for the latest code or to contribute - - - - - Render Markdown for text/markdown and text/plain ContentTypes - - - - - Used in Unit tests - - - - - - Non ASP.NET requests - - - - - - - - ASP.NET requests - - - - - - Writes to response. - Response headers are customizable by implementing IHasOptions an returning Dictionary of Http headers. - - The response. - Whether or not it was implicity handled by ServiceStack's built-in handlers. - The default action. - The serialization context. - Add prefix to response body if any - Add suffix to response body if any - - - - - Highly optimized code to find if GZIP is supported from: - - http://dotnetperls.com/gzip-request - - Other resources for GZip, deflate resources: - - http://www.west-wind.com/Weblog/posts/10564.aspx - - http://www.west-wind.com/WebLog/posts/102969.aspx - - ICSharpCode - - - - - Changes the links for the servicestack/metadata page - - - - - Non ASP.NET requests - - - - - ASP.NET requests - - - - - Keep default file contents in-memory - - - - - - Call to signal the completion of a ServiceStack-handled Request - - - - - Resolves and auto-wires a ServiceStack Service from a ASP.NET HttpContext. - - - - - Resolves and auto-wires a ServiceStack Service from a HttpListenerContext. - - - - - Resolves and auto-wires a ServiceStack Service. - - - - diff --git a/lib/tests/nunit.framework.dll b/lib/tests/nunit.framework.dll deleted file mode 100644 index 215767d2f..000000000 Binary files a/lib/tests/nunit.framework.dll and /dev/null differ diff --git a/lib/tests/nunit.framework.xml b/lib/tests/nunit.framework.xml deleted file mode 100644 index 7b0e798ca..000000000 --- a/lib/tests/nunit.framework.xml +++ /dev/null @@ -1,10892 +0,0 @@ - - - - nunit.framework - - - - - Attribute used to apply a category to a test - - - - - The name of the category - - - - - Construct attribute for a given category based on - a name. The name may not contain the characters ',', - '+', '-' or '!'. However, this is not checked in the - constructor since it would cause an error to arise at - as the test was loaded without giving a clear indication - of where the problem is located. The error is handled - in NUnitFramework.cs by marking the test as not - runnable. - - The name of the category - - - - Protected constructor uses the Type name as the name - of the category. - - - - - The name of the category - - - - - Used to mark a field for use as a datapoint when executing a theory - within the same fixture that requires an argument of the field's Type. - - - - - Used to mark an array as containing a set of datapoints to be used - executing a theory within the same fixture that requires an argument - of the Type of the array elements. - - - - - Attribute used to provide descriptive text about a - test case or fixture. - - - - - Construct the attribute - - Text describing the test - - - - Gets the test description - - - - - Enumeration indicating how the expected message parameter is to be used - - - - Expect an exact match - - - Expect a message containing the parameter string - - - Match the regular expression provided as a parameter - - - Expect a message that starts with the parameter string - - - - ExpectedExceptionAttribute - - - - - - Constructor for a non-specific exception - - - - - Constructor for a given type of exception - - The type of the expected exception - - - - Constructor for a given exception name - - The full name of the expected exception - - - - Gets or sets the expected exception type - - - - - Gets or sets the full Type name of the expected exception - - - - - Gets or sets the expected message text - - - - - Gets or sets the user message displayed in case of failure - - - - - Gets or sets the type of match to be performed on the expected message - - - - - Gets the name of a method to be used as an exception handler - - - - - ExplicitAttribute marks a test or test fixture so that it will - only be run if explicitly executed from the gui or command line - or if it is included by use of a filter. The test will not be - run simply because an enclosing suite is run. - - - - - Default constructor - - - - - Constructor with a reason - - The reason test is marked explicit - - - - The reason test is marked explicit - - - - - Attribute used to mark a test that is to be ignored. - Ignored tests result in a warning message when the - tests are run. - - - - - Constructs the attribute without giving a reason - for ignoring the test. - - - - - Constructs the attribute giving a reason for ignoring the test - - The reason for ignoring the test - - - - The reason for ignoring a test - - - - - Abstract base for Attributes that are used to include tests - in the test run based on environmental settings. - - - - - Constructor with no included items specified, for use - with named property syntax. - - - - - Constructor taking one or more included items - - Comma-delimited list of included items - - - - Name of the item that is needed in order for - a test to run. Multiple itemss may be given, - separated by a comma. - - - - - Name of the item to be excluded. Multiple items - may be given, separated by a comma. - - - - - The reason for including or excluding the test - - - - - PlatformAttribute is used to mark a test fixture or an - individual method as applying to a particular platform only. - - - - - Constructor with no platforms specified, for use - with named property syntax. - - - - - Constructor taking one or more platforms - - Comma-deliminted list of platforms - - - - CultureAttribute is used to mark a test fixture or an - individual method as applying to a particular Culture only. - - - - - Constructor with no cultures specified, for use - with named property syntax. - - - - - Constructor taking one or more cultures - - Comma-deliminted list of cultures - - - - Marks a test to use a combinatorial join of any argument data - provided. NUnit will create a test case for every combination of - the arguments provided. This can result in a large number of test - cases and so should be used judiciously. This is the default join - type, so the attribute need not be used except as documentation. - - - - - PropertyAttribute is used to attach information to a test as a name/value pair.. - - - - - Construct a PropertyAttribute with a name and string value - - The name of the property - The property value - - - - Construct a PropertyAttribute with a name and int value - - The name of the property - The property value - - - - Construct a PropertyAttribute with a name and double value - - The name of the property - The property value - - - - Constructor for derived classes that set the - property dictionary directly. - - - - - Constructor for use by derived classes that use the - name of the type as the property name. Derived classes - must ensure that the Type of the property value is - a standard type supported by the BCL. Any custom - types will cause a serialization Exception when - in the client. - - - - - Gets the property dictionary for this attribute - - - - - Default constructor - - - - - Marks a test to use pairwise join of any argument data provided. - NUnit will attempt too excercise every pair of argument values at - least once, using as small a number of test cases as it can. With - only two arguments, this is the same as a combinatorial join. - - - - - Default constructor - - - - - Marks a test to use a sequential join of any argument data - provided. NUnit will use arguements for each parameter in - sequence, generating test cases up to the largest number - of argument values provided and using null for any arguments - for which it runs out of values. Normally, this should be - used with the same number of arguments for each parameter. - - - - - Default constructor - - - - - Summary description for MaxTimeAttribute. - - - - - Construct a MaxTimeAttribute, given a time in milliseconds. - - The maximum elapsed time in milliseconds - - - - RandomAttribute is used to supply a set of random values - to a single parameter of a parameterized test. - - - - - ValuesAttribute is used to provide literal arguments for - an individual parameter of a test. - - - - - Abstract base class for attributes that apply to parameters - and supply data for the parameter. - - - - - Gets the data to be provided to the specified parameter - - - - - The collection of data to be returned. Must - be set by any derived attribute classes. - We use an object[] so that the individual - elements may have their type changed in GetData - if necessary. - - - - - Construct with one argument - - - - - - Construct with two arguments - - - - - - - Construct with three arguments - - - - - - - - Construct with an array of arguments - - - - - - Get the collection of values to be used as arguments - - - - - Construct a set of doubles from 0.0 to 1.0, - specifying only the count. - - - - - - Construct a set of doubles from min to max - - - - - - - - Construct a set of ints from min to max - - - - - - - - Get the collection of values to be used as arguments - - - - - RangeAttribute is used to supply a range of values to an - individual parameter of a parameterized test. - - - - - Construct a range of ints using default step of 1 - - - - - - - Construct a range of ints specifying the step size - - - - - - - - Construct a range of longs - - - - - - - - Construct a range of doubles - - - - - - - - Construct a range of floats - - - - - - - - RepeatAttribute may be applied to test case in order - to run it multiple times. - - - - - Construct a RepeatAttribute - - The number of times to run the test - - - - RequiredAddinAttribute may be used to indicate the names of any addins - that must be present in order to run some or all of the tests in an - assembly. If the addin is not loaded, the entire assembly is marked - as NotRunnable. - - - - - Initializes a new instance of the class. - - The required addin. - - - - Gets the name of required addin. - - The required addin name. - - - - Summary description for SetCultureAttribute. - - - - - Construct given the name of a culture - - - - - - Summary description for SetUICultureAttribute. - - - - - Construct given the name of a culture - - - - - - SetUpAttribute is used in a TestFixture to identify a method - that is called immediately before each test is run. It is - also used in a SetUpFixture to identify the method that is - called once, before any of the subordinate tests are run. - - - - - Attribute used to mark a class that contains one-time SetUp - and/or TearDown methods that apply to all the tests in a - namespace or an assembly. - - - - - Attribute used to mark a static (shared in VB) property - that returns a list of tests. - - - - - Attribute used in a TestFixture to identify a method that is - called immediately after each test is run. It is also used - in a SetUpFixture to identify the method that is called once, - after all subordinate tests have run. In either case, the method - is guaranteed to be called, even if an exception is thrown. - - - - - Provide actions to execute before and after tests. - - - - - When implemented by an attribute, this interface implemented to provide actions to execute before and after tests. - - - - - Executed before each test is run - - Provides details about the test that is going to be run. - - - - Executed after each test is run - - Provides details about the test that has just been run. - - - - Provides the target for the action attribute - - The target for the action attribute - - - - Adding this attribute to a method within a - class makes the method callable from the NUnit test runner. There is a property - called Description which is optional which you can provide a more detailed test - description. This class cannot be inherited. - - - - [TestFixture] - public class Fixture - { - [Test] - public void MethodToTest() - {} - - [Test(Description = "more detailed description")] - publc void TestDescriptionMethod() - {} - } - - - - - - Descriptive text for this test - - - - - TestCaseAttribute is used to mark parameterized test cases - and provide them with their arguments. - - - - - The ITestCaseData interface is implemented by a class - that is able to return complete testcases for use by - a parameterized test method. - - NOTE: This interface is used in both the framework - and the core, even though that results in two different - types. However, sharing the source code guarantees that - the various implementations will be compatible and that - the core is able to reflect successfully over the - framework implementations of ITestCaseData. - - - - - Gets the argument list to be provided to the test - - - - - Gets the expected result - - - - - Indicates whether a result has been specified. - This is necessary because the result may be - null, so it's value cannot be checked. - - - - - Gets the expected exception Type - - - - - Gets the FullName of the expected exception - - - - - Gets the name to be used for the test - - - - - Gets the description of the test - - - - - Gets a value indicating whether this is ignored. - - true if ignored; otherwise, false. - - - - Gets a value indicating whether this is explicit. - - true if explicit; otherwise, false. - - - - Gets the ignore reason. - - The ignore reason. - - - - Construct a TestCaseAttribute with a list of arguments. - This constructor is not CLS-Compliant - - - - - - Construct a TestCaseAttribute with a single argument - - - - - - Construct a TestCaseAttribute with a two arguments - - - - - - - Construct a TestCaseAttribute with a three arguments - - - - - - - - Gets the list of arguments to a test case - - - - - Gets or sets the expected result. - - The result. - - - - Gets the expected result. - - The result. - - - - Gets a flag indicating whether an expected - result has been set. - - - - - Gets a list of categories associated with this test; - - - - - Gets or sets the category associated with this test. - May be a single category or a comma-separated list. - - - - - Gets or sets the expected exception. - - The expected exception. - - - - Gets or sets the name the expected exception. - - The expected name of the exception. - - - - Gets or sets the expected message of the expected exception - - The expected message of the exception. - - - - Gets or sets the type of match to be performed on the expected message - - - - - Gets or sets the description. - - The description. - - - - Gets or sets the name of the test. - - The name of the test. - - - - Gets or sets the ignored status of the test - - - - - Gets or sets the ignored status of the test - - - - - Gets or sets the explicit status of the test - - - - - Gets or sets the reason for not running the test - - - - - Gets or sets the reason for not running the test. - Set has the side effect of marking the test as ignored. - - The ignore reason. - - - - FactoryAttribute indicates the source to be used to - provide test cases for a test method. - - - - - Construct with the name of the factory - for use with languages - that don't support params arrays. - - An array of the names of the factories that will provide data - - - - Construct with a Type and name - for use with languages - that don't support params arrays. - - The Type that will provide data - The name of the method, property or field that will provide data - - - - The name of a the method, property or fiend to be used as a source - - - - - A Type to be used as a source - - - - - Gets or sets the category associated with this test. - May be a single category or a comma-separated list. - - - - - [TestFixture] - public class ExampleClass - {} - - - - - Default constructor - - - - - Construct with a object[] representing a set of arguments. - In .NET 2.0, the arguments may later be separated into - type arguments and constructor arguments. - - - - - - Descriptive text for this fixture - - - - - Gets and sets the category for this fixture. - May be a comma-separated list of categories. - - - - - Gets a list of categories for this fixture - - - - - The arguments originally provided to the attribute - - - - - Gets or sets a value indicating whether this should be ignored. - - true if ignore; otherwise, false. - - - - Gets or sets the ignore reason. May set Ignored as a side effect. - - The ignore reason. - - - - Get or set the type arguments. If not set - explicitly, any leading arguments that are - Types are taken as type arguments. - - - - - Attribute used to identify a method that is - called before any tests in a fixture are run. - - - - - Attribute used to identify a method that is called after - all the tests in a fixture have run. The method is - guaranteed to be called, even if an exception is thrown. - - - - - Adding this attribute to a method within a - class makes the method callable from the NUnit test runner. There is a property - called Description which is optional which you can provide a more detailed test - description. This class cannot be inherited. - - - - [TestFixture] - public class Fixture - { - [Test] - public void MethodToTest() - {} - - [Test(Description = "more detailed description")] - publc void TestDescriptionMethod() - {} - } - - - - - - Used on a method, marks the test with a timeout value in milliseconds. - The test will be run in a separate thread and is cancelled if the timeout - is exceeded. Used on a method or assembly, sets the default timeout - for all contained test methods. - - - - - Construct a TimeoutAttribute given a time in milliseconds - - The timeout value in milliseconds - - - - Marks a test that must run in the STA, causing it - to run in a separate thread if necessary. - - On methods, you may also use STAThreadAttribute - to serve the same purpose. - - - - - Construct a RequiresSTAAttribute - - - - - Marks a test that must run in the MTA, causing it - to run in a separate thread if necessary. - - On methods, you may also use MTAThreadAttribute - to serve the same purpose. - - - - - Construct a RequiresMTAAttribute - - - - - Marks a test that must run on a separate thread. - - - - - Construct a RequiresThreadAttribute - - - - - Construct a RequiresThreadAttribute, specifying the apartment - - - - - ValueSourceAttribute indicates the source to be used to - provide data for one parameter of a test method. - - - - - Construct with the name of the factory - for use with languages - that don't support params arrays. - - The name of the data source to be used - - - - Construct with a Type and name - for use with languages - that don't support params arrays. - - The Type that will provide data - The name of the method, property or field that will provide data - - - - The name of a the method, property or fiend to be used as a source - - - - - A Type to be used as a source - - - - - AttributeExistsConstraint tests for the presence of a - specified attribute on a Type. - - - - - The Constraint class is the base of all built-in constraints - within NUnit. It provides the operator overloads used to combine - constraints. - - - - - The IConstraintExpression interface is implemented by all - complete and resolvable constraints and expressions. - - - - - Return the top-level constraint for this expression - - - - - - Static UnsetObject used to detect derived constraints - failing to set the actual value. - - - - - The actual value being tested against a constraint - - - - - The display name of this Constraint for use by ToString() - - - - - Argument fields used by ToString(); - - - - - The builder holding this constraint - - - - - Construct a constraint with no arguments - - - - - Construct a constraint with one argument - - - - - Construct a constraint with two arguments - - - - - Sets the ConstraintBuilder holding this constraint - - - - - Write the failure message to the MessageWriter provided - as an argument. The default implementation simply passes - the constraint and the actual value to the writer, which - then displays the constraint description and the value. - - Constraints that need to provide additional details, - such as where the error occured can override this. - - The MessageWriter on which to display the message - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Test whether the constraint is satisfied by an - ActualValueDelegate that returns the value to be tested. - The default implementation simply evaluates the delegate - but derived classes may override it to provide for delayed - processing. - - An ActualValueDelegate - True for success, false for failure - - - - Test whether the constraint is satisfied by a given reference. - The default implementation simply dereferences the value but - derived classes may override it to provide for delayed processing. - - A reference to the value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Default override of ToString returns the constraint DisplayName - followed by any arguments within angle brackets. - - - - - - Returns the string representation of this constraint - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if the - argument constraint is not satisfied. - - - - - Returns a DelayedConstraint with the specified delay time. - - The delay in milliseconds. - - - - - Returns a DelayedConstraint with the specified delay time - and polling interval. - - The delay in milliseconds. - The interval at which to test the constraint. - - - - - The display name of this Constraint for use by ToString(). - The default value is the name of the constraint with - trailing "Constraint" removed. Derived classes may set - this to another name in their constructors. - - - - - Returns a ConstraintExpression by appending And - to the current constraint. - - - - - Returns a ConstraintExpression by appending And - to the current constraint. - - - - - Returns a ConstraintExpression by appending Or - to the current constraint. - - - - - Class used to detect any derived constraints - that fail to set the actual value in their - Matches override. - - - - - Constructs an AttributeExistsConstraint for a specific attribute Type - - - - - - Tests whether the object provides the expected attribute. - - A Type, MethodInfo, or other ICustomAttributeProvider - True if the expected attribute is present, otherwise false - - - - Writes the description of the constraint to the specified writer - - - - - AttributeConstraint tests that a specified attribute is present - on a Type or other provider and that the value of the attribute - satisfies some other constraint. - - - - - Abstract base class used for prefixes - - - - - The base constraint - - - - - Construct given a base constraint - - - - - - Constructs an AttributeConstraint for a specified attriute - Type and base constraint. - - - - - - - Determines whether the Type or other provider has the - expected attribute and if its value matches the - additional constraint specified. - - - - - Writes a description of the attribute to the specified writer. - - - - - Writes the actual value supplied to the specified writer. - - - - - Returns a string representation of the constraint. - - - - - BasicConstraint is the abstract base for constraints that - perform a simple comparison to a constant value. - - - - - Initializes a new instance of the class. - - The expected. - The description. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - NullConstraint tests that the actual value is null - - - - - Initializes a new instance of the class. - - - - - TrueConstraint tests that the actual value is true - - - - - Initializes a new instance of the class. - - - - - FalseConstraint tests that the actual value is false - - - - - Initializes a new instance of the class. - - - - - NaNConstraint tests that the actual value is a double or float NaN - - - - - Test that the actual value is an NaN - - - - - - - Write the constraint description to a specified writer - - - - - - BinaryConstraint is the abstract base of all constraints - that combine two other constraints in some fashion. - - - - - The first constraint being combined - - - - - The second constraint being combined - - - - - Construct a BinaryConstraint from two other constraints - - The first constraint - The second constraint - - - - AndConstraint succeeds only if both members succeed. - - - - - Create an AndConstraint from two other constraints - - The first constraint - The second constraint - - - - Apply both member constraints to an actual value, succeeding - succeeding only if both of them succeed. - - The actual value - True if the constraints both succeeded - - - - Write a description for this contraint to a MessageWriter - - The MessageWriter to receive the description - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - OrConstraint succeeds if either member succeeds - - - - - Create an OrConstraint from two other constraints - - The first constraint - The second constraint - - - - Apply the member constraints to an actual value, succeeding - succeeding as soon as one of them succeeds. - - The actual value - True if either constraint succeeded - - - - Write a description for this contraint to a MessageWriter - - The MessageWriter to receive the description - - - - CollectionConstraint is the abstract base class for - constraints that operate on collections. - - - - - Construct an empty CollectionConstraint - - - - - Construct a CollectionConstraint - - - - - - Determines whether the specified enumerable is empty. - - The enumerable. - - true if the specified enumerable is empty; otherwise, false. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Protected method to be implemented by derived classes - - - - - - - CollectionItemsEqualConstraint is the abstract base class for all - collection constraints that apply some notion of item equality - as a part of their operation. - - - - - Construct an empty CollectionConstraint - - - - - Construct a CollectionConstraint - - - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied Comparison object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Compares two collection members for equality - - - - - Return a new CollectionTally for use in making tests - - The collection to be included in the tally - - - - Flag the constraint to ignore case and return self. - - - - - EmptyCollectionConstraint tests whether a collection is empty. - - - - - Check that the collection is empty - - - - - - - Write the constraint description to a MessageWriter - - - - - - UniqueItemsConstraint tests whether all the items in a - collection are unique. - - - - - Check that all items are unique. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - CollectionContainsConstraint is used to test whether a collection - contains an expected object as a member. - - - - - Construct a CollectionContainsConstraint - - - - - - Test whether the expected item is contained in the collection - - - - - - - Write a descripton of the constraint to a MessageWriter - - - - - - CollectionEquivalentCOnstraint is used to determine whether two - collections are equivalent. - - - - - Construct a CollectionEquivalentConstraint - - - - - - Test whether two collections are equivalent - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - CollectionSubsetConstraint is used to determine whether - one collection is a subset of another - - - - - Construct a CollectionSubsetConstraint - - The collection that the actual value is expected to be a subset of - - - - Test whether the actual collection is a subset of - the expected collection provided. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - CollectionOrderedConstraint is used to test whether a collection is ordered. - - - - - Construct a CollectionOrderedConstraint - - - - - Modifies the constraint to use an IComparer and returns self. - - - - - Modifies the constraint to use an IComparer<T> and returns self. - - - - - Modifies the constraint to use a Comparison<T> and returns self. - - - - - Modifies the constraint to test ordering by the value of - a specified property and returns self. - - - - - Test whether the collection is ordered - - - - - - - Write a description of the constraint to a MessageWriter - - - - - - Returns the string representation of the constraint. - - - - - - If used performs a reverse comparison - - - - - CollectionTally counts (tallies) the number of - occurences of each object in one or more enumerations. - - - - - Construct a CollectionTally object from a comparer and a collection - - - - - Try to remove an object from the tally - - The object to remove - True if successful, false if the object was not found - - - - Try to remove a set of objects from the tally - - The objects to remove - True if successful, false if any object was not found - - - - The number of objects remaining in the tally - - - - - ComparisonAdapter class centralizes all comparisons of - values in NUnit, adapting to the use of any provided - IComparer, IComparer<T> or Comparison<T> - - - - - Returns a ComparisonAdapter that wraps an IComparer - - - - - Returns a ComparisonAdapter that wraps an IComparer<T> - - - - - Returns a ComparisonAdapter that wraps a Comparison<T> - - - - - Compares two objects - - - - - Gets the default ComparisonAdapter, which wraps an - NUnitComparer object. - - - - - Construct a ComparisonAdapter for an IComparer - - - - - Compares two objects - - - - - - - - Construct a default ComparisonAdapter - - - - - ComparisonAdapter<T> extends ComparisonAdapter and - allows use of an IComparer<T> or Comparison<T> - to actually perform the comparison. - - - - - Construct a ComparisonAdapter for an IComparer<T> - - - - - Compare a Type T to an object - - - - - Construct a ComparisonAdapter for a Comparison<T> - - - - - Compare a Type T to an object - - - - - Abstract base class for constraints that compare values to - determine if one is greater than, equal to or less than - the other. This class supplies the Using modifiers. - - - - - ComparisonAdapter to be used in making the comparison - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - - - Modifies the constraint to use an IComparer and returns self - - - - - Modifies the constraint to use an IComparer<T> and returns self - - - - - Modifies the constraint to use a Comparison<T> and returns self - - - - - Delegate used to delay evaluation of the actual value - to be used in evaluating a constraint - - - - - ConstraintBuilder maintains the stacks that are used in - processing a ConstraintExpression. An OperatorStack - is used to hold operators that are waiting for their - operands to be reognized. a ConstraintStack holds - input constraints as well as the results of each - operator applied. - - - - - Initializes a new instance of the class. - - - - - Appends the specified operator to the expression by first - reducing the operator stack and then pushing the new - operator on the stack. - - The operator to push. - - - - Appends the specified constraint to the expresson by pushing - it on the constraint stack. - - The constraint to push. - - - - Sets the top operator right context. - - The right context. - - - - Reduces the operator stack until the topmost item - precedence is greater than or equal to the target precedence. - - The target precedence. - - - - Resolves this instance, returning a Constraint. If the builder - is not currently in a resolvable state, an exception is thrown. - - The resolved constraint - - - - Gets a value indicating whether this instance is resolvable. - - - true if this instance is resolvable; otherwise, false. - - - - - OperatorStack is a type-safe stack for holding ConstraintOperators - - - - - Initializes a new instance of the class. - - The builder. - - - - Pushes the specified operator onto the stack. - - The op. - - - - Pops the topmost operator from the stack. - - - - - - Gets a value indicating whether this is empty. - - true if empty; otherwise, false. - - - - Gets the topmost operator without modifying the stack. - - The top. - - - - ConstraintStack is a type-safe stack for holding Constraints - - - - - Initializes a new instance of the class. - - The builder. - - - - Pushes the specified constraint. As a side effect, - the constraint's builder field is set to the - ConstraintBuilder owning this stack. - - The constraint. - - - - Pops this topmost constrait from the stack. - As a side effect, the constraint's builder - field is set to null. - - - - - - Gets a value indicating whether this is empty. - - true if empty; otherwise, false. - - - - Gets the topmost constraint without modifying the stack. - - The topmost constraint - - - - ConstraintExpression represents a compound constraint in the - process of being constructed from a series of syntactic elements. - - Individual elements are appended to the expression as they are - reognized. Once an actual Constraint is appended, the expression - returns a resolvable Constraint. - - - - - ConstraintExpressionBase is the abstract base class for the - ConstraintExpression class, which represents a - compound constraint in the process of being constructed - from a series of syntactic elements. - - NOTE: ConstraintExpressionBase is separate because the - ConstraintExpression class was generated in earlier - versions of NUnit. The two classes may be combined - in a future version. - - - - - The ConstraintBuilder holding the elements recognized so far - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the - class passing in a ConstraintBuilder, which may be pre-populated. - - The builder. - - - - Returns a string representation of the expression as it - currently stands. This should only be used for testing, - since it has the side-effect of resolving the expression. - - - - - - Appends an operator to the expression and returns the - resulting expression itself. - - - - - Appends a self-resolving operator to the expression and - returns a new ResolvableConstraintExpression. - - - - - Appends a constraint to the expression and returns that - constraint, which is associated with the current state - of the expression being built. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the - class passing in a ConstraintBuilder, which may be pre-populated. - - The builder. - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding only if a specified number of them succeed. - - - - - Returns a new PropertyConstraintExpression, which will either - test for the existence of the named property on the object - being tested or apply any following constraint to that property. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns the constraint provided as an argument - used to allow custom - custom constraints to easily participate in the syntax. - - - - - Returns the constraint provided as an argument - used to allow custom - custom constraints to easily participate in the syntax. - - - - - Returns a constraint that tests two items for equality - - - - - Returns a constraint that tests that two references are the same object - - - - - Returns a constraint that tests whether the - actual value is greater than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a collection containing the same elements as the - collection supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a subset of the collection supplied as an argument. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new ContainsConstraint. This constraint - will, in turn, make use of the appropriate second-level - constraint, depending on the type of the actual argument. - This overload is only used if the item sought is a string, - since any other type implies that we are looking for a - collection member. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the Regex pattern supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the Regex pattern supplied as an argument. - - - - - Returns a constraint that tests whether the path provided - is the same as an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the actual value falls - within a specified range. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if at least one of them succeeds. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them fail. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Length property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Count property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Message property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the InnerException property of the object being tested. - - - - - With is currently a NOP - reserved for future use. - - - - - Returns a constraint that tests for null - - - - - Returns a constraint that tests for True - - - - - Returns a constraint that tests for False - - - - - Returns a constraint that tests for a positive value - - - - - Returns a constraint that tests for a negative value - - - - - Returns a constraint that tests for NaN - - - - - Returns a constraint that tests for empty - - - - - Returns a constraint that tests whether a collection - contains all unique items. - - - - - Returns a constraint that tests whether an object graph is serializable in binary format. - - - - - Returns a constraint that tests whether an object graph is serializable in xml format. - - - - - Returns a constraint that tests whether a collection is ordered - - - - - Helper class with properties and methods that supply - a number of constraints used in Asserts. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding only if a specified number of them succeed. - - - - - Returns a new PropertyConstraintExpression, which will either - test for the existence of the named property on the object - being tested or apply any following constraint to that property. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a constraint that tests two items for equality - - - - - Returns a constraint that tests that two references are the same object - - - - - Returns a constraint that tests whether the - actual value is greater than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a collection containing the same elements as the - collection supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a subset of the collection supplied as an argument. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new ContainsConstraint. This constraint - will, in turn, make use of the appropriate second-level - constraint, depending on the type of the actual argument. - This overload is only used if the item sought is a string, - since any other type implies that we are looking for a - collection member. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the Regex pattern supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the Regex pattern supplied as an argument. - - - - - Returns a constraint that fails if the actual - value matches the pattern supplied as an argument. - - - - - Returns a constraint that tests whether the path provided - is the same as an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the actual value falls - within a specified range. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if at least one of them succeeds. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them fail. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Length property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Count property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Message property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the InnerException property of the object being tested. - - - - - Returns a constraint that tests for null - - - - - Returns a constraint that tests for True - - - - - Returns a constraint that tests for False - - - - - Returns a constraint that tests for a positive value - - - - - Returns a constraint that tests for a negative value - - - - - Returns a constraint that tests for NaN - - - - - Returns a constraint that tests for empty - - - - - Returns a constraint that tests whether a collection - contains all unique items. - - - - - Returns a constraint that tests whether an object graph is serializable in binary format. - - - - - Returns a constraint that tests whether an object graph is serializable in xml format. - - - - - Returns a constraint that tests whether a collection is ordered - - - - - The ConstraintOperator class is used internally by a - ConstraintBuilder to represent an operator that - modifies or combines constraints. - - Constraint operators use left and right precedence - values to determine whether the top operator on the - stack should be reduced before pushing a new operator. - - - - - The precedence value used when the operator - is about to be pushed to the stack. - - - - - The precedence value used when the operator - is on the top of the stack. - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - The syntax element preceding this operator - - - - - The syntax element folowing this operator - - - - - The precedence value used when the operator - is about to be pushed to the stack. - - - - - The precedence value used when the operator - is on the top of the stack. - - - - - PrefixOperator takes a single constraint and modifies - it's action in some way. - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - Returns the constraint created by applying this - prefix to another constraint. - - - - - - - Negates the test of the constraint it wraps. - - - - - Constructs a new NotOperator - - - - - Returns a NotConstraint applied to its argument. - - - - - Abstract base for operators that indicate how to - apply a constraint to items in a collection. - - - - - Constructs a CollectionOperator - - - - - Represents a constraint that succeeds if all the - members of a collection match a base constraint. - - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - they all succeed. - - - - - Represents a constraint that succeeds if any of the - members of a collection match a base constraint. - - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - any of them succeed. - - - - - Represents a constraint that succeeds if none of the - members of a collection match a base constraint. - - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - none of them succeed. - - - - - Represents a constraint that succeeds if the specified - count of members of a collection match a base constraint. - - - - - Construct an ExactCountOperator for a specified count - - The expected count - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - none of them succeed. - - - - - Represents a constraint that simply wraps the - constraint provided as an argument, without any - further functionality, but which modifes the - order of evaluation because of its precedence. - - - - - Constructor for the WithOperator - - - - - Returns a constraint that wraps its argument - - - - - Abstract base class for operators that are able to reduce to a - constraint whether or not another syntactic element follows. - - - - - Operator used to test for the presence of a named Property - on an object and optionally apply further tests to the - value of that property. - - - - - Constructs a PropOperator for a particular named property - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - Gets the name of the property to which the operator applies - - - - - Operator that tests for the presence of a particular attribute - on a type and optionally applies further tests to the attribute. - - - - - Construct an AttributeOperator for a particular Type - - The Type of attribute tested - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - Operator that tests that an exception is thrown and - optionally applies further tests to the exception. - - - - - Construct a ThrowsOperator - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - Abstract base class for all binary operators - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - Abstract method that produces a constraint by applying - the operator to its left and right constraint arguments. - - - - - Gets the left precedence of the operator - - - - - Gets the right precedence of the operator - - - - - Operator that requires both it's arguments to succeed - - - - - Construct an AndOperator - - - - - Apply the operator to produce an AndConstraint - - - - - Operator that requires at least one of it's arguments to succeed - - - - - Construct an OrOperator - - - - - Apply the operator to produce an OrConstraint - - - - - ContainsConstraint tests a whether a string contains a substring - or a collection contains an object. It postpones the decision of - which test to use until the type of the actual argument is known. - This allows testing whether a string is contained in a collection - or as a substring of another string using the same syntax. - - - - - Initializes a new instance of the class. - - The expected. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied Comparison object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to ignore case and return self. - - - - - Applies a delay to the match so that a match can be evaluated in the future. - - - - - Creates a new DelayedConstraint - - The inner constraint two decorate - The time interval after which the match is performed - If the value of is less than 0 - - - - Creates a new DelayedConstraint - - The inner constraint two decorate - The time interval after which the match is performed - The time interval used for polling - If the value of is less than 0 - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for if the base constraint fails, false if it succeeds - - - - Test whether the constraint is satisfied by a delegate - - The delegate whose value is to be tested - True for if the base constraint fails, false if it succeeds - - - - Test whether the constraint is satisfied by a given reference. - Overridden to wait for the specified delay period before - calling the base constraint with the dereferenced value. - - A reference to the value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a MessageWriter. - - The writer on which the actual value is displayed - - - - Returns the string representation of the constraint. - - - - - EmptyDirectoryConstraint is used to test that a directory is empty - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - EmptyConstraint tests a whether a string or collection is empty, - postponing the decision about which test is applied until the - type of the actual argument is known. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - EqualConstraint is able to compare an actual value with the - expected value provided in its constructor. Two objects are - considered equal if both are null, or if both have the same - value. NUnit has special semantics for some object types. - - - - - If true, strings in error messages will be clipped - - - - - NUnitEqualityComparer used to test equality. - - - - - Initializes a new instance of the class. - - The expected value. - - - - Flag the constraint to use a tolerance when determining equality. - - Tolerance value to be used - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied Comparison object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write a failure message. Overridden to provide custom - failure messages for EqualConstraint. - - The MessageWriter to write to - - - - Write description of this constraint - - The MessageWriter to write to - - - - Display the failure information for two collections that did not match. - - The MessageWriter on which to display - The expected collection. - The actual collection - The depth of this failure in a set of nested collections - - - - Displays a single line showing the types and sizes of the expected - and actual enumerations, collections or arrays. If both are identical, - the value is only shown once. - - The MessageWriter on which to display - The expected collection or array - The actual collection or array - The indentation level for the message line - - - - Displays a single line showing the point in the expected and actual - arrays at which the comparison failed. If the arrays have different - structures or dimensions, both values are shown. - - The MessageWriter on which to display - The expected array - The actual array - Index of the failure point in the underlying collections - The indentation level for the message line - - - - Display the failure information for two IEnumerables that did not match. - - The MessageWriter on which to display - The expected enumeration. - The actual enumeration - The depth of this failure in a set of nested collections - - - - Flag the constraint to ignore case and return self. - - - - - Flag the constraint to suppress string clipping - and return self. - - - - - Flag the constraint to compare arrays as collections - and return self. - - - - - Switches the .Within() modifier to interpret its tolerance as - a distance in representable values (see remarks). - - Self. - - Ulp stands for "unit in the last place" and describes the minimum - amount a given value can change. For any integers, an ulp is 1 whole - digit. For floating point values, the accuracy of which is better - for smaller numbers and worse for larger numbers, an ulp depends - on the size of the number. Using ulps for comparison of floating - point results instead of fixed tolerances is safer because it will - automatically compensate for the added inaccuracy of larger numbers. - - - - - Switches the .Within() modifier to interpret its tolerance as - a percentage that the actual values is allowed to deviate from - the expected value. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in days. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in hours. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in minutes. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in seconds. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in milliseconds. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in clock ticks. - - Self - - - - EqualityAdapter class handles all equality comparisons - that use an IEqualityComparer, IEqualityComparer<T> - or a ComparisonAdapter. - - - - - Compares two objects, returning true if they are equal - - - - - Returns true if the two objects can be compared by this adapter. - The base adapter cannot handle IEnumerables except for strings. - - - - - Returns an EqualityAdapter that wraps an IComparer. - - - - - Returns an EqualityAdapter that wraps an IEqualityComparer. - - - - - Returns an EqualityAdapter that wraps an IEqualityComparer<T>. - - - - - Returns an EqualityAdapter that wraps an IComparer<T>. - - - - - Returns an EqualityAdapter that wraps a Comparison<T>. - - - - - EqualityAdapter that wraps an IComparer. - - - - - Returns true if the two objects can be compared by this adapter. - Generic adapter requires objects of the specified type. - - - - - EqualityAdapter that wraps an IComparer. - - - - Helper routines for working with floating point numbers - - - The floating point comparison code is based on this excellent article: - http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm - - - "ULP" means Unit in the Last Place and in the context of this library refers to - the distance between two adjacent floating point numbers. IEEE floating point - numbers can only represent a finite subset of natural numbers, with greater - accuracy for smaller numbers and lower accuracy for very large numbers. - - - If a comparison is allowed "2 ulps" of deviation, that means the values are - allowed to deviate by up to 2 adjacent floating point values, which might be - as low as 0.0000001 for small numbers or as high as 10.0 for large numbers. - - - - - Compares two floating point values for equality - First floating point value to be compared - Second floating point value t be compared - - Maximum number of representable floating point values that are allowed to - be between the left and the right floating point values - - True if both numbers are equal or close to being equal - - - Floating point values can only represent a finite subset of natural numbers. - For example, the values 2.00000000 and 2.00000024 can be stored in a float, - but nothing inbetween them. - - - This comparison will count how many possible floating point values are between - the left and the right number. If the number of possible values between both - numbers is less than or equal to maxUlps, then the numbers are considered as - being equal. - - - Implementation partially follows the code outlined here: - http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ - - - - - Compares two double precision floating point values for equality - First double precision floating point value to be compared - Second double precision floating point value t be compared - - Maximum number of representable double precision floating point values that are - allowed to be between the left and the right double precision floating point values - - True if both numbers are equal or close to being equal - - - Double precision floating point values can only represent a limited series of - natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004 - can be stored in a double, but nothing inbetween them. - - - This comparison will count how many possible double precision floating point - values are between the left and the right number. If the number of possible - values between both numbers is less than or equal to maxUlps, then the numbers - are considered as being equal. - - - Implementation partially follows the code outlined here: - http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ - - - - - - Reinterprets the memory contents of a floating point value as an integer value - - - Floating point value whose memory contents to reinterpret - - - The memory contents of the floating point value interpreted as an integer - - - - - Reinterprets the memory contents of a double precision floating point - value as an integer value - - - Double precision floating point value whose memory contents to reinterpret - - - The memory contents of the double precision floating point value - interpreted as an integer - - - - - Reinterprets the memory contents of an integer as a floating point value - - Integer value whose memory contents to reinterpret - - The memory contents of the integer value interpreted as a floating point value - - - - - Reinterprets the memory contents of an integer value as a double precision - floating point value - - Integer whose memory contents to reinterpret - - The memory contents of the integer interpreted as a double precision - floating point value - - - - Union of a floating point variable and an integer - - - The union's value as a floating point variable - - - The union's value as an integer - - - The union's value as an unsigned integer - - - Union of a double precision floating point variable and a long - - - The union's value as a double precision floating point variable - - - The union's value as a long - - - The union's value as an unsigned long - - - - Tests whether a value is greater than the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Tests whether a value is greater than or equal to the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Tests whether a value is less than the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Tests whether a value is less than or equal to the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - MessageWriter is the abstract base for classes that write - constraint descriptions and messages in some form. The - class has separate methods for writing various components - of a message, allowing implementations to tailor the - presentation as needed. - - - - - Construct a MessageWriter given a culture - - - - - Method to write single line message with optional args, usually - written to precede the general failure message. - - The message to be written - Any arguments used in formatting the message - - - - Method to write single line message with optional args, usually - written to precede the general failure message, at a givel - indentation level. - - The indentation level of the message - The message to be written - Any arguments used in formatting the message - - - - Display Expected and Actual lines for a constraint. This - is called by MessageWriter's default implementation of - WriteMessageTo and provides the generic two-line display. - - The constraint that failed - - - - Display Expected and Actual lines for given values. This - method may be called by constraints that need more control over - the display of actual and expected values than is provided - by the default implementation. - - The expected value - The actual value causing the failure - - - - Display Expected and Actual lines for given values, including - a tolerance value on the Expected line. - - The expected value - The actual value causing the failure - The tolerance within which the test was made - - - - Display the expected and actual string values on separate lines. - If the mismatch parameter is >=0, an additional line is displayed - line containing a caret that points to the mismatch point. - - The expected string value - The actual string value - The point at which the strings don't match or -1 - If true, case is ignored in locating the point where the strings differ - If true, the strings should be clipped to fit the line - - - - Writes the text for a connector. - - The connector. - - - - Writes the text for a predicate. - - The predicate. - - - - Writes the text for an expected value. - - The expected value. - - - - Writes the text for a modifier - - The modifier. - - - - Writes the text for an actual value. - - The actual value. - - - - Writes the text for a generalized value. - - The value. - - - - Writes the text for a collection value, - starting at a particular point, to a max length - - The collection containing elements to write. - The starting point of the elements to write - The maximum number of elements to write - - - - Abstract method to get the max line length - - - - - Static methods used in creating messages - - - - - Static string used when strings are clipped - - - - - Returns the representation of a type as used in NUnitLite. - This is the same as Type.ToString() except for arrays, - which are displayed with their declared sizes. - - - - - - - Converts any control characters in a string - to their escaped representation. - - The string to be converted - The converted string - - - - Return the a string representation for a set of indices into an array - - Array of indices for which a string is needed - - - - Get an array of indices representing the point in a enumerable, - collection or array corresponding to a single int index into the - collection. - - The collection to which the indices apply - Index in the collection - Array of indices - - - - Clip a string to a given length, starting at a particular offset, returning the clipped - string with ellipses representing the removed parts - - The string to be clipped - The maximum permitted length of the result string - The point at which to start clipping - The clipped string - - - - Clip the expected and actual strings in a coordinated fashion, - so that they may be displayed together. - - - - - - - - - Shows the position two strings start to differ. Comparison - starts at the start index. - - The expected string - The actual string - The index in the strings at which comparison should start - Boolean indicating whether case should be ignored - -1 if no mismatch found, or the index where mismatch found - - - - The Numerics class contains common operations on numeric values. - - - - - Checks the type of the object, returning true if - the object is a numeric type. - - The object to check - true if the object is a numeric type - - - - Checks the type of the object, returning true if - the object is a floating point numeric type. - - The object to check - true if the object is a floating point numeric type - - - - Checks the type of the object, returning true if - the object is a fixed point numeric type. - - The object to check - true if the object is a fixed point numeric type - - - - Test two numeric values for equality, performing the usual numeric - conversions and using a provided or default tolerance. If the tolerance - provided is Empty, this method may set it to a default tolerance. - - The expected value - The actual value - A reference to the tolerance in effect - True if the values are equal - - - - Compare two numeric values, performing the usual numeric conversions. - - The expected value - The actual value - The relationship of the values to each other - - - - NUnitComparer encapsulates NUnit's default behavior - in comparing two objects. - - - - - Compares two objects - - - - - - - - Returns the default NUnitComparer. - - - - - Generic version of NUnitComparer - - - - - - Compare two objects of the same type - - - - - NUnitEqualityComparer encapsulates NUnit's handling of - equality tests between objects. - - - - - - - - - - Compares two objects for equality within a tolerance - - The first object to compare - The second object to compare - The tolerance to use in the comparison - - - - - If true, all string comparisons will ignore case - - - - - If true, arrays will be treated as collections, allowing - those of different dimensions to be compared - - - - - Comparison objects used in comparisons for some constraints. - - - - - Compares two objects for equality within a tolerance. - - - - - Helper method to compare two arrays - - - - - Method to compare two DirectoryInfo objects - - first directory to compare - second directory to compare - true if equivalent, false if not - - - - Returns the default NUnitEqualityComparer - - - - - Gets and sets a flag indicating whether case should - be ignored in determining equality. - - - - - Gets and sets a flag indicating that arrays should be - compared as collections, without regard to their shape. - - - - - Gets and sets an external comparer to be used to - test for equality. It is applied to members of - collections, in place of NUnit's own logic. - - - - - Gets the list of failure points for the last Match performed. - - - - - FailurePoint class represents one point of failure - in an equality test. - - - - - The location of the failure - - - - - The expected value - - - - - The actual value - - - - - Indicates whether the expected value is valid - - - - - Indicates whether the actual value is valid - - - - - PathConstraint serves as the abstract base of constraints - that operate on paths and provides several helper methods. - - - - - The expected path used in the constraint - - - - - The actual path being tested - - - - - Flag indicating whether a caseInsensitive comparison should be made - - - - - Construct a PathConstraint for a give expected path - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Returns true if the expected path and actual path match - - - - - Returns the string representation of this constraint - - - - - Canonicalize the provided path - - - The path in standardized form - - - - Test whether two paths are the same - - The first path - The second path - Indicates whether case should be ignored - - - - - Test whether one path is under another path - - The first path - supposed to be the parent path - The second path - supposed to be the child path - Indicates whether case should be ignored - - - - - Test whether one path is the same as or under another path - - The first path - supposed to be the parent path - The second path - supposed to be the child path - - - - - Modifies the current instance to be case-insensitve - and returns it. - - - - - Modifies the current instance to be case-sensitve - and returns it. - - - - - Summary description for SamePathConstraint. - - - - - Initializes a new instance of the class. - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The expected path - The actual path - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - SubPathConstraint tests that the actual path is under the expected path - - - - - Initializes a new instance of the class. - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The expected path - The actual path - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - SamePathOrUnderConstraint tests that one path is under another - - - - - Initializes a new instance of the class. - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The expected path - The actual path - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Predicate constraint wraps a Predicate in a constraint, - returning success if the predicate is true. - - - - - Construct a PredicateConstraint from a predicate - - - - - Determines whether the predicate succeeds when applied - to the actual value. - - - - - Writes the description to a MessageWriter - - - - - NotConstraint negates the effect of some other constraint - - - - - Initializes a new instance of the class. - - The base constraint to be negated. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for if the base constraint fails, false if it succeeds - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a MessageWriter. - - The writer on which the actual value is displayed - - - - AllItemsConstraint applies another constraint to each - item in a collection, succeeding if they all succeed. - - - - - Construct an AllItemsConstraint on top of an existing constraint - - - - - - Apply the item constraint to each item in the collection, - failing if any item fails. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - SomeItemsConstraint applies another constraint to each - item in a collection, succeeding if any of them succeeds. - - - - - Construct a SomeItemsConstraint on top of an existing constraint - - - - - - Apply the item constraint to each item in the collection, - succeeding if any item succeeds. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - NoItemConstraint applies another constraint to each - item in a collection, failing if any of them succeeds. - - - - - Construct a NoItemConstraint on top of an existing constraint - - - - - - Apply the item constraint to each item in the collection, - failing if any item fails. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - ExactCoutConstraint applies another constraint to each - item in a collection, succeeding only if a specified - number of items succeed. - - - - - Construct an ExactCountConstraint on top of an existing constraint - - - - - - - Apply the item constraint to each item in the collection, - succeeding only if the expected number of items pass. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - PropertyExistsConstraint tests that a named property - exists on the object provided through Match. - - Originally, PropertyConstraint provided this feature - in addition to making optional tests on the vaue - of the property. The two constraints are now separate. - - - - - Initializes a new instance of the class. - - The name of the property. - - - - Test whether the property exists for a given object - - The object to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. - - The writer on which the actual value is displayed - - - - Returns the string representation of the constraint. - - - - - - PropertyConstraint extracts a named property and uses - its value as the actual value for a chained constraint. - - - - - Initializes a new instance of the class. - - The name. - The constraint to apply to the property. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation of the constraint. - - - - - - RangeConstraint tests whethe two values are within a - specified range. - - - - - Initializes a new instance of the class. - - From. - To. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - ResolvableConstraintExpression is used to represent a compound - constraint being constructed at a point where the last operator - may either terminate the expression or may have additional - qualifying constraints added to it. - - It is used, for example, for a Property element or for - an Exception element, either of which may be optionally - followed by constraints that apply to the property or - exception. - - - - - Create a new instance of ResolvableConstraintExpression - - - - - Create a new instance of ResolvableConstraintExpression, - passing in a pre-populated ConstraintBuilder. - - - - - Resolve the current expression to a Constraint - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if the - argument constraint is not satisfied. - - - - - Appends an And Operator to the expression - - - - - Appends an Or operator to the expression. - - - - - ReusableConstraint wraps a resolved constraint so that it - may be saved and reused as needed. - - - - - Construct a ReusableConstraint - - The constraint or expression to be reused - - - - Conversion operator from a normal constraint to a ReusableConstraint. - - The original constraint to be wrapped as a ReusableConstraint - - - - - Returns the string representation of the constraint. - - A string representing the constraint - - - - Resolves the ReusableConstraint by returning the constraint - that it originally wrapped. - - A resolved constraint - - - - SameAsConstraint tests whether an object is identical to - the object passed to its constructor - - - - - Initializes a new instance of the class. - - The expected object. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - BinarySerializableConstraint tests whether - an object is serializable in binary format. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation - - - - - BinarySerializableConstraint tests whether - an object is serializable in binary format. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation of this constraint - - - - - StringConstraint is the abstract base for constraints - that operate on strings. It supports the IgnoreCase - modifier for string operations. - - - - - The expected value - - - - - Indicates whether tests should be case-insensitive - - - - - Constructs a StringConstraint given an expected value - - The expected value - - - - Modify the constraint to ignore case in matching. - - - - - EmptyStringConstraint tests whether a string is empty. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - NullEmptyStringConstraint tests whether a string is either null or empty. - - - - - Constructs a new NullOrEmptyStringConstraint - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - SubstringConstraint can test whether a string contains - the expected substring. - - - - - Initializes a new instance of the class. - - The expected. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - StartsWithConstraint can test whether a string starts - with an expected substring. - - - - - Initializes a new instance of the class. - - The expected string - - - - Test whether the constraint is matched by the actual value. - This is a template method, which calls the IsMatch method - of the derived class. - - - - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - EndsWithConstraint can test whether a string ends - with an expected substring. - - - - - Initializes a new instance of the class. - - The expected string - - - - Test whether the constraint is matched by the actual value. - This is a template method, which calls the IsMatch method - of the derived class. - - - - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - RegexConstraint can test whether a string matches - the pattern provided. - - - - - Initializes a new instance of the class. - - The pattern. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - ThrowsConstraint is used to test the exception thrown by - a delegate by applying a constraint to it. - - - - - Initializes a new instance of the class, - using a constraint to be applied to the exception. - - A constraint to apply to the caught exception. - - - - Executes the code of the delegate and captures any exception. - If a non-null base constraint was provided, it applies that - constraint to the exception. - - A delegate representing the code to be tested - True if an exception is thrown and the constraint succeeds, otherwise false - - - - Converts an ActualValueDelegate to a TestDelegate - before calling the primary overload. - - - - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation of this constraint - - - - - Get the actual exception thrown - used by Assert.Throws. - - - - - ThrowsNothingConstraint tests that a delegate does not - throw an exception. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True if no exception is thrown, otherwise false - - - - Converts an ActualValueDelegate to a TestDelegate - before calling the primary overload. - - - - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Modes in which the tolerance value for a comparison can - be interpreted. - - - - - The tolerance was created with a value, without specifying - how the value would be used. This is used to prevent setting - the mode more than once and is generally changed to Linear - upon execution of the test. - - - - - The tolerance is used as a numeric range within which - two compared values are considered to be equal. - - - - - Interprets the tolerance as the percentage by which - the two compared values my deviate from each other. - - - - - Compares two values based in their distance in - representable numbers. - - - - - The Tolerance class generalizes the notion of a tolerance - within which an equality test succeeds. Normally, it is - used with numeric types, but it can be used with any - type that supports taking a difference between two - objects and comparing that difference to a value. - - - - - Constructs a linear tolerance of a specdified amount - - - - - Constructs a tolerance given an amount and ToleranceMode - - - - - Tests that the current Tolerance is linear with a - numeric value, throwing an exception if it is not. - - - - - Returns an empty Tolerance object, equivalent to - specifying no tolerance. In most cases, it results - in an exact match but for floats and doubles a - default tolerance may be used. - - - - - Returns a zero Tolerance object, equivalent to - specifying an exact match. - - - - - Gets the ToleranceMode for the current Tolerance - - - - - Gets the value of the current Tolerance instance. - - - - - Returns a new tolerance, using the current amount as a percentage. - - - - - Returns a new tolerance, using the current amount in Ulps. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of days. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of hours. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of minutes. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of seconds. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of milliseconds. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of clock ticks. - - - - - Returns true if the current tolerance is empty. - - - - - TypeConstraint is the abstract base for constraints - that take a Type as their expected value. - - - - - The expected Type used by the constraint - - - - - Construct a TypeConstraint for a given Type - - - - - - Write the actual value for a failing constraint test to a - MessageWriter. TypeConstraints override this method to write - the name of the type. - - The writer on which the actual value is displayed - - - - ExactTypeConstraint is used to test that an object - is of the exact type provided in the constructor - - - - - Construct an ExactTypeConstraint for a given Type - - The expected Type. - - - - Test that an object is of the exact type specified - - The actual value. - True if the tested object is of the exact type provided, otherwise false. - - - - Write the description of this constraint to a MessageWriter - - The MessageWriter to use - - - - ExceptionTypeConstraint is a special version of ExactTypeConstraint - used to provided detailed info about the exception thrown in - an error message. - - - - - Constructs an ExceptionTypeConstraint - - - - - Write the actual value for a failing constraint test to a - MessageWriter. Overriden to write additional information - in the case of an Exception. - - The MessageWriter to use - - - - InstanceOfTypeConstraint is used to test that an object - is of the same type provided or derived from it. - - - - - Construct an InstanceOfTypeConstraint for the type provided - - The expected Type - - - - Test whether an object is of the specified type or a derived type - - The object to be tested - True if the object is of the provided type or derives from it, otherwise false. - - - - Write a description of this constraint to a MessageWriter - - The MessageWriter to use - - - - AssignableFromConstraint is used to test that an object - can be assigned from a given Type. - - - - - Construct an AssignableFromConstraint for the type provided - - - - - - Test whether an object can be assigned from the specified type - - The object to be tested - True if the object can be assigned a value of the expected Type, otherwise false. - - - - Write a description of this constraint to a MessageWriter - - The MessageWriter to use - - - - AssignableToConstraint is used to test that an object - can be assigned to a given Type. - - - - - Construct an AssignableToConstraint for the type provided - - - - - - Test whether an object can be assigned to the specified type - - The object to be tested - True if the object can be assigned a value of the expected Type, otherwise false. - - - - Write a description of this constraint to a MessageWriter - - The MessageWriter to use - - - - Thrown when an assertion failed. - - - - - The error message that explains - the reason for the exception - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - Thrown when an assertion failed. - - - - - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - Thrown when a test executes inconclusively. - - - - - The error message that explains - the reason for the exception - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - Thrown when an assertion failed. - - - - - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - - - - - - - Compares two objects of a given Type for equality within a tolerance - - The first object to compare - The second object to compare - The tolerance to use in the comparison - - - - - The different targets a test action attribute can be applied to - - - - - Default target, which is determined by where the action attribute is attached - - - - - Target a individual test case - - - - - Target a suite of test cases - - - - - Delegate used by tests that execute code and - capture any thrown exception. - - - - - The Assert class contains a collection of static methods that - implement the most common assertions used in NUnit. - - - - - We don't actually want any instances of this object, but some people - like to inherit from it to add other static methods. Hence, the - protected constructor disallows any instances of this object. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Helper for Assert.AreEqual(double expected, double actual, ...) - allowing code generation to work consistently. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Throws a with the message and arguments - that are passed in. This allows a test to be cut short, with a result - of success returned to NUnit. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws a with the message and arguments - that are passed in. This allows a test to be cut short, with a result - of success returned to NUnit. - - The message to initialize the with. - - - - Throws a with the message and arguments - that are passed in. This allows a test to be cut short, with a result - of success returned to NUnit. - - - - - Throws an with the message and arguments - that are passed in. This is used by the other Assert functions. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws an with the message that is - passed in. This is used by the other Assert functions. - - The message to initialize the with. - - - - Throws an . - This is used by the other Assert functions. - - - - - Throws an with the message and arguments - that are passed in. This causes the test to be reported as ignored. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws an with the message that is - passed in. This causes the test to be reported as ignored. - - The message to initialize the with. - - - - Throws an . - This causes the test to be reported as ignored. - - - - - Throws an with the message and arguments - that are passed in. This causes the test to be reported as inconclusive. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws an with the message that is - passed in. This causes the test to be reported as inconclusive. - - The message to initialize the with. - - - - Throws an . - This causes the test to be reported as Inconclusive. - - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - - - - Asserts that the code represented by a delegate throws an exception - that satisfies the constraint provided. - - A TestDelegate to be executed - A ThrowsConstraint used in the test - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - Used as a synonym for That in rare cases where a private setter - causes a Visual Basic compilation error. - - A Constraint to be applied - The actual value to test - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - Used as a synonym for That in rare cases where a private setter - causes a Visual Basic compilation error. - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - Used as a synonym for That in rare cases where a private setter - causes a Visual Basic compilation error. - - - This method is provided for use by VB developers needing to test - the value of properties with private setters. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - A constraint to be satisfied by the exception - A TestSnippet delegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - A constraint to be satisfied by the exception - A TestSnippet delegate - The message that will be displayed on failure - - - - Verifies that a delegate throws a particular exception when called. - - A constraint to be satisfied by the exception - A TestSnippet delegate - - - - Verifies that a delegate throws a particular exception when called. - - The exception Type expected - A TestSnippet delegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - The exception Type expected - A TestSnippet delegate - The message that will be displayed on failure - - - - Verifies that a delegate throws a particular exception when called. - - The exception Type expected - A TestSnippet delegate - - - - Verifies that a delegate throws a particular exception when called. - - Type of the expected exception - A TestSnippet delegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - Type of the expected exception - A TestSnippet delegate - The message that will be displayed on failure - - - - Verifies that a delegate throws a particular exception when called. - - Type of the expected exception - A TestSnippet delegate - - - - Verifies that a delegate throws an exception when called - and returns it. - - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws an exception when called - and returns it. - - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws an exception when called - and returns it. - - A TestDelegate - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - - - - Verifies that a delegate does not throw an exception - - A TestSnippet delegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate does not throw an exception. - - A TestSnippet delegate - The message that will be displayed on failure - - - - Verifies that a delegate does not throw an exception. - - A TestSnippet delegate - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - - - - Assert that a string is empty - that is equal to string.Empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is empty - that is equal to string.Empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is empty - that is equal to string.Empty - - The string to be tested - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing ICollection - - - - Assert that a string is not empty - that is not equal to string.Empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is not empty - that is not equal to string.Empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is not empty - that is not equal to string.Empty - - The string to be tested - - - - Assert that an array, list or other collection is not empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that an array, list or other collection is not empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - - - - Assert that an array, list or other collection is not empty - - An array, list or other collection implementing ICollection - - - - Assert that a string is either null or equal to string.Empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is either null or equal to string.Empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is either null or equal to string.Empty - - The string to be tested - - - - Assert that a string is not null or empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is not null or empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is not null or empty - - The string to be tested - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - - - - Verifies that two objects are equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are not equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two objects are equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are not equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - - - - Verifies that two objects are equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are not equal an is thrown. - - The value that is expected - The actual value - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two values are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two objects are not equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two objects are not equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - - - - Verifies that two objects are not equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are equal an is thrown. - - The value that is expected - The actual value - - - - Asserts that two objects refer to the same object. If they - are not the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that two objects refer to the same object. If they - are not the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - - - - Asserts that two objects refer to the same object. If they - are not the same an is thrown. - - The expected object - The actual object - - - - Asserts that two objects do not refer to the same object. If they - are the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that two objects do not refer to the same object. If they - are the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - - - - Asserts that two objects do not refer to the same object. If they - are the same an is thrown. - - The expected object - The actual object - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Asserts that an object is contained in a list. - - The expected object - The list to be examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is contained in a list. - - The expected object - The list to be examined - The message to display in case of failure - - - - Asserts that an object is contained in a list. - - The expected object - The list to be examined - - - - Gets the number of assertions executed so far and - resets the counter to zero. - - - - - AssertionHelper is an optional base class for user tests, - allowing the use of shorter names for constraints and - asserts and avoiding conflict with the definition of - , from which it inherits much of its - behavior, in certain mock object frameworks. - - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. Works - identically to Assert.That - - A Constraint to be applied - The actual value to test - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. Works - identically to Assert.That. - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. Works - identically to Assert.That - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . Works Identically to Assert.That. - - The evaluated condition - The message to display if the condition is false - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . Works Identically to Assert.That. - - The evaluated condition - The message to display if the condition is false - - - - Asserts that a condition is true. If the condition is false the method throws - an . Works Identically Assert.That. - - The evaluated condition - - - - Asserts that the code represented by a delegate throws an exception - that satisfies the constraint provided. - - A TestDelegate to be executed - A ThrowsConstraint used in the test - - - - Returns a ListMapper based on a collection. - - The original collection - - - - - Provides static methods to express the assumptions - that must be met for a test to give a meaningful - result. If an assumption is not met, the test - should produce an inconclusive result. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - - - - Asserts that a condition is true. If the condition is false the - method throws an . - - The evaluated condition - - - - Asserts that the code represented by a delegate throws an exception - that satisfies the constraint provided. - - A TestDelegate to be executed - A ThrowsConstraint used in the test - - - - A set of Assert methods operationg on one or more collections - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Asserts that all items contained in collection are of the type specified by expectedType. - - IEnumerable containing objects to be considered - System.Type that all objects in collection must be instances of - - - - Asserts that all items contained in collection are of the type specified by expectedType. - - IEnumerable containing objects to be considered - System.Type that all objects in collection must be instances of - The message that will be displayed on failure - - - - Asserts that all items contained in collection are of the type specified by expectedType. - - IEnumerable containing objects to be considered - System.Type that all objects in collection must be instances of - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that all items contained in collection are not equal to null. - - IEnumerable containing objects to be considered - - - - Asserts that all items contained in collection are not equal to null. - - IEnumerable containing objects to be considered - The message that will be displayed on failure - - - - Asserts that all items contained in collection are not equal to null. - - IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Ensures that every object contained in collection exists within the collection - once and only once. - - IEnumerable of objects to be considered - - - - Ensures that every object contained in collection exists within the collection - once and only once. - - IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Ensures that every object contained in collection exists within the collection - once and only once. - - IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are not exactly equal. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are not exactly equal. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - - - - Asserts that expected and actual are not exactly equal. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are not exactly equal. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - - - - Asserts that expected and actual are not exactly equal. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are not exactly equal. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are not equivalent. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are not equivalent. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are not equivalent. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that collection contains actual as an item. - - IEnumerable of objects to be considered - Object to be found within collection - - - - Asserts that collection contains actual as an item. - - IEnumerable of objects to be considered - Object to be found within collection - The message that will be displayed on failure - - - - Asserts that collection contains actual as an item. - - IEnumerable of objects to be considered - Object to be found within collection - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that collection does not contain actual as an item. - - IEnumerable of objects to be considered - Object that cannot exist within collection - - - - Asserts that collection does not contain actual as an item. - - IEnumerable of objects to be considered - Object that cannot exist within collection - The message that will be displayed on failure - - - - Asserts that collection does not contain actual as an item. - - IEnumerable of objects to be considered - Object that cannot exist within collection - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that superset is not a subject of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - - - - Asserts that superset is not a subject of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - - - - Asserts that superset is not a subject of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that superset is a subset of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - - - - Asserts that superset is a subset of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - - - - Asserts that superset is a subset of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - - - - Assert that an array,list or other collection is empty - - An array, list or other collection implementing IEnumerable - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - - - - Assert that an array,list or other collection is empty - - An array, list or other collection implementing IEnumerable - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - A custom comparer to perform the comparisons - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - A custom comparer to perform the comparisons - The message to be displayed on failure - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - A custom comparer to perform the comparisons - - - - Static helper class used in the constraint-based syntax - - - - - Creates a new SubstringConstraint - - The value of the substring - A SubstringConstraint - - - - Creates a new CollectionContainsConstraint. - - The item that should be found. - A new CollectionContainsConstraint - - - - Summary description for DirectoryAssert - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - We don't actually want any instances of this object, but some people - like to inherit from it to add other static methods. Hence, the - protected constructor disallows any instances of this object. - - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are not equal - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are equal - Arguments to be used in formatting the message - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are equal - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Summary description for FileAssert. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - We don't actually want any instances of this object, but some people - like to inherit from it to add other static methods. Hence, the - protected constructor disallows any instances of this object. - - - - - Verifies that two Streams are equal. Two Streams are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The expected Stream - The actual Stream - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Verifies that two Streams are equal. Two Streams are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The expected Stream - The actual Stream - The message to display if objects are not equal - - - - Verifies that two Streams are equal. Two Streams are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The expected Stream - The actual Stream - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if objects are not equal - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A file containing the value that is expected - A file containing the actual value - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if objects are not equal - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - - - - Asserts that two Streams are not equal. If they are equal - an is thrown. - - The expected Stream - The actual Stream - The message to be displayed when the two Stream are the same. - Arguments to be used in formatting the message - - - - Asserts that two Streams are not equal. If they are equal - an is thrown. - - The expected Stream - The actual Stream - The message to be displayed when the Streams are the same. - - - - Asserts that two Streams are not equal. If they are equal - an is thrown. - - The expected Stream - The actual Stream - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if objects are not equal - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - A file containing the value that is expected - A file containing the actual value - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if objects are not equal - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - - - - GlobalSettings is a place for setting default values used - by the framework in performing asserts. - - - - - Default tolerance for floating point equality - - - - - Helper class with properties and methods that supply - a number of constraints used in Asserts. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding only if a specified number of them succeed. - - - - - Returns a new PropertyConstraintExpression, which will either - test for the existence of the named property on the object - being tested or apply any following constraint to that property. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if at least one of them succeeds. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them fail. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Length property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Count property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Message property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the InnerException property of the object being tested. - - - - - Interface implemented by a user fixture in order to - validate any expected exceptions. It is only called - for test methods marked with the ExpectedException - attribute. - - - - - Method to handle an expected exception - - The exception to be handled - - - - Helper class with properties and methods that supply - a number of constraints used in Asserts. - - - - - Returns a constraint that tests two items for equality - - - - - Returns a constraint that tests that two references are the same object - - - - - Returns a constraint that tests whether the - actual value is greater than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a collection containing the same elements as the - collection supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a subset of the collection supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the Regex pattern supplied as an argument. - - - - - Returns a constraint that tests whether the path provided - is the same as an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the actual value falls - within a specified range. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a constraint that tests for null - - - - - Returns a constraint that tests for True - - - - - Returns a constraint that tests for False - - - - - Returns a constraint that tests for a positive value - - - - - Returns a constraint that tests for a negative value - - - - - Returns a constraint that tests for NaN - - - - - Returns a constraint that tests for empty - - - - - Returns a constraint that tests whether a collection - contains all unique items. - - - - - Returns a constraint that tests whether an object graph is serializable in binary format. - - - - - Returns a constraint that tests whether an object graph is serializable in xml format. - - - - - Returns a constraint that tests whether a collection is ordered - - - - - The Iz class is a synonym for Is intended for use in VB, - which regards Is as a keyword. - - - - - The List class is a helper class with properties and methods - that supply a number of constraints used with lists and collections. - - - - - List.Map returns a ListMapper, which can be used to map - the original collection to another collection. - - - - - - - ListMapper is used to transform a collection used as an actual argument - producing another collection to be used in the assertion. - - - - - Construct a ListMapper based on a collection - - The collection to be transformed - - - - Produces a collection containing all the values of a property - - The collection of property values - - - - - Randomizer returns a set of random values in a repeatable - way, to allow re-running of tests if necessary. - - - - - Get a randomizer for a particular member, returning - one that has already been created if it exists. - This ensures that the same values are generated - each time the tests are reloaded. - - - - - Get a randomizer for a particular parameter, returning - one that has already been created if it exists. - This ensures that the same values are generated - each time the tests are reloaded. - - - - - Construct a randomizer using a random seed - - - - - Construct a randomizer using a specified seed - - - - - Return an array of random doubles between 0.0 and 1.0. - - - - - - - Return an array of random doubles with values in a specified range. - - - - - Return an array of random ints with values in a specified range. - - - - - Get a random seed for use in creating a randomizer. - - - - - The SpecialValue enum is used to represent TestCase arguments - that cannot be used as arguments to an Attribute. - - - - - Null represents a null value, which cannot be used as an - argument to an attriute under .NET 1.x - - - - - Basic Asserts on strings. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - - - - Asserts that a string is not found within another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - - - - Asserts that a string starts with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string starts with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string starts with another string. - - The expected string - The string to be examined - - - - Asserts that a string does not start with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string does not start with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string does not start with another string. - - The expected string - The string to be examined - - - - Asserts that a string ends with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string ends with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string ends with another string. - - The expected string - The string to be examined - - - - Asserts that a string does not end with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string does not end with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string does not end with another string. - - The expected string - The string to be examined - - - - Asserts that two strings are equal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that two strings are equal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - - - - Asserts that two strings are equal, without regard to case. - - The expected string - The actual string - - - - Asserts that two strings are not equal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that two strings are Notequal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - - - - Asserts that two strings are not equal, without regard to case. - - The expected string - The actual string - - - - Asserts that a string matches an expected regular expression pattern. - - The regex pattern to be matched - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string matches an expected regular expression pattern. - - The regex pattern to be matched - The actual string - The message to display in case of failure - - - - Asserts that a string matches an expected regular expression pattern. - - The regex pattern to be matched - The actual string - - - - Asserts that a string does not match an expected regular expression pattern. - - The regex pattern to be used - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string does not match an expected regular expression pattern. - - The regex pattern to be used - The actual string - The message to display in case of failure - - - - Asserts that a string does not match an expected regular expression pattern. - - The regex pattern to be used - The actual string - - - - The TestCaseData class represents a set of arguments - and other parameter info to be used for a parameterized - test case. It provides a number of instance modifiers - for use in initializing the test case. - - Note: Instance modifiers are getters that return - the same instance after modifying it's state. - - - - - The argument list to be provided to the test - - - - - The expected result to be returned - - - - - Set to true if this has an expected result - - - - - The expected exception Type - - - - - The FullName of the expected exception - - - - - The name to be used for the test - - - - - The description of the test - - - - - A dictionary of properties, used to add information - to tests without requiring the class to change. - - - - - If true, indicates that the test case is to be ignored - - - - - If true, indicates that the test case is marked explicit - - - - - The reason for ignoring a test case - - - - - Initializes a new instance of the class. - - The arguments. - - - - Initializes a new instance of the class. - - The argument. - - - - Initializes a new instance of the class. - - The first argument. - The second argument. - - - - Initializes a new instance of the class. - - The first argument. - The second argument. - The third argument. - - - - Sets the expected result for the test - - The expected result - A modified TestCaseData - - - - Sets the expected exception type for the test - - Type of the expected exception. - The modified TestCaseData instance - - - - Sets the expected exception type for the test - - FullName of the expected exception. - The modified TestCaseData instance - - - - Sets the name of the test case - - The modified TestCaseData instance - - - - Sets the description for the test case - being constructed. - - The description. - The modified TestCaseData instance. - - - - Applies a category to the test - - - - - - - Applies a named property to the test - - - - - - - - Applies a named property to the test - - - - - - - - Applies a named property to the test - - - - - - - - Ignores this TestCase. - - - - - - Ignores this TestCase, specifying the reason. - - The reason. - - - - - Marks this TestCase as Explicit - - - - - - Marks this TestCase as Explicit, specifying the reason. - - The reason. - - - - - Gets the argument list to be provided to the test - - - - - Gets the expected result - - - - - Returns true if the result has been set - - - - - Gets the expected exception Type - - - - - Gets the FullName of the expected exception - - - - - Gets the name to be used for the test - - - - - Gets the description of the test - - - - - Gets a value indicating whether this is ignored. - - true if ignored; otherwise, false. - - - - Gets a value indicating whether this is explicit. - - true if explicit; otherwise, false. - - - - Gets the ignore reason. - - The ignore reason. - - - - Gets a list of categories associated with this test. - - - - - Gets the property dictionary for this test - - - - - Provide the context information of the current test - - - - - Constructs a TestContext using the provided context dictionary - - A context dictionary - - - - Get the current test context. This is created - as needed. The user may save the context for - use within a test, but it should not be used - outside the test for which it is created. - - - - - Gets a TestAdapter representing the currently executing test in this context. - - - - - Gets a ResultAdapter representing the current result for the test - executing in this context. - - - - - Gets the directory containing the current test assembly. - - - - - Gets the directory to be used for outputing files created - by this test run. - - - - - TestAdapter adapts a Test for consumption by - the user test code. - - - - - Constructs a TestAdapter for this context - - The context dictionary - - - - The name of the test. - - - - - The FullName of the test - - - - - The properties of the test. - - - - - ResultAdapter adapts a TestResult for consumption by - the user test code. - - - - - Construct a ResultAdapter for a context - - The context holding the result - - - - The TestState of current test. This maps to the ResultState - used in nunit.core and is subject to change in the future. - - - - - The TestStatus of current test. This enum will be used - in future versions of NUnit and so is to be preferred - to the TestState value. - - - - - Provides details about a test - - - - - Creates an instance of TestDetails - - The fixture that the test is a member of, if available. - The method that implements the test, if available. - The full name of the test. - A string representing the type of test, e.g. "Test Case". - Indicates if the test represents a suite of tests. - - - - The fixture that the test is a member of, if available. - - - - - The method that implements the test, if available. - - - - - The full name of the test. - - - - - A string representing the type of test, e.g. "Test Case". - - - - - Indicates if the test represents a suite of tests. - - - - - The ResultState enum indicates the result of running a test - - - - - The result is inconclusive - - - - - The test was not runnable. - - - - - The test has been skipped. - - - - - The test has been ignored. - - - - - The test succeeded - - - - - The test failed - - - - - The test encountered an unexpected exception - - - - - The test was cancelled by the user - - - - - The TestStatus enum indicates the result of running a test - - - - - The test was inconclusive - - - - - The test has skipped - - - - - The test succeeded - - - - - The test failed - - - - - Helper class with static methods used to supply constraints - that operate on strings. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the Regex pattern supplied as an argument. - - - - - Returns a constraint that fails if the actual - value matches the pattern supplied as an argument. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - TextMessageWriter writes constraint descriptions and messages - in displayable form as a text stream. It tailors the display - of individual message components to form the standard message - format of NUnit assertion failure messages. - - - - - Prefix used for the expected value line of a message - - - - - Prefix used for the actual value line of a message - - - - - Length of a message prefix - - - - - Construct a TextMessageWriter - - - - - Construct a TextMessageWriter, specifying a user message - and optional formatting arguments. - - - - - - - Method to write single line message with optional args, usually - written to precede the general failure message, at a givel - indentation level. - - The indentation level of the message - The message to be written - Any arguments used in formatting the message - - - - Display Expected and Actual lines for a constraint. This - is called by MessageWriter's default implementation of - WriteMessageTo and provides the generic two-line display. - - The constraint that failed - - - - Display Expected and Actual lines for given values. This - method may be called by constraints that need more control over - the display of actual and expected values than is provided - by the default implementation. - - The expected value - The actual value causing the failure - - - - Display Expected and Actual lines for given values, including - a tolerance value on the expected line. - - The expected value - The actual value causing the failure - The tolerance within which the test was made - - - - Display the expected and actual string values on separate lines. - If the mismatch parameter is >=0, an additional line is displayed - line containing a caret that points to the mismatch point. - - The expected string value - The actual string value - The point at which the strings don't match or -1 - If true, case is ignored in string comparisons - If true, clip the strings to fit the max line length - - - - Writes the text for a connector. - - The connector. - - - - Writes the text for a predicate. - - The predicate. - - - - Write the text for a modifier. - - The modifier. - - - - Writes the text for an expected value. - - The expected value. - - - - Writes the text for an actual value. - - The actual value. - - - - Writes the text for a generalized value. - - The value. - - - - Writes the text for a collection value, - starting at a particular point, to a max length - - The collection containing elements to write. - The starting point of the elements to write - The maximum number of elements to write - - - - Write the generic 'Expected' line for a constraint - - The constraint that failed - - - - Write the generic 'Expected' line for a given value - - The expected value - - - - Write the generic 'Expected' line for a given value - and tolerance. - - The expected value - The tolerance within which the test was made - - - - Write the generic 'Actual' line for a constraint - - The constraint for which the actual value is to be written - - - - Write the generic 'Actual' line for a given value - - The actual value causing a failure - - - - Gets or sets the maximum line length for this writer - - - - - Helper class with properties and methods that supply - constraints that operate on exceptions. - - - - - Creates a constraint specifying the exact type of exception expected - - - - - Creates a constraint specifying the exact type of exception expected - - - - - Creates a constraint specifying the type of exception expected - - - - - Creates a constraint specifying the type of exception expected - - - - - Creates a constraint specifying an expected exception - - - - - Creates a constraint specifying an exception with a given InnerException - - - - - Creates a constraint specifying an expected TargetInvocationException - - - - - Creates a constraint specifying an expected TargetInvocationException - - - - - Creates a constraint specifying an expected TargetInvocationException - - - - - Creates a constraint specifying that no exception is thrown - - - - diff --git a/lib/x32/net35/System.Data.SQLite.Linq.dll b/lib/x32/net35/System.Data.SQLite.Linq.dll deleted file mode 100644 index 4475a413f..000000000 Binary files a/lib/x32/net35/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/lib/x32/net35/System.Data.SQLite.dll b/lib/x32/net35/System.Data.SQLite.dll deleted file mode 100644 index 58f294f35..000000000 Binary files a/lib/x32/net35/System.Data.SQLite.dll and /dev/null differ diff --git a/lib/x32/net40/System.Data.SQLite.Linq.dll b/lib/x32/net40/System.Data.SQLite.Linq.dll deleted file mode 100644 index b94dcba24..000000000 Binary files a/lib/x32/net40/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/lib/x32/net40/System.Data.SQLite.dll b/lib/x32/net40/System.Data.SQLite.dll deleted file mode 100644 index 457521fa4..000000000 Binary files a/lib/x32/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/lib/x64/net35/System.Data.SQLite.Linq.dll b/lib/x64/net35/System.Data.SQLite.Linq.dll deleted file mode 100644 index 4475a413f..000000000 Binary files a/lib/x64/net35/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/lib/x64/net35/System.Data.SQLite.dll b/lib/x64/net35/System.Data.SQLite.dll deleted file mode 100644 index bb1366d9b..000000000 Binary files a/lib/x64/net35/System.Data.SQLite.dll and /dev/null differ diff --git a/lib/x64/net40/System.Data.SQLite.Linq.dll b/lib/x64/net40/System.Data.SQLite.Linq.dll deleted file mode 100644 index b94dcba24..000000000 Binary files a/lib/x64/net40/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/lib/x64/net40/System.Data.SQLite.dll b/lib/x64/net40/System.Data.SQLite.dll deleted file mode 100644 index cc5f814ae..000000000 Binary files a/lib/x64/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/src/.gitignore b/src/.gitignore index 2d806f8ff..7991d543d 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ bin/ obj/ -_ReSharper.ServiceStack.OrmLite/ \ No newline at end of file +_ReSharper.ServiceStack.OrmLite/ +packages/ \ No newline at end of file diff --git a/src/.nuget/NuGet.config b/src/.nuget/NuGet.config deleted file mode 100644 index 67f8ea046..000000000 --- a/src/.nuget/NuGet.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/.nuget/NuGet.exe b/src/.nuget/NuGet.exe deleted file mode 100644 index ed2b0a221..000000000 Binary files a/src/.nuget/NuGet.exe and /dev/null differ diff --git a/src/.nuget/NuGet.targets b/src/.nuget/NuGet.targets deleted file mode 100644 index f2d0eb36f..000000000 --- a/src/.nuget/NuGet.targets +++ /dev/null @@ -1,77 +0,0 @@ - - - - $(MSBuildProjectDirectory)\..\ - - - - - $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) - $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) - $([System.IO.Path]::Combine($(SolutionDir), "packages")) - - - - - $(SolutionDir).nuget - packages.config - $(SolutionDir)packages - - - - - $(NuGetToolsPath)\NuGet.exe - "$(NuGetExePath)" - mono --runtime=v4.0.30319 $(NuGetExePath) - - $(TargetDir.Trim('\\')) - - - "" - - - false - - - false - - - $(NuGetCommand) install "$(PackagesConfig)" -source $(PackageSources) -o "$(PackagesDir)" - $(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols - - - - RestorePackages; - $(BuildDependsOn); - - - - - $(BuildDependsOn); - BuildPackage; - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/AllDialectsTest/AllDialectsTest.csproj b/src/AllDialectsTest/AllDialectsTest.csproj deleted file mode 100644 index f2ea6caad..000000000 --- a/src/AllDialectsTest/AllDialectsTest.csproj +++ /dev/null @@ -1,94 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480} - Exe - AllDialectsTest - AllDialectsTest - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - ..\..\lib\FirebirdSql.Data.FirebirdClient.dll - - - ..\..\lib\Mono.Data.Sqlite.dll - - - ..\..\lib\Mono.Security.dll - - - ..\..\lib\mysql.data.dll - - - ..\..\lib\Npgsql.dll - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - test.mdf - Always - - - test_log.ldf - Always - test.mdf - - - \ No newline at end of file diff --git a/src/AllDialectsTest/AssemblyInfo.cs b/src/AllDialectsTest/AssemblyInfo.cs deleted file mode 100644 index 15ca070ec..000000000 --- a/src/AllDialectsTest/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("AllDialectsTest")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/AllDialectsTest/Author.cs b/src/AllDialectsTest/Author.cs deleted file mode 100644 index 1f5dbb466..000000000 --- a/src/AllDialectsTest/Author.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; - -namespace AllDialectsTest -{ - public class Author - { - public Author(){} - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - public DateTime Birthday { get; set;} - public DateTime ? LastActivity { get; set;} - public Decimal? Earnings { get; set;} - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - public Int16 Rate{ get; set;} - } -} - diff --git a/src/AllDialectsTest/Dialect.cs b/src/AllDialectsTest/Dialect.cs deleted file mode 100644 index c1fecf2ce..000000000 --- a/src/AllDialectsTest/Dialect.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Reflection; -using System.IO; -using ServiceStack.OrmLite; - -namespace AllDialectsTest -{ - public class Dialect - { - //private static Dictionary dialectDbTypes = new Dictionary(); - - public string Name { get; set; } - public string PathToAssembly { get; set; } - public string AssemblyName { get; set; } - public string ClassName { get; set; } - public string InstanceFieldName { get; set; } - public string ConnectionString { get; set; } - - public IOrmLiteDialectProvider DialectProvider - { - get - { - var assembly = Assembly.LoadFrom(Path.Combine(PathToAssembly, AssemblyName)); - var type = assembly.GetType(ClassName); - if (type == null) - throw new Exception( - string.Format("Can not load type '{0}' from assembly '{1}'", - ClassName, Path.Combine(PathToAssembly, AssemblyName))); - - var fi = type.GetField(InstanceFieldName); - if (fi == null) - throw new Exception( - string.Format("Can not get Field '{0}' from class '{1}'", - InstanceFieldName, ClassName)); - - var o = fi.GetValue(null); - var dialect = o as IOrmLiteDialectProvider; - - if (dialect == null) - throw new Exception( - string.Format("Can not cast from '{0}' to '{1}'", - o, typeof(IOrmLiteDialectProvider)) - ); - - - //Angel can you check if we need this now? DbTypes are now static per Dialiect provider so shouldn't conflict, i.e. DbTypes - - //Types types; - //if (dialectDbTypes.TryGetValue(Name, out types)) - //{ - // DbTypes.ColumnTypeMap = Clone(types.ColumnTypeMap); - // DbTypes.ColumnDbTypeMap = Clone(types.ColumnDbTypeMap); - //} - //else - //{ - // dialectDbTypes[Name] = new Types { - // ColumnTypeMap = Clone(DbTypes.ColumnTypeMap), - // ColumnDbTypeMap = Clone(DbTypes.ColumnDbTypeMap) - // }; - //} - return dialect; - } - } - - //private class Types - //{ - // public Dictionary ColumnTypeMap = new Dictionary(); - // public Dictionary ColumnDbTypeMap = new Dictionary(); - //} - - //private Dictionary Clone(Dictionary original) - //{ - // var clone = new Dictionary(original); - // return clone; - //} - - } -} - diff --git a/src/AllDialectsTest/Main.cs b/src/AllDialectsTest/Main.cs deleted file mode 100644 index 011d788e3..000000000 --- a/src/AllDialectsTest/Main.cs +++ /dev/null @@ -1,593 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Data; -using ServiceStack; -using ServiceStack.OrmLite; - -namespace AllDialectsTest -{ - class MainClass - { - private static List dialects; - private static List authors; - - public static void Main(string[] args) - { - - bool exit=false; - - dialects = BuildDialectList(); - authors = BuildAuthorList(); - - PaintMenu(); - - while (!exit) - { - - Console.WriteLine("Select your option [{0}-{1}] or q to quit and press ENTER", 1, dialects.Count); - string option = Console.ReadLine(); - if (string.IsNullOrEmpty(option)) - Console.WriteLine("NO VALID OPTION"); - else if (option.ToUpper() == "Q") - exit = true; - else - { - int opt; - if (int.TryParse(option, out opt)) - { - if (opt >= 1 && opt <= dialects.Count) - TestDialect(dialects[opt - 1]); - else - { - Console.WriteLine("NO VALID OPTION"); - } - - } - else - Console.WriteLine("NO VALID OPTION"); - } - } - - - } - - private static void PaintMenu() - { - Console.Clear(); - int i=0; - foreach (Dialect d in dialects) - { - Console.WriteLine("{0} {1}", ++i, d.Name); - } - Console.WriteLine("q quit"); - } - - private static List BuildDialectList() - { - List l = new List(); - Dialect d = new Dialect() { - Name = "Sqlite", - PathToAssembly = "../../../ServiceStack.OrmLite.Sqlite/bin/Debug", - AssemblyName = "ServiceStack.OrmLite.Sqlite.dll", - ClassName = "ServiceStack.OrmLite.Sqlite.SqliteOrmLiteDialectProvider", - InstanceFieldName = "Instance", - ConnectionString = "~/db.sqlite".MapAbsolutePath() - }; - l.Add(d); - - d = new Dialect() { - Name = "SqlServer", - PathToAssembly = "../../../ServiceStack.OrmLite.SqlServer/bin/Debug", - AssemblyName = "ServiceStack.OrmLite.SqlServer.dll", - ClassName = "ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider", - InstanceFieldName = "Instance", - ConnectionString = "~/test.mdf".MapAbsolutePath() - }; - l.Add(d); - - d = new Dialect() { - Name = "MySql", - PathToAssembly = "../../../ServiceStack.OrmLite.MySql/bin/Debug", - AssemblyName = "ServiceStack.OrmLite.MySql.dll", - ClassName = "ServiceStack.OrmLite.MySql.MySqlDialectProvider", - InstanceFieldName = "Instance", - ConnectionString = "Server = 127.0.0.1; Database = ormlite; Uid = root; Pwd = password" - }; - l.Add(d); - - d = new Dialect() { - Name = "PostgreSQL", - PathToAssembly = "../../../ServiceStack.OrmLite.PostgreSQL/bin/Debug", - AssemblyName = "ServiceStack.OrmLite.PostgreSQL.dll", - ClassName = "ServiceStack.OrmLite.PostgreSQL.PostgreSQLDialectProvider", - InstanceFieldName = "Instance", - ConnectionString = "Server=localhost;Port=5432;User Id=postgres; Password=postgres; Database=ormlite" - }; - l.Add(d); - - d = new Dialect() { - Name = "FirebirdSql", - PathToAssembly = "../../../ServiceStack.OrmLite.Firebird/bin/Debug", - AssemblyName = "ServiceStack.OrmLite.Firebird.dll", - ClassName = "ServiceStack.OrmLite.Firebird.FirebirdOrmLiteDialectProvider", - InstanceFieldName = "Instance", - ConnectionString = "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;" - }; - l.Add(d); - - d = new Dialect() { - Name = "Oracle", - PathToAssembly = "../../../ServiceStack.OrmLite.Oracle/bin/Debug", - AssemblyName = "ServiceStack.OrmLite.Oracle.dll", - ClassName = "ServiceStack.OrmLite.Oracle.OracleOrmLiteDialectProvider", - InstanceFieldName = "Instance", - ConnectionString = "Data Source=localhost:1521/XE;User ID=servicestack_test;Password=servicestack_test;Unicode=True" - }; - l.Add(d); - - return l; - - } - - private static List BuildAuthorList() - { - - List a = new List(); - a.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); - a.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); - a.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); - a.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); - a.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - a.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - a.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); - a.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); - a.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); - a.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); - a.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); - a.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); - a.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); - a.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico", LastActivity= DateTime.Today }); - return a; - } - - private static void TestDialect(Dialect dialect) - { - Console.Clear(); - Console.WriteLine("Testing expressions for Dialect {0}", dialect.Name); - - OrmLiteConfig.ClearCache(); - OrmLiteConfig.DialectProvider = dialect.DialectProvider; - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (IDbConnection db = dialect.ConnectionString.OpenDbConnection()) - { - try - { - db.DropTable(); - - var tableExists = OrmLiteConfig.DialectProvider.DoesTableExist(db, typeof(Author).Name); - Console.WriteLine("Expected:{0} Selected:{1} {2}", bool.FalseString, tableExists.ToString(), !tableExists ? "OK" : "************** FAILED ***************"); - - db.CreateTable(); - - tableExists = OrmLiteConfig.DialectProvider.DoesTableExist(db, typeof(Author).Name); - Console.WriteLine("Expected:{0} Selected:{1} {2}", bool.TrueString, tableExists.ToString(), tableExists ? "OK" : "************** FAILED ***************"); - - db.DeleteAll(); - Console.WriteLine("Inserting..."); - DateTime t1= DateTime.Now; - db.InsertAll(authors); - DateTime t2= DateTime.Now; - Console.WriteLine("Inserted {0} rows in {1}", authors.Count, t2 - t1); - - Console.WriteLine("Selecting....."); - - int year = DateTime.Today.AddYears(-20).Year; - var lastDay= new DateTime(year, 12, 31); - int expected=5; - - ev.Where().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - Console.WriteLine(ev.ToSelectStatement()); - List result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - Author a = new Author() { Birthday = lastDay }; - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - // select authors from London, Berlin and Madrid : 6 - expected = 6; - //Sql.In can take params object[] - var city="Berlin"; - ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); //clean prev - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - // select authors from Bogota and Cartagena : 7 - expected = 7; - //... or Sql.In can take List - city = "Bogota"; - List cities= new List(); - cities.Add(city); - cities.Add("Cartagena"); - ev.Where().Where(rn => Sql.In(rn.City, cities)); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - - // select authors which name starts with A - expected = 3; - ev.Where().Where(rn => rn.Name.StartsWith("A")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => rn.Name.StartsWith("A")); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected = 3; - var name="GARZON"; - ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected = 3; - ev.Where().Where(rn => rn.Name.EndsWith("garzon")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - - // select authors which name contains Benedict - expected = 2; - name = "Benedict"; - ev.Where().Where(rn => rn.Name.Contains(name)); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - a.Name = name; - result = db.Select(rn => rn.Name.Contains(a.Name)); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - - // select authors with Earnings <= 50 - expected = 3; - var earnings=50; - ev.Where().Where(rn => rn.Earnings <= earnings); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => rn.Earnings <= 50); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - // select authors with Rate = 10 and city=Mexio - expected = 1; - city = "Mexico"; - ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - a.City = city; - result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected = 2; - var rate=0; - ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected = 4; - ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); - ev.Where().Where(rn => !rn.Active); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - //update comment for City == null - expected = 2; - ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); - - // delete where City is null - expected = 2; - rows = db.Delete(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected = 14; - ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - Console.WriteLine(ev.OrderByExpression); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel", author.Name, "Claudia Espinel" == author.Name ? "OK" : "************** FAILED ***************"); - - // select only first 5 rows .... - - expected = 5; - ev.Limit(5); // note: order is the same as in the last sentence - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); - - //paging : - ev.Limit(0, 4);// first page, page size=4; - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); - - ev.Limit(4, 4);// second page - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} Selected:{1} {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); - - ev.Limit(8, 4);// third page - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} Selected:{1} {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); - - // select distinct.. - ev.Limit().OrderBy(); // clear limit, clear order for postres - ev.SelectDistinct(r => r.City); - expected = 6; - result = db.Select(ev); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); - - ev.Select(r=> Sql.As(Sql.Max(r.Birthday), "Birthday")); - result = db.Select(ev); - var expectedResult = authors.Max(r=>r.Birthday); - Console.WriteLine("Expected:{0} Selected {1} {2}",expectedResult, - result[0].Birthday, - expectedResult == result[0].Birthday ? "OK" : "************** FAILED ***************"); - - ev.Select(r=> Sql.As(Sql.Max(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Max(r=>r.Birthday); - Console.WriteLine("Expected:{0} Selected {1} {2}",expectedResult, - result[0].Birthday, - expectedResult == result[0].Birthday ? "OK" : "************** FAILED ***************"); - - - - var r1 = db.Single(ev); - Console.WriteLine("FOD: Expected:{0} Selected {1} {2}",expectedResult, - r1.Birthday, - expectedResult == r1.Birthday ? "OK" : "************** FAILED ***************"); - - - var r2 = db.Scalar( e => Sql.Max(e.Birthday) ); - Console.WriteLine("GetScalar DateTime: Expected:{0} Selected {1} {2}",expectedResult, - r2, - expectedResult == r2 ? "OK" : "************** FAILED ***************"); - - ev.Select(r=> Sql.As( Sql.Min(r.Birthday), "Birthday")); - result = db.Select(ev); - expectedResult = authors.Min(r=>r.Birthday); - Console.WriteLine("Expected:{0} Selected {1} {2}",expectedResult, - result[0].Birthday, - expectedResult == result[0].Birthday? "OK" : "************** FAILED ***************"); - - - - ev.Select(r=> Sql.As( Sql.Min(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Min(r=>r.Birthday); - Console.WriteLine("Expected:{0} Selected {1} {2}",expectedResult, - result[0].Birthday, - expectedResult == result[0].Birthday? "OK" : "************** FAILED ***************"); - - - ev.Select(r=>new{r.City, MaxResult=Sql.As( Sql.Min(r.Birthday), "Birthday") }) - .GroupBy(r=>r.City) - .OrderBy(r=>r.City); - result = db.Select(ev); - var expectedStringResult= "Berlin"; - Console.WriteLine("Expected:{0} Selected {1} {2}",expectedResult, - result[0].City, - expectedStringResult == result[0].City ? "OK" : "************** FAILED ***************"); - - - ev.Select(r=>new{r.City, MaxResult=Sql.As( Sql.Min(r.Birthday), r.Birthday) }) - .GroupBy(r=>r.City) - .OrderBy(r=>r.City); - result = db.Select(ev); - expectedStringResult= "Berlin"; - Console.WriteLine("Expected:{0} Selected {1} {2}",expectedResult, - result[0].City, - expectedStringResult == result[0].City ? "OK" : "************** FAILED ***************"); - - r1 = db.Single(ev); - Console.WriteLine("FOD: Expected:{0} Selected {1} {2}",expectedResult, - r1.City, - expectedStringResult == result[0].City ? "OK" : "************** FAILED ***************"); - - - var expectedDecimal= authors.Max(e=>e.Earnings); - Decimal? r3 = db.Scalar(e=> Sql.Max(e.Earnings)); - Console.WriteLine("GetScalar decimal?: Expected:{0} Selected {1} {2}",expectedDecimal, - r3.Value, - expectedDecimal == r3.Value ? "OK" : "************** FAILED ***************"); - - var expectedString= authors.Max(e=>e.Name); - string r4 = db.Scalar(e=> Sql.Max(e.Name)); - - Console.WriteLine("GetScalar string?: Expected:{0} Selected {1} {2}",expectedString, - r4, - expectedString == r4 ? "OK" : "************** FAILED ***************"); - - var expectedDate= authors.Max(e=>e.LastActivity); - DateTime? r5 = db.Scalar(e=> Sql.Max(e.LastActivity)); - Console.WriteLine("GetScalar datetime?: Expected:{0} Selected {1} {2}", - expectedDate, - r5, - expectedDate == r5 ? "OK" : "************** FAILED ***************"); - - - var expectedDate51= authors.Where(e=> e.City=="Bogota").Max(e=>e.LastActivity); - DateTime? r51 = db.Scalar( - e=> Sql.Max(e.LastActivity), - e=> e.City=="Bogota" ); - - Console.WriteLine("GetScalar datetime?: Expected:{0} Selected {1} {2}", - expectedDate51, - r51, - expectedDate51 == r51 ? "OK" : "************** FAILED ***************"); - - try{ - var expectedBool= authors.Max(e=>e.Active); - bool r6 = db.Scalar(e=> Sql.Max(e.Active)); - Console.WriteLine("GetScalar bool: Expected:{0} Selected {1} {2}",expectedBool, - r6, - expectedBool == r6 ? "OK" : "************** FAILED ***************"); - } - catch(Exception e){ - if(dialect.Name=="PostgreSQL") - Console.WriteLine("OK PostgreSQL: " + e.Message); - else - Console.WriteLine("************** FAILED *************** " + e.Message); - } - - - - // Tests for predicate overloads that make use of the expression visitor - Console.WriteLine("First author by name (exists)"); - author = db.Single(q => q.Name == "Jorge Garzon"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon", author.Name, "Jorge Garzon" == author.Name); - - try - { - Console.WriteLine("First author by name (does not exist)"); - author = db.Single(q => q.Name == "Does not exist"); - - Console.WriteLine("Expected exception thrown, OK? False"); - } - catch - { - Console.WriteLine("Expected exception thrown, OK? True"); - } - - Console.WriteLine("First author or default (does not exist)"); - author = db.Single(q => q.Name == "Does not exist"); - Console.WriteLine("Expected:null ; OK? {0}", author == null); - - Console.WriteLine("First author or default by city (multiple matches)"); - author = db.Single(q => q.City == "Bogota"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Angel Colmenares", author.Name, "Angel Colmenares" == author.Name); - - a.City = "Bogota"; - author = db.Single(q => q.City == a.City); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Angel Colmenares", author.Name, "Angel Colmenares" == author.Name); - - // count test - - var expectedCount= authors.Count(); - long r7 = db.Scalar(e=> Sql.Count(e.Id)); - Console.WriteLine("GetScalar long: Expected:{0} Selected {1} {2}",expectedCount, - r7, - expectedCount == r7 ? "OK" : "************** FAILED ***************"); - - expectedCount= authors.Count(e=> e.City=="Bogota"); - r7 = db.Scalar( - e=> Sql.Count(e.Id), - e=> e.City=="Bogota" ); - - Console.WriteLine("GetScalar long: Expected:{0} Selected {1} {2}",expectedCount, - r7, - expectedCount == r7 ? "OK" : "************** FAILED ***************"); - - - // more updates..... - Console.WriteLine("more updates....................."); - ev.Update();// all fields will be updated - // select and update - expected=1; - var rr= db.Single(rn => rn.Name=="Luis garzon"); - rr.City="Madrid"; - rr.Comments="Updated"; - ev.Where().Where(r=>r.Id==rr.Id); // if omit, then all records will be updated - rows=db.UpdateOnly(rr,ev); // == dbCmd.Update(rr) but it returns void - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); - - expected=0; - ev.Where().Where(r=>r.City=="Ciudad Gotica"); - rows=db.UpdateOnly(rr, ev); - Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); - - expected= db.Select(x=>x.City=="Madrid").Count; - author = new Author(){Active=false}; - rows=db.UpdateOnly(author, x=>x.Active, x=>x.City=="Madrid"); - Console.WriteLine("Expected:{0} Updated:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); - - expected= db.Select(x=>x.Active==false).Count; - rows = db.Delete( x=>x.Active==false); - Console.WriteLine("Expected:{0} Deleted:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); - - DateTime t3= DateTime.Now; - Console.WriteLine("Expressions test in: {0}", t3 - t2); - Console.WriteLine("All test in : {0}", t3 - t1); - - } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - } - - Console.WriteLine("Press enter to return to main menu"); - Console.ReadLine(); - PaintMenu(); - } - } -} diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 000000000..bb03bf89b --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,55 @@ + + + + 6.0.3 + ServiceStack + ServiceStack, Inc. + © 2008-2022 ServiceStack, Inc + $(MSBuildProjectDirectory)/../../NuGet/ + true + https://github.com/ServiceStack/ServiceStack.OrmLite + https://servicestack.net/terms + https://servicestack.net/img/logo-64.png + https://docs.servicestack.net/release-notes-history + git + https://github.com/ServiceStack/ServiceStack.OrmLite.git + embedded + latest + true + true + false + + + + true + true + + + + $(DefineConstants);NETFX;NET45;NET472 + True + False + ../servicestack.snk + + + + $(DefineConstants);NETSTANDARD;NETSTANDARD2_0 + + + + $(DefineConstants);NET6_0;NET6_0_OR_GREATER + + + + $(DefineConstants);NETCORE;NETCORE_SUPPORT + + + + + + + + DEBUG + + + diff --git a/src/Docker/docker-compose.yml b/src/Docker/docker-compose.yml new file mode 100644 index 000000000..a43cac82e --- /dev/null +++ b/src/Docker/docker-compose.yml @@ -0,0 +1,131 @@ +# this file creates docker instances of all the db engines required for running integration tests +# before running tests, from a commandline in this directory type `docker-compose up -d` to start database engines +# to remove all db engines after tesing, type `docker-compose down` + +version: '3' + +services: + + firebird3: + image: "jacobalberty/firebird:3.0.4" + networks: + - servicestack_test + ports: + - "48101:3050" + environment: + FIREBIRD_DATABASE: "test.gdb" + FIREBIRD_USER: "test" + ISC_PASSWORD: "masterkey" + EnableWireCrypt: "true" + + mysql5.5: + image: mariadb:5.5 + networks: + - servicestack_test + ports: + - "48201:3306" + environment: + MYSQL_DATABASE: "test" + MYSQL_USER: "test" + MYSQL_ROOT_PASSWORD: "test" + + mysql10.1: + image: mariadb:10.1 + networks: + - servicestack_test + ports: + - "48202:3306" + environment: + MYSQL_DATABASE: "test" + MYSQL_USER: "test" + MYSQL_ROOT_PASSWORD: "test" + + mysql10.2: + image: mariadb:10.2 + networks: + - servicestack_test + ports: + - "48203:3306" + environment: + MYSQL_DATABASE: "test" + MYSQL_USER: "test" + MYSQL_ROOT_PASSWORD: "test" + + mysql10.3: + image: mariadb:10.3 + networks: + - servicestack_test + ports: + - "48204:3306" + environment: + MYSQL_DATABASE: "test" + MYSQL_USER: "test" + MYSQL_ROOT_PASSWORD: "test" + + mysql10.4: + image: mariadb:10.4 + networks: + - servicestack_test + ports: + - "48205:3306" + environment: + MYSQL_DATABASE: "test" + MYSQL_USER: "test" + MYSQL_ROOT_PASSWORD: "test" + + postgres9: + image: postgres:9-alpine + networks: + - servicestack_test + ports: + - "48301:5432" + environment: + POSTGRES_USER: "test" + POSTGRES_DB: "test" + POSTGRES_PASSWORD: "test" + + postgres10: + image: postgres:10-alpine + networks: + - servicestack_test + ports: + - "48302:5432" + environment: + POSTGRES_USER: "test" + POSTGRES_DB: "test" + POSTGRES_PASSWORD: "test" + + postgres11: + image: postgres:11-alpine + networks: + - servicestack_test + ports: + - "48303:5432" + environment: + POSTGRES_USER: "test" + POSTGRES_DB: "test" + POSTGRES_PASSWORD: "test" + + oracle11: + image: epiclabs/docker-oracle-xe-11g + networks: + - servicestack_test + ports: + - "48401:1521" + environment: + ORACLE_ALLOW_REMOTE: "true" + ORACLE_PASSWORD : "test" + + MSSqlServer2019: + image: mcr.microsoft.com/mssql/server:2019-latest + networks: + - servicestack_test + ports: + - "48501:1433" + environment: + MSSQL_PID: "Express" + ACCEPT_EULA: "Y" + SA_PASSWORD : "Test!tesT" + +networks: + servicestack_test: \ No newline at end of file diff --git a/src/Docker/ormlite-docker.gif b/src/Docker/ormlite-docker.gif new file mode 100644 index 000000000..79fdd6528 Binary files /dev/null and b/src/Docker/ormlite-docker.gif differ diff --git a/src/Docker/readme.md b/src/Docker/readme.md new file mode 100644 index 000000000..811130704 --- /dev/null +++ b/src/Docker/readme.md @@ -0,0 +1,37 @@ +# Docker database server instances for testing + +This directory contains a docker compose file that can be used to create database server instances for running tests that do not support embedded instances. The list of db servers created is below. + +To use, you must first have docker and docker compose installed. + +## To spin up all the database servers, run the following + +```bash +$> docker-compose up -d +``` + +## To remove/teardown the database servers, run the following + +```bash +$> docker-compose down +``` + +## Database servers created + +|Database|Version|Port|DbName|DbUser|DbPwd| +|--------|-------|----|------|------|-----| +|Firebird|3.0.4|48101|test|test|test|masterkey| +|MySql (mariaDb)|5.5.x|48201|test|root|test| +|MySql (mariaDb)|10.1.x|48202|test|root|test| +|MySql (mariaDb)|10.2.x|48203|test|root|test| +|MySql (mariaDb)|10.3.x|48204|test|root|test| +|MySql (mariaDb)|10.4.x|48205|test|root|test| +|Postgres|9.x|48301|test|test|test| +|Postgres|10.x|48302|test|test|test| +|Postgres|11.x|48303|test|test|test| +|Oracle XE|11.x|48401|SID: xe|system|test| +|MS SQL Server Express|2019.x|48501|master|sa|Test!tesT| + +## What it looks like in action... + +![Example](ormlite-docker.gif) \ No newline at end of file diff --git a/src/Docker/servicestack-ci/docker-compose.yml b/src/Docker/servicestack-ci/docker-compose.yml new file mode 100644 index 000000000..cd057cdd9 --- /dev/null +++ b/src/Docker/servicestack-ci/docker-compose.yml @@ -0,0 +1,99 @@ +# this file creates docker instances of all the db engines required for running integration tests +# before running tests, from a commandline in this directory type `docker-compose up -d` to start database engines +# to remove all db engines after tesing, type `docker-compose down` + +version: '3' + +services: + + firebird3: + image: "jacobalberty/firebird:3.0.4" + ports: + - "48101:3050" + environment: + FIREBIRD_DATABASE: "test.gdb" + FIREBIRD_USER: "test" + ISC_PASSWORD: "masterkey" + EnableWireCrypt: "true" + + mysql10.4: + image: mariadb:10.4 + ports: + - "48205:3306" + environment: + MYSQL_DATABASE: "test" + MYSQL_USER: "test" + MYSQL_ROOT_PASSWORD: "test" + + postgres11: + image: postgres:11-alpine + ports: + - "48303:5432" + environment: + POSTGRES_USER: "test" + POSTGRES_DB: "test" + POSTGRES_PASSWORD: "test" + + oracle11: + image: epiclabs/docker-oracle-xe-11g + ports: + - "48401:1521" + environment: + ORACLE_ALLOW_REMOTE: "true" + ORACLE_PASSWORD : "test" + + MSSqlServer2017: + image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu + ports: + - "48501:1433" + environment: + MSSQL_PID: "Express" + ACCEPT_EULA: "Y" + SA_PASSWORD : "Test!tesT" + + redis: + image: redis + ports: + - "6379:6379" + volumes: + - "./data:/data" + command: redis-server --appendonly yes + + dynamodb: + image: amazon/dynamodb-local + ports: + - "48000:8000" + + rabbitmq: + image: rabbitmq:3.7.5-management + hostname: app-rabbitmq + ports: + - 45672:5672 + - 41672:15672 + volumes: + - ./data/rabbitmq:/var/lib/rabbitmq/mnesia/rabbit@app-rabbitmq:cached + environment: + RABBITMQ_ERLANG_COOKIE: 6085e2412b6fa88647466c6a81c0cea0 + RABBITMQ_DEFAULT_USER: guest + RABBITMQ_DEFAULT_PASS: guest + RABBITMQ_DEFAULT_VHOST: / + + server: + image: jetbrains/teamcity-server + ports: + - "2080:8111" + volumes: + - /root/docker/teamcity/server/data:/data/teamcity_server/datadir + - /root/docker/teamcity/server/logs:/opt/teamcity/logs + + ci-agent: + image: servicestack/ci-agent + volumes: + - /root/docker/build/ci-agent/conf:/data/teamcity_agent/conf + environment: + SERVER_URL: https://build.servicestack.net + + +networks: + default: + driver: bridge \ No newline at end of file diff --git a/src/FirebirdTests/TestClassWriter/AssemblyInfo.cs b/src/FirebirdTests/TestClassWriter/AssemblyInfo.cs deleted file mode 100644 index 62b79e3a1..000000000 --- a/src/FirebirdTests/TestClassWriter/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestClassWriter")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestClassWriter/Main.cs b/src/FirebirdTests/TestClassWriter/Main.cs deleted file mode 100644 index c2481d904..000000000 --- a/src/FirebirdTests/TestClassWriter/Main.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.IO; -using System.CodeDom.Compiler; -using Microsoft.CSharp; -using System.Collections.Generic; -using System.Data; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - -namespace TestClassWriter -{ - class MainClass - { - public static void Main (string[] args) - { - - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - using ( IDbCommand dbConn = db.CreateCommand()) - { - Schema fbd= new Schema(){ - Connection = db - }; - - ClassWriter cw = new ClassWriter(){ - Schema=fbd, - GenerateMetadata=true, - //SpaceName= "your.app.namespace", - //OutputDirectory="outputpath" - //Usings="Using System;\nUsing System.Data\n" - }; - - foreach(var t in fbd.Tables){ - Console.Write("Generating POCO Class for table:'{0}'...", t.Name); - cw.WriteClass( t); - Console.WriteLine(" Done."); - } - Console.WriteLine("---------------------------------"); - Console.WriteLine("See classes in: '{0}'", cw.OutputDirectory); - - //compilar ... - CompilerParameters cp = new CompilerParameters(); - cp.GenerateExecutable=false; - cp.GenerateInMemory=false; - cp.ReferencedAssemblies.AddRange( - new string[]{ - "System.dll", - "System.ComponentModel.DataAnnotations.dll", - Path.Combine( Directory.GetCurrentDirectory(), "ServiceStack.OrmLite.dll"), - Path.Combine( Directory.GetCurrentDirectory(), "ServiceStack.Common.dll"), - Path.Combine( Directory.GetCurrentDirectory(),"ServiceStack.Interfaces.dll") - }); - cp.OutputAssembly= Path.Combine(cw.OutputDirectory, cw.SpaceName+".dll"); - - var providerOptions = new Dictionary(); - providerOptions.Add("CompilerVersion", "v3.5"); - - CodeDomProvider cdp =new CSharpCodeProvider(providerOptions); - - string [] files = Directory.GetFiles(cw.OutputDirectory,"*.cs"); - CompilerResults cr= cdp.CompileAssemblyFromFile(cp, files); - - if( cr.Errors.Count==0){ - Console.WriteLine("Generated file {0}", Path.Combine(cw.OutputDirectory, cw.SpaceName+".dll")); - } - else{ - foreach (CompilerError ce in cr.Errors) - Console.WriteLine(ce.ErrorText); - } - - - - - } - - - Console.WriteLine ("This is The End my friend!"); - - } - } -} diff --git a/src/FirebirdTests/TestClassWriter/TestClassWriter.csproj b/src/FirebirdTests/TestClassWriter/TestClassWriter.csproj deleted file mode 100644 index 2e10d22c7..000000000 --- a/src/FirebirdTests/TestClassWriter/TestClassWriter.csproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {85DF0278-488D-460B-8B40-737E07089465} - Exe - TestClassWriter - TestClassWriter - v4.0 - - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestClassWriter/app.config b/src/FirebirdTests/TestClassWriter/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/FirebirdTests/TestClassWriter/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/FirebirdTests/TestExpression02/AssemblyInfo.cs b/src/FirebirdTests/TestExpression02/AssemblyInfo.cs deleted file mode 100644 index 791856539..000000000 --- a/src/FirebirdTests/TestExpression02/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestExpression02")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestExpression02/Main.cs b/src/FirebirdTests/TestExpression02/Main.cs deleted file mode 100644 index 7c6c6ac1f..000000000 --- a/src/FirebirdTests/TestExpression02/Main.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace TestExpression02 -{ - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - } - } -} diff --git a/src/FirebirdTests/TestExpression02/TestExpression02.csproj b/src/FirebirdTests/TestExpression02/TestExpression02.csproj deleted file mode 100644 index 977342fcb..000000000 --- a/src/FirebirdTests/TestExpression02/TestExpression02.csproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F} - Exe - TestExpression02 - TestExpression02 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - - - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestExpressions/AssemblyInfo.cs b/src/FirebirdTests/TestExpressions/AssemblyInfo.cs deleted file mode 100644 index 4002f55ad..000000000 --- a/src/FirebirdTests/TestExpressions/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestExpressions")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestExpressions/Main.cs b/src/FirebirdTests/TestExpressions/Main.cs deleted file mode 100644 index 4539f8684..000000000 --- a/src/FirebirdTests/TestExpressions/Main.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - - -namespace TestExpressions -{ - public class Author - { - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - public DateTime Birthday { get; set;} - public DateTime ? LastActivity { get; set;} - public Decimal? Earnings { get; set;} - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - public Int16 Rate{ get; set;} - } - - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.DeleteAll(); - - List authors = new List(); - authors.Add(new Author(){Name="Demis Bellot",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 99.9m,Comments="CSharp books", Rate=10, City="London"}); - authors.Add(new Author(){Name="Angel Colmenares",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 50.0m,Comments="CSharp books", Rate=5, City="Bogota"}); - authors.Add(new Author(){Name="Adam Witco",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 80.0m,Comments="Math Books", Rate=9, City="London"}); - authors.Add(new Author(){Name="Claudia Espinel",Birthday= DateTime.Today.AddYears(-23),Active=true,Earnings= 60.0m,Comments="Cooking books", Rate=10, City="Bogota"}); - authors.Add(new Author(){Name="Libardo Pajaro",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 80.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Jorge Garzon",Birthday= DateTime.Today.AddYears(-28),Active=true,Earnings= 70.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Alejandro Isaza",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 70.0m,Comments="Java books", Rate=0, City="Bogota"}); - authors.Add(new Author(){Name="Wilmer Agamez",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 30.0m,Comments="Java books", Rate=0, City="Cartagena"}); - authors.Add(new Author(){Name="Rodger Contreras",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 90.0m,Comments="CSharp books", Rate=8, City="Cartagena"}); - authors.Add(new Author(){Name="Chuck Benedict",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="CSharp books", Rate=8, City="London"}); - authors.Add(new Author(){Name="James Benedict II",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="Java books", Rate=5, City="Berlin"}); - authors.Add(new Author(){Name="Ethan Brown",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 45.0m,Comments="CSharp books", Rate=5, City="Madrid"}); - authors.Add(new Author(){Name="Xavi Garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 75.0m,Comments="CSharp books", Rate=9, City="Madrid"}); - authors.Add(new Author(){Name="Luis garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.0m,Comments="CSharp books", Rate=10, City="Mexico"}); - - db.InsertAll(authors); - - - // lets start ! - - // select authors born 20 year ago - int year = DateTime.Today.AddYears(-20).Year; - int expected=5; - - ev.Where(rn=> rn.Birthday>=new DateTime(year, 1,1) && rn.Birthday<=new DateTime(year, 12,31)); - List result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31))); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors from London, Berlin and Madrid : 6 - expected=6; - //Sql.In can take params object[] - ev.Where(rn=> Sql.In( rn.City, new object[]{"London", "Madrid", "Berlin"}) ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors from Bogota and Cartagena : 7 - expected=7; - //... or Sql.In can take IList - List cities= new List(); - cities.Add("Bogota"); - cities.Add("Cartagena"); - ev.Where(rn => Sql.In(rn.City, cities )); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors which name starts with A - expected=3; - ev.Where(rn=> rn.Name.StartsWith("A") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.ToUpper().EndsWith("GARZON") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.EndsWith("garzon") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors which name contains Benedict - expected=2; - ev.Where(rn=> rn.Name.Contains("Benedict") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors with Earnings <= 50 - expected=3; - ev.Where(rn=> rn.Earnings<=50 ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors with Rate = 10 and city=Mexio - expected=1; - ev.Where(rn=> rn.Rate==10 && rn.City=="Mexico"); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected=2; - ev.Where(rn=> rn.Rate==0 ).Update(rn=> rn.Active); - var rows = db.UpdateOnly( new Author(){ Active=false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected=4; - ev.Insert(rn =>new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate} ); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Victor Grozny", Birthday=DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Ivan Chorny", Birthday=DateTime.Today.AddYears(-19) }, ev); - ev.Where(rn=> !rn.Active); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - //update comment for City == null - expected=2; - ev.Where( rn => rn.City==null ).Update(rn=> rn.Comments); - rows=db.UpdateOnly(new Author(){Comments="No comments"}, ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // delete where City is null - expected=2; - rows = db.Delete( ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected=14; - ev.Where().OrderBy(rn=> new{ at=Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - Console.WriteLine(ev.OrderByExpression); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel", author.Name, "Claudia Espinel"==author.Name); - - // select only first 5 rows .... - - expected=5; - ev.Limit(5); // note: order is the same as in the last sentence - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn=> new { at= Sql.As( rn.Name.ToUpper(), "Name" ), rn.City} ); - Console.WriteLine(ev.SelectExpression); - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - //paging : - ev.Limit(0,4);// first page, page size=4; - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - ev.Limit(4,4);// second page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper()==author.Name); - - ev.Limit(8,4);// third page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper()==author.Name); - - - // select distinct.. - ev.Limit(); // clear limit - ev.SelectDistinct(r=>r.City); - expected=6; - result=db.Select(ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - Console.ReadLine(); - Console.WriteLine("Press Enter to continue"); - - } - - Console.WriteLine ("This is The End my friend!"); - } - } -} diff --git a/src/FirebirdTests/TestExpressions/TestExpressions.csproj b/src/FirebirdTests/TestExpressions/TestExpressions.csproj deleted file mode 100644 index 6e4fc7c44..000000000 --- a/src/FirebirdTests/TestExpressions/TestExpressions.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {80896749-19C6-437C-8852-F07243AA5F59} - Exe - TestExpressions - TestExpressions - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestLiteFirebird00/AssemblyInfo.cs b/src/FirebirdTests/TestLiteFirebird00/AssemblyInfo.cs deleted file mode 100644 index 316af1e89..000000000 --- a/src/FirebirdTests/TestLiteFirebird00/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestLiteFirebird00")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestLiteFirebird00/Main.cs b/src/FirebirdTests/TestLiteFirebird00/Main.cs deleted file mode 100644 index bf809a5c2..000000000 --- a/src/FirebirdTests/TestLiteFirebird00/Main.cs +++ /dev/null @@ -1,229 +0,0 @@ -using System; -using System.Linq; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - - -namespace TestLiteFirebird00 -{ - - public class Author{ - - public Author(){ - } - - [AutoIncrement] - //[Sequence("Author_Id_GEN")] - public Int32 Id { get; set;} - - [Required] - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - - [Required] - public DateTime Birthday { get; set;} - - public DateTime ? LastActivity { get; set;} - - public Decimal? Earnings { get; set;} // Precision=18, scale=12 default values - - //[Alias("Active")] // Active Firebird Reserved ? - public bool Active { get; set; } - - [StringLength(80)] - public string City { get; set;} - - [StringLength(80)] - public string Comments { get; set;} - - public Int16 Rate{ get; set;} - - - } - - public class Book{ - - public Book(){ - } - - [AutoIncrement] - //[Sequence("Book_Id_GEN")] - public Int32 Id { get; set;} - - [References(typeof(Author))] - public Int32 IdAuthor {get; set;} - - [StringLength(80)] - public string Title {get; set;} - [DecimalLength(15,2)] - public Decimal Price { get; set;} // Precision= 15, Scale=2 - - } - - - class MainClass - { - public static void Main (string[] args) - { - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - { - //try{ - // due to firebirdslq features, we have to drop book first and then author - db.DropTable(); - db.DropTable(); - - db.CreateTable(); - db.CreateTable(); - - db.Insert( new Author(){ - Name="Demis Bellot", - Birthday= DateTime.Today.AddYears(20), - Active=true, - Earnings= 99.9m, - Comments="ServiceStack.Net ...", - City="London", - Rate=10 - }); - - db.Insert( new Author(){ - Name="Angel Colmenares", - Birthday= DateTime.Today.AddYears(30), - Active=true, - Earnings= 50.25m, - Comments="OrmLite.Firebird", - City="Bogota", - Rate=9 - }); - - db.Insert( new Author(){ - Name="Adam Witco", - Birthday= DateTime.Today.AddYears(25), - Active=true, - Comments="other books...", - City="London", - Rate=8 - }); - - - db.Insert( new Author(){ - Name="Claudia Espinel", - Birthday= DateTime.Today.AddYears(28), - Active=false, - Comments="other books...", - City="Bogota", - Rate=10 - }); - - //------------------------------------------------------------------- - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - ev.Insert(r=> new {r.Id, r.Name, r.Birthday, r.Active, r.Rate}); // fields to insert - - var author = new Author(){ - Name="William", - Birthday= DateTime.Today.AddYears(250), - Active=false, - City="London", - Rate= 0, - Comments="this will not be inserted" // null in db - }; - - db.InsertOnly(author, ev); - - author.Comments="this will be updated"; - - ev.Update(rn=> rn.Comments).Where(r=>r.Id==author.Id); - db.UpdateOnly(author, ev); - - - // update comment for all authors from london... - - author.Comments="update from london"; - ev.Where(rn=> rn.City=="London"); - db.UpdateOnly(author, ev); - - // select author from Bogota - ev.Where(rn=> rn.City=="Bogota"); - var authors = db.Select(ev); - Console.WriteLine(authors.Count); - - // select author from Bogota and Active=true; - - ev.Where(rn=> rn.City=="Bogota" && rn.Active==true); // sorry for firebird must write ==true ! - authors = db.Select(ev); - Console.WriteLine(authors.Count); - - //------------------------------------------------------------------- - authors = db.Select(); - - Console.WriteLine("Rows in Author : '{0}'",authors.Count); - - foreach(Author a in authors){ - Console.WriteLine("Id :{0} - Name : {1} -- Earnings {2}", a.Id, - a.Name, - a.Earnings.HasValue? a.Earnings.Value: 0.0m); - } - - author= authors.FirstOrDefault(r=>r.Name=="Angel Colmenares"); - if( author != default(Author) ){ - - db.Insert( new Book(){ - IdAuthor= author.Id, - Title= "The big book", - Price= 18.55m, - }); - Console.WriteLine("{0} == {1}", db.Exists(author), true ) ; - } - else{ - Console.WriteLine("Something wrong "); - } - - - author= authors.FirstOrDefault(r=>r.Name=="Adam Witco"); - if( author != default(Author) ){ - - - Console.WriteLine("{0} == {1}", db.Exists(author), false ) ; - } - else{ - Console.WriteLine("Something wrong "); - } - - var books = db.Select(); - - foreach(var b in books){ - Console.WriteLine("Title {0} Price {1}",b.Title, b.Price); - } - - ev.Select(r=>new { r.Name, r.Active}).Where(); // only Name and Active fields will be retrived - - authors = db.Select(ev); - Console.WriteLine(ev.SelectExpression); - - foreach(Author r in authors){ - Console.WriteLine("'{0}' '{1}' '{2}'", r.Name, r.Active, r.Id); - } - - - db.DeleteAll(); - db.DeleteAll(); - - - //} - - //catch(Exception e){ - // Console.WriteLine("Error : " + e.Message); - // return; - //} - Console.WriteLine("This is The End my friend !"); - - } - } - } -} \ No newline at end of file diff --git a/src/FirebirdTests/TestLiteFirebird00/TestLiteFirebird00.csproj b/src/FirebirdTests/TestLiteFirebird00/TestLiteFirebird00.csproj deleted file mode 100644 index 954f97bc2..000000000 --- a/src/FirebirdTests/TestLiteFirebird00/TestLiteFirebird00.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66} - Exe - TestLiteFirebird00 - TestLiteFirebird00 - v4.0 - - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestLiteFirebird00/app.config b/src/FirebirdTests/TestLiteFirebird00/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/FirebirdTests/TestLiteFirebird00/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/FirebirdTests/TestLiteFirebird04/AssemblyInfo.cs b/src/FirebirdTests/TestLiteFirebird04/AssemblyInfo.cs deleted file mode 100644 index 361e02330..000000000 --- a/src/FirebirdTests/TestLiteFirebird04/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestLiteFirebird04")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestLiteFirebird04/Company.cs b/src/FirebirdTests/TestLiteFirebird04/Company.cs deleted file mode 100644 index 082f3f07a..000000000 --- a/src/FirebirdTests/TestLiteFirebird04/Company.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace Database.Records -{ - [Alias("COMPANY")] - public partial class Company:IHasId{ - - public Company(){} - - [Alias("ID")] - [Sequence("COMPANY_ID_GEN")] - [PrimaryKey] - [AutoIncrement] - public System.Int32 Id { get; set;} - - [Alias("NAME")] - public System.String Name { get; set;} - - [Alias("TURNOVER")] - public System.Single? Turnover { get; set;} - - [Alias("STARTED")] - public System.DateTime? Started { get; set;} - - [Alias("EMPLOYEES")] - public System.Int32? Employees { get; set;} - - [Alias("CREATED_DATE")] - public System.DateTime? CreatedDate { get; set;} - - [Alias("GUID")] - public System.Guid? Guid { get; set;} - - [Alias("SOMEDOUBLE")] - public Double SomeDouble { get; set;} - - [Alias("SOMEBOOL")] - public bool SomeBoolean { get; set;} - - - public static class Me { - - public static string TableName { get { return "COMPANY"; }} - public static string Id { get { return "ID"; }} - public static string Name { get { return "NAME"; }} - public static string Turnover { get { return "TURNOVER"; }} - public static string Started { get { return "STARTED"; }} - public static string Employees { get { return "EMPLOYEES"; }} - public static string CreatedDate { get { return "CREATED_DATE"; }} - public static string Guid { get { return "GUID"; }} - - } - } -} \ No newline at end of file diff --git a/src/FirebirdTests/TestLiteFirebird04/DbMethodsIn.cs b/src/FirebirdTests/TestLiteFirebird04/DbMethodsIn.cs deleted file mode 100644 index c5c5a7082..000000000 --- a/src/FirebirdTests/TestLiteFirebird04/DbMethodsIn.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Collections.Generic; -namespace ServiceStack.OrmLite -{ - public static class DbMethods - { - public static bool In(this T value, IList list) { - foreach( Object obj in list){ - if(obj==null || value==null ) continue; - if( obj.ToString() == value.ToString() ) return true; - } - return false; - } - - public static string Desc(this T value) { - return value==null? "": value.ToString() + " DESC"; - } - - public static string As(this T value, string asValue) { - return value==null? "": string.Format("{0} AS {1}", value.ToString(), asValue); - } - - public static T Sum(this T value) { - return value; - } - - public static T Count(this T value) { - return value; - } - - public static T Min(this T value) { - return value; - } - - public static T Avg(this T value) { - return value; - } - } - -} - -//class DbMehods.In, As , Desc, Sum, Count : methdos DbMethodName - -/* - public static T Sum(params T[] args) where T: struct - { - - T total = default(T); - Func addMethod = CreateAdd(); - - foreach (T val in args) - { - total = addMethod(total, val); - } - - return total; - } - - - private static Func CreateAdd() - { - ParameterExpression lhs = Expression.Parameter(typeof(T), "lhs"); - ParameterExpression rhs = Expression.Parameter(typeof(T), "rhs"); - Expression> addExpr = Expression>. - - Lambda>( - Expression.Add(lhs, rhs), - new ParameterExpression[] { lhs, rhs }); - - Func addMethod = addExpr.Compile(); - - return addMethod; - } - - } -*/ \ No newline at end of file diff --git a/src/FirebirdTests/TestLiteFirebird04/Main.cs b/src/FirebirdTests/TestLiteFirebird04/Main.cs deleted file mode 100644 index 7aa12ead6..000000000 --- a/src/FirebirdTests/TestLiteFirebird04/Main.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - -using Database.Records; - -namespace TestLiteFirebird04 -{ - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - ServiceStack.OrmLite.SqlExpression sql = - OrmLiteConfig.DialectProvider.SqlExpression(); - - List names = new List(); - names.Add("SOME COMPANY"); - names.Add("XYZ"); - - - List ids = new List(); - ids.Add(1); - ids.Add(2); - - Company company = new Company(){ Id=1, Name ="XYZ"}; - Console.WriteLine( company.Id.In(ids) ); - Console.WriteLine( company.Name.In(names) ); - - - sql.Where( cp => cp.Name == "On more Company"); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => cp.Name != "On more Company"); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => cp.Name == null ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => cp.Name != null); - Console.WriteLine(sql.WhereExpression); - - - - sql.Where( cp => cp.SomeBoolean); // TODO : fix - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => !cp.SomeBoolean && 1==1); //TODO : fix - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => cp.SomeBoolean && 1==1); //TODO : fix - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => 1 == 1 ); // TODO : fix ? - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => "1"== "1"); // TODO : fix ? - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => "1"== "0"); // TODO : fix ? - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => 1 != 1); //ok - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => cp.SomeBoolean==true); //OK - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => cp.SomeBoolean==false); //OK - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => !cp.SomeBoolean); // OK - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => (cp.Name==cp.Name) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => (cp.Name=="On more Company" || cp.Id>30) ); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => (cp.CreatedDate== DateTime.Today )); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => (cp.CreatedDate==DateTime.Today && (cp.Name=="On more Company" || cp.Id>30)) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ( cp.Name.ToUpper()=="ONE MORE COMPANY" )); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ( cp.Name.ToLower()=="ONE MORE COMPANY".ToLower() ) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ( cp.Name.ToLower().StartsWith("one") ) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ( cp.Name.ToUpper().EndsWith("COMPANY") ) ); - Console.WriteLine(sql.WhereExpression); - sql.Where( cp => ( cp.Name.ToUpper().Contains("MORE") ) ); - Console.WriteLine(sql.WhereExpression); - sql.Where( cp => ( cp.Name.Substring(0)=="ONE MORE COMPANY") ); - Console.WriteLine(sql.WhereExpression); - sql.Where( cp => ( cp.Name.ToUpper().Substring(0,7)=="ONE MOR" )); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => (cp.CreatedDate>= new DateTime(2000,1,1 ) ) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => (cp.Employees/2 > 10.0 ) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => (cp.Employees*2 > 10.0/5 )); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ((cp.Employees+3) > (10.0+5) ) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ((cp.Employees-3) > (10.0+5) ) ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => (( cp.Employees%3) > (10.0+5)) ); - Console.WriteLine(sql.WhereExpression); - - - - sql.Where( cp => ( Math.Round( cp.SomeDouble) > (10.0+5) ) ); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( Math.Round( cp.SomeDouble,3) > (10.0+5) ) ); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( Math.Floor( cp.SomeDouble) > (10.0+5) ) ); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( Math.Ceiling( cp.SomeDouble) > (10.0+5) ) ); - Console.WriteLine(sql.WhereExpression); - - - - sql.Where( cp => ( string.Concat( cp.SomeDouble, "XYZ") =="SOME COMPANY XYZ") ); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ( string.Concat( cp.SomeDouble, "X", "Y","Z") =="SOME COMPANY XYZ")); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( string.Concat( cp.Name, "X", "Y","Z") =="SOME COMPANY XYZ")); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ( string.Concat( cp.SomeDouble.ToString(), "X", "Y","Z") =="SOME COMPANY XYZ")); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( (cp.CreatedDate ?? DateTime.Today) == DateTime.Today)); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( (cp.Turnover ?? 0 )> 15)); - Console.WriteLine(sql.WhereExpression); - - sql.Where( cp => ( Math.Abs(cp.Turnover ?? 0 )> 15)); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( Sql.In( cp.Name, names ) )); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => ( Sql.In( cp.Id, ids ) )); - Console.WriteLine(sql.WhereExpression); - - - sql.OrderBy(cp=> cp.Name); - Console.WriteLine("{0}",sql.OrderByExpression); - - sql.OrderBy(cp=> new{cp.Name, cp.Id} ); - Console.WriteLine("{0}", sql.OrderByExpression); - - sql.OrderBy(cp=> new{cp.Name, Id=cp.Id*-1} ); - Console.WriteLine("{0}", sql.OrderByExpression); - - sql.OrderByDescending(cp=> cp.Name); - Console.WriteLine("{0}",sql.OrderByExpression); - - sql.OrderBy(cp=> new{cp.Name, X=cp.Id.Desc() } ); - Console.WriteLine("{0}", sql.OrderByExpression); - - - sql.Where( cp => ( string.Concat( cp.Name, "_", cp.Employees) =="SOME COMPANY XYZ_2")); - Console.WriteLine(sql.WhereExpression); - - - sql.Where( cp => cp.Id != 1); - Console.WriteLine(sql.WhereExpression); - - - sql.Select(cp=>new{cp.Employees, cp.Name}); - Console.WriteLine("To Select:'{0}' ",sql.SelectExpression); - - sql.Select(cp=>new{cp.Employees, cp.Name, Some=(cp.Id*4).As("SomeExpression")}); - Console.WriteLine("To Select:'{0}' ",sql.SelectExpression); - - sql.Select(cp=>new{cp.Employees, cp.Name, Some=cp.Turnover.Sum().As("SomeExpression")}); - Console.WriteLine("To Select:'{0}' ",sql.SelectExpression); - - sql.Select(cp=>new{cp.Employees, cp.Name, Some=DbMethods.Sum(cp.Turnover ?? 0).As("SomeExpression")}); - Console.WriteLine("To Select:'{0}' ",sql.SelectExpression); - - sql.Update(cp=> new{cp.Employees,cp.Name} ); - Console.WriteLine("To Update:'{0}' ", string.Join(",", sql.UpdateFields.ToArray() ) ); - - sql.Insert(cp=> new{cp.Id, cp.Employees,cp.Name} ); - Console.WriteLine("To Insert:'{0}' ", string.Join(",", sql.InsertFields.ToArray()) ); - - - Console.WriteLine ("This is The End my friend!"); - - - } - } -} - diff --git a/src/FirebirdTests/TestLiteFirebird04/TestLiteFirebird04.csproj b/src/FirebirdTests/TestLiteFirebird04/TestLiteFirebird04.csproj deleted file mode 100644 index cccb63334..000000000 --- a/src/FirebirdTests/TestLiteFirebird04/TestLiteFirebird04.csproj +++ /dev/null @@ -1,74 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A} - Exe - TestLiteFirebird04 - TestLiteFirebird04 - v4.0 - - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestLiteFirebird04/app.config b/src/FirebirdTests/TestLiteFirebird04/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/FirebirdTests/TestLiteFirebird04/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/FirebirdTests/TestSimpleFirebird01/AssemblyInfo.cs b/src/FirebirdTests/TestSimpleFirebird01/AssemblyInfo.cs deleted file mode 100644 index 875d4c3ab..000000000 --- a/src/FirebirdTests/TestSimpleFirebird01/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebird01")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestSimpleFirebird01/Main.cs b/src/FirebirdTests/TestSimpleFirebird01/Main.cs deleted file mode 100644 index 342e8ca3a..000000000 --- a/src/FirebirdTests/TestSimpleFirebird01/Main.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - -namespace TestLiteFirebird01 -{ - - [Alias("USERS")] - public class User - { - - [Alias("ID")] - [Sequence("USERS_ID_GEN")] - public int Id { get; set; } - [Alias("NAME")] - public string Name { get; set; } - [Alias("PASSWORD")] - public string Password { get; set; } - [Alias("COL1")] - public string Col1 { get; set; } - [Alias("COL2")] - public string Col2 { get; set; } - [Alias("COL3")] - public string Col3 { get; set; } - - [Alias("ACTIVEINTEGER")] - public bool Active { get; set; } - - [Alias("ACTIVECHAR")] - public bool Active2 { get; set; } - - [Ignore] - public string SomeStringProperty { - get{ return "SomeValue No from dB!!!";} - } - - [Ignore] - public Int32 SomeInt32Property { - get{ return 35;} - } - - [Ignore] - public DateTime SomeDateTimeProperty { - get{ return DateTime.Now ;} - } - - [Ignore] - public Int32? SomeInt32NullableProperty { - get{ return null;} - } - - [Ignore] - public DateTime? SomeDateTimeNullableProperty { - get{ return null ;} - } - - - - } - - class MainClass - { - public static void Main (string[] args) - { - - - //Set one before use (i.e. in a static constructor). - - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - { - //try{ - - - db.Insert(new User - { - Name= string.Format("Hello, World! {0}", DateTime.Now), - Password="jkkoo", - Col1="01", - Col2="02", - Col3="03" - - }); - - User user = new User(){ - Name="New User ", - Password= "kka", - Col1="XX", - Col2="YY", - Col3="ZZ", - Active=true - }; - - - db.Insert(user); - - Console.WriteLine("++++++++++Id for {0} {1}",user.Name, user.Id); - - - var rows = db.Select(); - - Console.WriteLine("++++++++++++++records in users {0}", rows.Count); - foreach(User u in rows){ - Console.WriteLine("{0} -- {1} -- {2} -- {3} -{4} --{5} ", u.Id, u.Name, u.SomeStringProperty, u.SomeDateTimeProperty, - (u.SomeInt32NullableProperty.HasValue)?u.SomeDateTimeNullableProperty.Value.ToString(): "", - u.Active); - db.Delete(u); - } - - rows = db.Select(); - - Console.WriteLine("-------------records in users after delete {0}", rows.Count); - - //} - - //catch(Exception e){ - // Console.WriteLine(e); - //} - } - - } - } -} - diff --git a/src/FirebirdTests/TestSimpleFirebird01/TestLiteFirebird01.csproj b/src/FirebirdTests/TestSimpleFirebird01/TestLiteFirebird01.csproj deleted file mode 100644 index 6466fcff6..000000000 --- a/src/FirebirdTests/TestSimpleFirebird01/TestLiteFirebird01.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003} - Exe - TestSimpleFirebird01 - TestSimpleFirebird01 - v4.0 - - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestSimpleFirebird01/app.config b/src/FirebirdTests/TestSimpleFirebird01/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/FirebirdTests/TestSimpleFirebird01/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/FirebirdTests/TestSimpleFirebird02/AssemblyInfo.cs b/src/FirebirdTests/TestSimpleFirebird02/AssemblyInfo.cs deleted file mode 100644 index 017906d02..000000000 --- a/src/FirebirdTests/TestSimpleFirebird02/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebird02")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestSimpleFirebird02/Company.cs b/src/FirebirdTests/TestSimpleFirebird02/Company.cs deleted file mode 100644 index 7a9b9a8ba..000000000 --- a/src/FirebirdTests/TestSimpleFirebird02/Company.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; - -using ServiceStack.Common; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; -using ServiceStack.OrmLite; - -namespace Database.Records -{ - [Alias("COMPANY")] - public partial class Company:IHasId{ - - public Company(){} - - [Alias("ID")] - [Sequence("COMPANY_ID_GEN")] - [PrimaryKey] - [AutoIncrement] - public System.Int32 Id { get; set;} - - [Alias("NAME")] - public System.String Name { get; set;} - - [Alias("TURNOVER")] - public System.Single? Turnover { get; set;} - - [Alias("STARTED")] - public System.DateTime? Started { get; set;} - - [Alias("EMPLOYEES")] - public System.Int32? Employees { get; set;} - - [Alias("CREATED_DATE")] - public System.DateTime? CreatedDate { get; set;} - - [Alias("GUID")] - public System.Guid? Guid { get; set;} - - - public static class Me { - - public static string TableName { get { return "COMPANY"; }} - public static string Id { get { return "ID"; }} - public static string Name { get { return "NAME"; }} - public static string Turnover { get { return "TURNOVER"; }} - public static string Started { get { return "STARTED"; }} - public static string Employees { get { return "EMPLOYEES"; }} - public static string CreatedDate { get { return "CREATED_DATE"; }} - public static string Guid { get { return "GUID"; }} - - } - } -} \ No newline at end of file diff --git a/src/FirebirdTests/TestSimpleFirebird02/Main.cs b/src/FirebirdTests/TestSimpleFirebird02/Main.cs deleted file mode 100644 index 7d05c340f..000000000 --- a/src/FirebirdTests/TestSimpleFirebird02/Main.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; -using Database.Records; - -namespace Database.Records -{ - - public partial class Company - { - - [Ignore] - public string UpperName - { - get { return Name.ToUpper(); } - } - } -} - -namespace TestLiteFirebird2 -{ - class MainClass - { - public static void Main(string[] args) - { - //Set one before use (i.e. in a static constructor). - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - { - try - { - - Console.WriteLine(db.Exists(new Company() { Id = 1000 })); - - Console.WriteLine(db.Exists(new Company() { Id = 5 })); - - Console.WriteLine(db.ExistsFmt(Company.Me.Id + "={0}", 5)); - - Console.WriteLine(db.ExistsFmt(Company.Me.Id + "={0}", 1000)); - - - var rows = db.Select(); - Console.WriteLine("Company: rows before insert :{0}", rows.Count); - - Company cp = new Company { - Name = "One More Company", - Employees = 10, - Started = DateTime.Today, - Turnover = 12525, - CreatedDate = DateTime.Now - }; - - - db.Insert(cp); - - rows = db.Select(); - Console.WriteLine("Company: rows after insert :{0}", rows.Count); - foreach (Company u in rows) - { - Console.WriteLine("{0} -- {1}", u.Id, u.Name); - } - Console.WriteLine("----------------------"); - - rows = db.SelectFmt(Company.Me.Id + ">={0} order by " + Company.Me.Id + " descending rows 5", - 10); - Console.WriteLine(rows.Count); - foreach (Company u in rows) - { - Console.WriteLine("{0} -- {1} -- {2} -- {3} -- {4} -- {5} --{6}", u.Id, u.Name, - (u.Employees.HasValue) ? u.Employees.Value.ToString() : "", - u.Started.HasValue ? u.Started.Value.ToString() : "", - u.Turnover.HasValue ? u.Turnover.Value.ToString() : "", - u.CreatedDate.HasValue ? u.CreatedDate.Value.ToString() : "", - u.UpperName - ); - } - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - } - - } - - //s.Substring(7, s.IndexOf("FROM")-8) --> columns - //s.Substring( s.IndexOf("FROM")+5) -} diff --git a/src/FirebirdTests/TestSimpleFirebird02/TestLiteFirebird02.csproj b/src/FirebirdTests/TestSimpleFirebird02/TestLiteFirebird02.csproj deleted file mode 100644 index ae8690112..000000000 --- a/src/FirebirdTests/TestSimpleFirebird02/TestLiteFirebird02.csproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {924A8BBF-4D88-41A3-9F83-4332B0019D0C} - Exe - TestSimpleFirebird02 - TestSimpleFirebird02 - v4.0 - ..\..\ - true - - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - False - ..\..\packages\odp.net.x86.112.3.20\lib\net40\Oracle.DataAccess.dll - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestSimpleFirebird02/app.config b/src/FirebirdTests/TestSimpleFirebird02/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/FirebirdTests/TestSimpleFirebird02/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/FirebirdTests/TestSimpleFirebird02/packages.config b/src/FirebirdTests/TestSimpleFirebird02/packages.config deleted file mode 100644 index d7abd32ac..000000000 --- a/src/FirebirdTests/TestSimpleFirebird02/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestSimpleFirebird03/AssemblyInfo.cs b/src/FirebirdTests/TestSimpleFirebird03/AssemblyInfo.cs deleted file mode 100644 index 1330c74e5..000000000 --- a/src/FirebirdTests/TestSimpleFirebird03/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebird03")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestSimpleFirebird03/Main.cs b/src/FirebirdTests/TestSimpleFirebird03/Main.cs deleted file mode 100644 index fafd8b61c..000000000 --- a/src/FirebirdTests/TestSimpleFirebird03/Main.cs +++ /dev/null @@ -1,117 +0,0 @@ - -using System; -using System.Data; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - -namespace TestLiteFirebir03 -{ - class MainClass - { - public static void Main (string[] args) - { - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - { - - Schema fbd= new Schema(){ - Connection = db - }; - - Console.WriteLine("--------TABLES-------------"); - - var tables = fbd.Tables; - - foreach(Table t in tables){ - Console.WriteLine(t.Name); - } - - Console.WriteLine("-------users's owner--------------"); - - - Table t1 = fbd.GetTable("USERS"); - Console.WriteLine(t1.Owner); - - Console.WriteLine ("---------user's columns ----------------"); - - var Columns = fbd.GetColumns("USERS"); - - foreach(Column cl in Columns){ - Console.WriteLine("{0}--{1}--{2}--{3} -- {4}-- {5}--{6} ", - cl.Name,cl.Position, cl.Nullable, cl.Length, cl.DbType, cl.NetType, cl.Sequence); - } - - Console.WriteLine("--------------------------------------------"); - - Console.WriteLine("EMPLOYEE's Columns "); - - Columns = fbd.GetColumns("EMPLOYEE"); - - foreach(Column cl in Columns){ - Console.WriteLine("{0}--{1}--{2}--{3} -- {4}-- {5}--{6} -- Computed {7} ", - cl.Name,cl.Position, cl.Nullable, cl.Length, cl.DbType, - cl.NetType, cl.Sequence,cl.IsComputed); - } - - Columns = fbd.GetColumns("COMPANY"); - - foreach(Column cl in Columns){ - Console.WriteLine("{0}--{1}--{2}--{3} -- {4}-- {5}--{6} ", - cl.Name,cl.Position, cl.Nullable, cl.Length, cl.DbType, cl.NetType, cl.Sequence); - } - - Console.WriteLine("--------------------------------------------"); - - Console.WriteLine("-----------------Procedure---------------------------"); - - Console.WriteLine ("----- ADD_EMP_PROJ ----"); - - Procedure p = fbd.GetProcedure("ADD_EMP_PROJ"); - Console.WriteLine("p.Name {0} p.Owner {1} p.Inputs {2} p.Outputs {3} p.Type {4}", - p.Name, p.Owner, p.Inputs, p.Outputs, p.Type); - - var parameters = fbd.GetParameters(p); - foreach( var par in parameters){ - Console.WriteLine("p.ProcedureName {0} p.Name {1} p.Position {2} p.ParameterType {3} p.DbType {4} p.NetType {5}", - par.ProcedureName, par.Name, par.Position, par.Direction, par.DbType, par.NetType); - } - - - Console.WriteLine ("----- ALL_LANGS ----"); - p = fbd.GetProcedure("ALL_LANGS"); - Console.WriteLine("p.Name {0} p.Owner {1} p.Inputs {2} p.Outputs {3} p.Type {4}", - p.Name, p.Owner, p.Inputs, p.Outputs, p.Type); - - - parameters = fbd.GetParameters(p); - - parameters = fbd.GetParameters(p); - foreach( var par in parameters){ - Console.WriteLine("p.ProcedureName {0} p.Name {1} p.Position {2} p.ParameterType {3} p.DbType {4} p.NetType {5}", - par.ProcedureName, par.Name, par.Position, par.Direction, par.DbType, par.NetType); - } - - - ClassWriter cw = new ClassWriter(){ - Schema=fbd, - }; - - cw.WriteClass( new Table(){Name="EMPLOYEE"} ); - - - Console.WriteLine("This is The End my friend"); - - //DTOGenerator - - } - - - - - } - } -} - diff --git a/src/FirebirdTests/TestSimpleFirebird03/TestSimpleFirebird03.csproj b/src/FirebirdTests/TestSimpleFirebird03/TestSimpleFirebird03.csproj deleted file mode 100644 index e37caa97b..000000000 --- a/src/FirebirdTests/TestSimpleFirebird03/TestSimpleFirebird03.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {E4489930-7E42-43B8-93C3-7E1974845D88} - Exe - TestSimpleFirebird03 - TestSimpleFirebird03 - v4.0 - - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestSimpleFirebird03/app.config b/src/FirebirdTests/TestSimpleFirebird03/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/FirebirdTests/TestSimpleFirebird03/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/FirebirdTests/TestSimpleFirebirdProcedures/AssemblyInfo.cs b/src/FirebirdTests/TestSimpleFirebirdProcedures/AssemblyInfo.cs deleted file mode 100644 index 88a32b5e7..000000000 --- a/src/FirebirdTests/TestSimpleFirebirdProcedures/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebirdProcedures")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/FirebirdTests/TestSimpleFirebirdProcedures/Main.cs b/src/FirebirdTests/TestSimpleFirebirdProcedures/Main.cs deleted file mode 100644 index 2ea6dcfe1..000000000 --- a/src/FirebirdTests/TestSimpleFirebirdProcedures/Main.cs +++ /dev/null @@ -1,369 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; - -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - - -namespace TestLiteFirebirdProcedures -{ - - [Alias("EMPLOYEE")] - public class Employee - { - - [Alias("EMP_NO")] - [Sequence("EMP_NO_GEN")] - public Int16 Id - { - get; - set; - } - - [Alias("FIRST_NAME")] - [Required] - public string FirstName - { - get; - set; - } - - [Alias("LAST_NAME")] - [Required] - public string LastName - { - get; - set; - } - - [Alias("PHONE_EXT")] - public string PhoneExtension - { - get; - set; - } - - [Alias("HIRE_DATE")] - [Required] - public DateTime HireDate - { - get; - set; - } - - [Alias("DEPT_NO")] - [Required] - public string DepartamentNumber - { - get; - set; - } - - [Alias("JOB_CODE")] - [Required] - public string JobCode - { - get; - set; - } - - [Alias("JOB_GRADE")] - public Int16 JobGrade - { - get; - set; - } - - - [Alias("JOB_COUNTRY")] - [Required] - public string JobCountry - { - get; - set; - } - - [Alias("SALARY")] - [Required] - public Decimal Salary - { - get; - set; - } - - } - - [Alias("DELETE_EMPLOYEE")] - public class ProcedureDeleteEmployee - { - [Alias("EMP_NUM")] - public Int16 EmployeeNumber - { - get; - set; - } - - } - - [Alias("SUB_TOT_BUDGET")] - public class ProcedureSubTotalBudgetParameters - { - - [Alias("HEAD_DEPT")] - public string HeadDepartament - { - get; - set; - } - - } - - public class ProcedureSubTotalBudgetResult - { - - [Alias("TOT_BUDGET")] - public decimal Total - { - get; - set; - } - - [Alias("AVG_BUDGET")] - public decimal Average - { - get; - set; - } - - [Alias("MAX_BUDGET")] - public decimal Max - { - get; - set; - } - - [Alias("MIN_BUDGET")] - public decimal Min - { - get; - set; - } - } - - - [Alias("SHOW_LANGS")] - public class ProcedureShowLangsParameters - { - - [Alias("CODE")] - public string Code - { - get; - set; - } - - [Alias("GRADE")] - public Int16 Grade - { - get; - set; - } - - [Alias("CTY")] - public string Country - { - get; - set; - } - - } - - - public class ProcedureShowLangsResult - { - - [Alias("LANGUAGES")] - public string Language - { - get; - set; - } - } - - [Alias("ALL_LANGS")] - public class ProcedureAllLangs - { - - public List Execute(IDbConnection db) - { - return db.SqlProcedure(this); - } - - //public List Results{ - // get; set; - //} - - public class ProcedureAllLangsResult - { - - [Alias("CODE")] - public string Code - { - get; - set; - } - - [Alias("GRADE")] - public string Grade - { - get; - set; - } - - [Alias("COUNTRY")] - public string Country - { - get; - set; - } - - [Alias("LANG")] - public string Language - { - get; - set; - } - - } - - } - - - - - - - - class MainClass - { - public static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - { - try - { - - var employees = db.Select(); - Console.WriteLine("Total Employees '{0}'", employees.Count); - - Employee employee = new Employee() { - FirstName = "LILA", - LastName = "FUTURAMA", - PhoneExtension = "0002", - HireDate = DateTime.Now, - DepartamentNumber = "900", - JobCode = "Eng", - JobGrade = 2, - JobCountry = "USA", - Salary = 75000 - }; - int count = employees.Count; - - db.Insert(employee); - Console.WriteLine("Id for new employee : '{0}'", employee.Id); - - employees = db.Select(); - Console.WriteLine("Total Employees '{0}' = '{1}'", employees.Count, count + 1); - - Console.WriteLine("Executing 'DELETE_EMPLOYEE' for '{0}' - {1}", employee.Id, employee.LastName); - ProcedureDeleteEmployee de = new ProcedureDeleteEmployee(); - de.EmployeeNumber = employee.Id; - db.ExecuteProcedure(de); - - employees = db.Select(); - Console.WriteLine("Total Employees '{0}'= '{1}' ", employees.Count, count); - - } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - - - try - { - - ProcedureSubTotalBudgetParameters p = new ProcedureSubTotalBudgetParameters() { - HeadDepartament = "000" - }; - - var results = db.SqlProcedure(p, ""); - - - foreach (var r in results) - { - Console.WriteLine("r.Total:{0} r.Average:{1} r.Max:{2} r.Min:{3}", r.Total, r.Average, r.Max, r.Min); - } - } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - - try - { - - ProcedureShowLangsParameters l = new ProcedureShowLangsParameters() { - Code = "Sales", - Grade = 3, - Country = "England" - }; - - var ls = db.SqlProcedure(l, ""); - - foreach (var lr in ls) - { - Console.WriteLine(lr.Language); - } - } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - - try - { - - ProcedureAllLangs l = new ProcedureAllLangs(); - - //var ls = db.SelectFromProcedure(l); - //db.SelectFromProcedure(l); - - - var ls = l.Execute(db); // better ? - - foreach (var lr in ls) - { - Console.WriteLine("lr.Code:{0} lr.Country:{1} lr.Grade:{2} lr.Language:{3}", - lr.Code, lr.Country, lr.Grade, lr.Language); - } - } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - - - Console.WriteLine("This is The End my friend!"); - } - - } - } -} - diff --git a/src/FirebirdTests/TestSimpleFirebirdProcedures/TestSimpleFirebirdProcedures.csproj b/src/FirebirdTests/TestSimpleFirebirdProcedures/TestSimpleFirebirdProcedures.csproj deleted file mode 100644 index 9fcea4584..000000000 --- a/src/FirebirdTests/TestSimpleFirebirdProcedures/TestSimpleFirebirdProcedures.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {60B6BD41-6415-418E-A71F-FB6622C379D9} - Exe - TestSimpleFirebirdProcedures - TestSimpleFirebirdProcedures - v4.0 - - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - \ No newline at end of file diff --git a/src/FirebirdTests/TestSimpleFirebirdProcedures/app.config b/src/FirebirdTests/TestSimpleFirebirdProcedures/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/FirebirdTests/TestSimpleFirebirdProcedures/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/GlobalAssemblyInfo.cs b/src/GlobalAssemblyInfo.cs deleted file mode 100644 index dfdfc74da..000000000 --- a/src/GlobalAssemblyInfo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Reflection; - -[assembly: AssemblyVersion("3.9.60.0")] \ No newline at end of file diff --git a/src/MySqlExpressionsTest/MySqlExpressionsTest.csproj b/src/MySqlExpressionsTest/MySqlExpressionsTest.csproj deleted file mode 100644 index e185df405..000000000 --- a/src/MySqlExpressionsTest/MySqlExpressionsTest.csproj +++ /dev/null @@ -1,97 +0,0 @@ - - - - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D} - Debug - x86 - Exe - MySqlExpressionsTest - MySqlExpressionsTest - Properties - C:\Users\angel\AppData\Roaming\ICSharpCode/SharpDevelop4\Settings.SourceAnalysis - 10.0.0 - 2.0 - v4.5 - - - - x86 - - - bin\Debug\ - True - Full - False - True - DEBUG;TRACE - - - bin\Release\ - False - None - True - False - TRACE - - - 4 - false - - - 4 - false - - - bin\x86\Signed\ - TRACE - true - None - x86 - MinimumRecommendedRules.ruleset - false - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - 3.5 - - - 3.5 - - - - 3.5 - - - - 3.5 - - - - - - - - - {fd20f088-acc0-4979-ac0c-8c541c2e7de5} - ServiceStack.OrmLite.MySql - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - - - \ No newline at end of file diff --git a/src/MySqlExpressionsTest/Program.cs b/src/MySqlExpressionsTest/Program.cs deleted file mode 100644 index 11e9a30f8..000000000 --- a/src/MySqlExpressionsTest/Program.cs +++ /dev/null @@ -1,264 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.MySql; - - -namespace MySqlExpressionsTest -{ - public class Author - { - public Author(){} - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - public DateTime Birthday { get; set;} - public DateTime ? LastActivity { get; set;} - public Decimal? Earnings { get; set;} - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - public Int16 Rate{ get; set;} - } - - - - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - OrmLiteConfig.DialectProvider = MySqlDialectProvider.Instance; - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (IDbConnection db = - "Server = 127.0.0.1; Database = ormlite; Uid = root; Pwd = password".OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.DeleteAll(); - - List authors = new List(); - authors.Add(new Author(){Name="Demis Bellot",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 99.9m,Comments="CSharp books", Rate=10, City="London"}); - authors.Add(new Author(){Name="Angel Colmenares",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 50.0m,Comments="CSharp books", Rate=5, City="Bogota"}); - authors.Add(new Author(){Name="Adam Witco",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 80.0m,Comments="Math Books", Rate=9, City="London"}); - authors.Add(new Author(){Name="Claudia Espinel",Birthday= DateTime.Today.AddYears(-23),Active=true,Earnings= 60.0m,Comments="Cooking books", Rate=10, City="Bogota"}); - authors.Add(new Author(){Name="Libardo Pajaro",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 80.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Jorge Garzon",Birthday= DateTime.Today.AddYears(-28),Active=true,Earnings= 70.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Alejandro Isaza",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 70.0m,Comments="Java books", Rate=0, City="Bogota"}); - authors.Add(new Author(){Name="Wilmer Agamez",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 30.0m,Comments="Java books", Rate=0, City="Cartagena"}); - authors.Add(new Author(){Name="Rodger Contreras",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 90.0m,Comments="CSharp books", Rate=8, City="Cartagena"}); - authors.Add(new Author(){Name="Chuck Benedict",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="CSharp books", Rate=8, City="London"}); - authors.Add(new Author(){Name="James Benedict II",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="Java books", Rate=5, City="Berlin"}); - authors.Add(new Author(){Name="Ethan Brown",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 45.0m,Comments="CSharp books", Rate=5, City="Madrid"}); - authors.Add(new Author(){Name="Xavi Garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 75.0m,Comments="CSharp books", Rate=9, City="Madrid"}); - authors.Add(new Author(){Name="Luis garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.0m,Comments="CSharp books", Rate=10, City="Mexico"}); - - db.InsertAll(authors); - - - // lets start ! - - // select authors born 20 year ago - int year = DateTime.Today.AddYears(-20).Year; - int expected=5; - - ev.Where(rn=> rn.Birthday>=new DateTime(year, 1,1) && rn.Birthday<=new DateTime(year, 12,31)); - List result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31))); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected=6; - ev.Where(rn=> Sql.In( rn.City, new object[]{"London", "Madrid", "Berlin"}) ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors from Bogota and Cartagena : 7 - expected=7; - ev.Where(rn => Sql.In(rn.City, new object[] { "Bogota", "Cartagena" })); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name starts with A - expected=3; - ev.Where(rn=> rn.Name.StartsWith("A") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.ToUpper().EndsWith("GARZON") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with garzon ( nonbinary string comparisons are case insensitive by default ) - expected=3; - ev.Where(rn=> rn.Name.EndsWith("garzon") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors which name contains Benedict - expected=2; - ev.Where(rn=> rn.Name.Contains("Benedict") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors with Earnings <= 50 - expected=3; - ev.Where(rn=> rn.Earnings<=50 ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors with Rate = 10 and city=Mexico - expected=1; - ev.Where(rn=> rn.Rate==10 && rn.City=="Mexico"); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected=2; - ev.Where(rn=> rn.Rate==0 ).Update(rn=> rn.Active); - var rows = db.UpdateOnly( new Author(){ Active=false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected=4; - ev.Insert(rn =>new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate} ); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Victor Grozny", Birthday=DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Ivan Chorny", Birthday=DateTime.Today.AddYears(-19) }, ev); - ev.Where(rn=> !rn.Active); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - //update comment for City == null - expected=2; - ev.Where( rn => rn.City==null ).Update(rn=> rn.Comments); - rows=db.UpdateOnly(new Author(){Comments="No comments"}, ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // delete where City is null - expected=2; - rows = db.Delete( ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected=14; - ev.Where().OrderBy(rn=> new{ at=Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - Console.WriteLine(ev.OrderByExpression); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel", author.Name, "Claudia Espinel"==author.Name); - - // select only first 5 rows .... - - expected=5; - ev.Limit(5); // note: order is the same as in the last sentence - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn=> new { at= Sql.As( rn.Name.ToUpper(), "Name" ), rn.City} ); - Console.WriteLine(ev.SelectExpression); - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - - //paging : - ev.Limit(0,4);// first page, page size=4; - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - ev.Limit(4,4);// second page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper()==author.Name); - - ev.Limit(8,4);// third page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper()==author.Name); - - // select distinct.. - ev.Limit(); // clear limit - ev.SelectDistinct(r=>r.City); - expected=6; - result=db.Select(ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - Console.WriteLine(); - // Tests for predicate overloads that make use of the expression visitor - Console.WriteLine("First author by name (exists)"); - author = db.Single(a => a.Name == "Jorge Garzon"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon", author.Name, "Jorge Garzon" == author.Name); - - try - { - Console.WriteLine("First author by name (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - - Console.WriteLine("Expected exception thrown, OK? False"); - } - catch - { - Console.WriteLine("Expected exception thrown, OK? True"); - } - - Console.WriteLine("First author or default (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - Console.WriteLine("Expected:null ; OK? {0}", author == null); - - Console.WriteLine("First author or default by city (multiple matches)"); - author = db.Single(a => a.City == "Bogota"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Angel Colmenares", author.Name, "Angel Colmenares" == author.Name); - - - Console.ReadLine(); - Console.WriteLine("Press Enter to continue"); - - } - - Console.WriteLine ("This is The End my friend!"); - } - } -} \ No newline at end of file diff --git a/src/MySqlExpressionsTest/Properties/AssemblyInfo.cs b/src/MySqlExpressionsTest/Properties/AssemblyInfo.cs deleted file mode 100644 index 89a6ae070..000000000 --- a/src/MySqlExpressionsTest/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Using directives - -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -#endregion - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("MySqlExpressionsTest")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MySqlExpressionsTest")] -[assembly: AssemblyCopyright("Copyright 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// This sets the default COM visibility of types in the assembly to invisible. -// If you need to expose a type to COM, use [ComVisible(true)] on that type. -[assembly: ComVisible(false)] - diff --git a/src/MySqlExpressionsTest/app.config b/src/MySqlExpressionsTest/app.config deleted file mode 100644 index 5c2425f42..000000000 --- a/src/MySqlExpressionsTest/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/OracleTests/TestClassWriter/AssemblyInfo.cs b/src/OracleTests/TestClassWriter/AssemblyInfo.cs deleted file mode 100644 index 62b79e3a1..000000000 --- a/src/OracleTests/TestClassWriter/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestClassWriter")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestClassWriter/Main.cs b/src/OracleTests/TestClassWriter/Main.cs deleted file mode 100644 index 19819dfb2..000000000 --- a/src/OracleTests/TestClassWriter/Main.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.IO; -using System.CodeDom.Compiler; -using Microsoft.CSharp; -using System.Collections.Generic; -using System.Data; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Oracle; -using ServiceStack.OrmLite.Oracle.DbSchema; - -namespace TestClassWriter -{ - class MainClass - { - public static void Main (string[] args) - { - - OrmLiteConfig.DialectProvider = new OracleOrmLiteDialectProvider { NamingStrategy = new OracleNamingStrategy()}; - using (IDbConnection db = - "Data Source=x;User Id=x;Password=x;".OpenDbConnection()) - using ( IDbCommand dbConn = db.CreateCommand()) - { - Schema fbd= new Schema(){ - Connection = db - }; - - ClassWriter cw = new ClassWriter(){ - Schema=fbd, - GenerateMetadata=true, - //SpaceName= "your.app.namespace", - //OutputDirectory="outputpath" - //Usings="Using System;\nUsing System.Data\n" - }; - - foreach(var t in fbd.Tables){ - Console.Write("Generating POCO Class for table:'{0}'...", t.Name); - cw.WriteClass( t); - Console.WriteLine(" Done."); - } - Console.WriteLine("---------------------------------"); - Console.WriteLine("See classes in: '{0}'", cw.OutputDirectory); - - //compilar ... - CompilerParameters cp = new CompilerParameters(); - cp.GenerateExecutable=false; - cp.GenerateInMemory=false; - cp.ReferencedAssemblies.AddRange( - new string[]{ - "System.dll", - "System.ComponentModel.DataAnnotations.dll", - Path.Combine( Directory.GetCurrentDirectory(), "ServiceStack.OrmLite.dll"), - Path.Combine( Directory.GetCurrentDirectory(), "ServiceStack.Common.dll"), - Path.Combine( Directory.GetCurrentDirectory(),"ServiceStack.Interfaces.dll") - }); - cp.OutputAssembly= Path.Combine(cw.OutputDirectory, cw.SpaceName+".dll"); - - var providerOptions = new Dictionary(); - providerOptions.Add("CompilerVersion", "v3.5"); - - CodeDomProvider cdp =new CSharpCodeProvider(providerOptions); - - string [] files = Directory.GetFiles(cw.OutputDirectory,"*.cs"); - CompilerResults cr= cdp.CompileAssemblyFromFile(cp, files); - - if( cr.Errors.Count==0){ - Console.WriteLine("Generated file {0}", Path.Combine(cw.OutputDirectory, cw.SpaceName+".dll")); - } - else{ - foreach (CompilerError ce in cr.Errors) - Console.WriteLine(ce.ErrorText); - } - - - - - } - - - Console.WriteLine ("This is The End my friend!"); - - } - } -} diff --git a/src/OracleTests/TestClassWriter/TestClassWriter.csproj b/src/OracleTests/TestClassWriter/TestClassWriter.csproj deleted file mode 100644 index bd3b2230d..000000000 --- a/src/OracleTests/TestClassWriter/TestClassWriter.csproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {AAE7E422-EAC0-4B06-A973-C32E7E600769} - Exe - TestClassWriter - TestClassWriter - v4.0 - - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - {517B64BA-D7A6-4A15-8719-821B38147C61} - ServiceStack.OrmLite.Oracle - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - - \ No newline at end of file diff --git a/src/OracleTests/TestClassWriter/app.config b/src/OracleTests/TestClassWriter/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/OracleTests/TestClassWriter/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/OracleTests/TestExpression02/AssemblyInfo.cs b/src/OracleTests/TestExpression02/AssemblyInfo.cs deleted file mode 100644 index 791856539..000000000 --- a/src/OracleTests/TestExpression02/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestExpression02")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestExpression02/Main.cs b/src/OracleTests/TestExpression02/Main.cs deleted file mode 100644 index 7c6c6ac1f..000000000 --- a/src/OracleTests/TestExpression02/Main.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace TestExpression02 -{ - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - } - } -} diff --git a/src/OracleTests/TestExpression02/TestExpression02.csproj b/src/OracleTests/TestExpression02/TestExpression02.csproj deleted file mode 100644 index 391906ef7..000000000 --- a/src/OracleTests/TestExpression02/TestExpression02.csproj +++ /dev/null @@ -1,45 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F} - Exe - TestExpression02 - TestExpression02 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - - - - - \ No newline at end of file diff --git a/src/OracleTests/TestExpressions/AssemblyInfo.cs b/src/OracleTests/TestExpressions/AssemblyInfo.cs deleted file mode 100644 index 4002f55ad..000000000 --- a/src/OracleTests/TestExpressions/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestExpressions")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestExpressions/Main.cs b/src/OracleTests/TestExpressions/Main.cs deleted file mode 100644 index b620f84e4..000000000 --- a/src/OracleTests/TestExpressions/Main.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Oracle; - - -namespace TestExpressions -{ - public class Author{ - public Author(){} - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - public DateTime Birthday { get; set;} - public DateTime ? LastActivity { get; set;} - public Decimal? Earnings { get; set;} - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - public Int16 Rate{ get; set;} - } - - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - OrmLiteConfig.DialectProvider = new OracleOrmLiteDialectProvider(); - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (IDbConnection db = - "Data Source=x;User Id=x;Password=x;".OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.DeleteAll(); - - List authors = new List(); - authors.Add(new Author(){Name="Demis Bellot",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 99.9m,Comments="CSharp books", Rate=10, City="London"}); - authors.Add(new Author(){Name="Angel Colmenares",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 50.0m,Comments="CSharp books", Rate=5, City="Bogota"}); - authors.Add(new Author(){Name="Adam Witco",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 80.0m,Comments="Math Books", Rate=9, City="London"}); - authors.Add(new Author(){Name="Claudia Espinel",Birthday= DateTime.Today.AddYears(-23),Active=true,Earnings= 60.0m,Comments="Cooking books", Rate=10, City="Bogota"}); - authors.Add(new Author(){Name="Libardo Pajaro",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 80.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Jorge Garzon",Birthday= DateTime.Today.AddYears(-28),Active=true,Earnings= 70.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Alejandro Isaza",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 70.0m,Comments="Java books", Rate=0, City="Bogota"}); - authors.Add(new Author(){Name="Wilmer Agamez",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 30.0m,Comments="Java books", Rate=0, City="Cartagena"}); - authors.Add(new Author(){Name="Rodger Contreras",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 90.0m,Comments="CSharp books", Rate=8, City="Cartagena"}); - authors.Add(new Author(){Name="Chuck Benedict",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="CSharp books", Rate=8, City="London"}); - authors.Add(new Author(){Name="James Benedict II",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="Java books", Rate=5, City="Berlin"}); - authors.Add(new Author(){Name="Ethan Brown",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 45.0m,Comments="CSharp books", Rate=5, City="Madrid"}); - authors.Add(new Author(){Name="Xavi Garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 75.0m,Comments="CSharp books", Rate=9, City="Madrid"}); - authors.Add(new Author(){Name="Luis garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.0m,Comments="CSharp books", Rate=10, City="Mexico"}); - - db.InsertAll(authors); - - - // lets start ! - - // select authors born 20 year ago - int year = DateTime.Today.AddYears(-20).Year; - int expected=5; - - ev.Where(rn=> rn.Birthday>=new DateTime(year, 1,1) && rn.Birthday<=new DateTime(year, 12,31)); - List result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31))); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors from London, Berlin and Madrid : 6 - expected=6; - //Sql.In can take params object[] - ev.Where(rn=> Sql.In( rn.City, new object[]{"London", "Madrid", "Berlin"}) ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors from Bogota and Cartagena : 7 - expected=7; - //... or Sql.In can take IList - List cities= new List(); - cities.Add("Bogota"); - cities.Add("Cartagena"); - ev.Where(rn => Sql.In(rn.City, cities )); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors which name starts with A - expected=3; - ev.Where(rn=> rn.Name.StartsWith("A") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.ToUpper().EndsWith("GARZON") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.EndsWith("garzon") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors which name contains Benedict - expected=2; - ev.Where(rn=> rn.Name.Contains("Benedict") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors with Earnings <= 50 - expected=3; - ev.Where(rn=> rn.Earnings<=50 ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors with Rate = 10 and city=Mexio - expected=1; - ev.Where(rn=> rn.Rate==10 && rn.City=="Mexico"); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected=2; - ev.Where(rn=> rn.Rate==0 ).Update(rn=> rn.Active); - var rows = db.UpdateOnly( new Author(){ Active=false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected=4; - ev.Insert(rn =>new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate} ); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Victor Grozny", Birthday=DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Ivan Chorny", Birthday=DateTime.Today.AddYears(-19) }, ev); - ev.Where(rn=> !rn.Active); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - //update comment for City == null - expected=2; - ev.Where( rn => rn.City==null ).Update(rn=> rn.Comments); - rows=db.UpdateOnly(new Author(){Comments="No comments"}, ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // delete where City is null - expected=2; - rows = db.Delete( ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected=14; - ev.Where().OrderBy(rn=> new{ at=Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - Console.WriteLine(ev.OrderByExpression); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel", author.Name, "Claudia Espinel"==author.Name); - - // select only first 5 rows .... - - expected=5; - ev.Limit(5); // note: order is the same as in the last sentence - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn=> new { at= Sql.As( rn.Name.ToUpper(), "Name" ), rn.City} ); - Console.WriteLine(ev.SelectExpression); - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - //paging : - ev.Limit(0,4);// first page, page size=4; - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - ev.Limit(4,4);// second page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper()==author.Name); - - ev.Limit(8,4);// third page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper()==author.Name); - - - // select distinct.. - ev.Limit(); // clear limit - ev.SelectDistinct(r=>r.City).OrderBy(); - expected=6; - result=db.Select(ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - Console.ReadLine(); - Console.WriteLine("Press Enter to continue"); - - } - - Console.WriteLine ("This is The End my friend!"); - } - } -} diff --git a/src/OracleTests/TestExpressions/TestExpressions.csproj b/src/OracleTests/TestExpressions/TestExpressions.csproj deleted file mode 100644 index fb941866d..000000000 --- a/src/OracleTests/TestExpressions/TestExpressions.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {619CF480-0DFB-429E-8FC1-B039E8C47AD9} - Exe - TestExpressions - TestExpressions - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - {517B64BA-D7A6-4A15-8719-821B38147C61} - ServiceStack.OrmLite.Oracle - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - \ No newline at end of file diff --git a/src/OracleTests/TestLiteOracle00/AssemblyInfo.cs b/src/OracleTests/TestLiteOracle00/AssemblyInfo.cs deleted file mode 100644 index 9b76a4803..000000000 --- a/src/OracleTests/TestLiteOracle00/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestLiteOracle00")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestLiteOracle00/Main.cs b/src/OracleTests/TestLiteOracle00/Main.cs deleted file mode 100644 index 933191a52..000000000 --- a/src/OracleTests/TestLiteOracle00/Main.cs +++ /dev/null @@ -1,226 +0,0 @@ -using System; -using System.Linq; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Oracle; - - -namespace TestLiteOracle00 -{ - - public class Author{ - - public Author(){ - } - - [AutoIncrement] - //[Sequence("Author_Id_GEN")] - public Int32 Id { get; set;} - - [Required] - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - - [Required] - public DateTime Birthday { get; set;} - - public DateTime ? LastActivity { get; set;} - - public Decimal? Earnings { get; set;} // Precision=18, scale=12 default values - - //[Alias("Active")] // Active Firebird Reserved ? - public bool Active { get; set; } - - [StringLength(80)] - public string City { get; set;} - - [StringLength(80)] - public string Comments { get; set;} - - public Int16 Rate{ get; set;} - - - } - - public class Book{ - - public Book(){ - } - - [AutoIncrement] - //[Sequence("Book_Id_GEN")] - public Int32 Id { get; set;} - - [References(typeof(Author))] - public Int32 IdAuthor {get; set;} - - [StringLength(80)] - public string Title {get; set;} - [DecimalLength(15,2)] - public Decimal Price { get; set;} // Precision= 15, Scale=2 - - } - - - class MainClass - { - public static void Main (string[] args) - { - OrmLiteConfig.DialectProvider = new OracleOrmLiteDialectProvider(); - - using (IDbConnection db = - "Data Source=x;User Id=x;Password=x;".OpenDbConnection()) - { - //try{ - // due to firebirdslq features, we have to drop book first and then author - db.DropTable(); - db.DropTable(); - - db.CreateTable(); - db.CreateTable(); - - db.Insert( new Author(){ - Name="Demis Bellot", - Birthday= DateTime.Today.AddYears(20), - Active=true, - Earnings= 99.9m, - Comments="ServiceStack.Net ...", - City="London", - Rate=10 - }); - - db.Insert( new Author(){ - Name="Angel Colmenares", - Birthday= DateTime.Today.AddYears(30), - Active=true, - Earnings= 50.25m, - Comments="OrmLite.Firebird", - City="Bogota", - Rate=9 - }); - - db.Insert( new Author(){ - Name="Adam Witco", - Birthday= DateTime.Today.AddYears(25), - Active=true, - Comments="other books...", - City="London", - Rate=8 - }); - - - db.Insert( new Author(){ - Name="Claudia Espinel", - Birthday= DateTime.Today.AddYears(28), - Active=false, - Comments="other books...", - City="Bogota", - Rate=10 - }); - - //------------------------------------------------------------------- - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - ev.Insert(r=> new {r.Id, r.Name, r.Birthday, r.Active, r.Rate}); // fields to insert - - var author = new Author(){ - Name="William", - Birthday= DateTime.Today.AddYears(250), - Active=false, - City="London", - Rate= 0, - Comments="this will not be inserted" // null in db - }; - - db.InsertOnly(author, ev); - - author.Comments="this will be updated"; - - ev.Update(rn=> rn.Comments).Where(r=>r.Id==author.Id); - db.UpdateOnly(author, ev); - - - // update comment for all authors from london... - - author.Comments="update from london"; - ev.Where(rn=> rn.City=="London"); - db.UpdateOnly(author, ev); - - // select author from Bogota - ev.Where(rn=> rn.City=="Bogota"); - var authors = db.Select(ev); - Console.WriteLine(authors.Count); - - // select author from Bogota and Active=true; - - ev.Where(rn=> rn.City=="Bogota" && rn.Active==true); // sorry for firebird must write ==true ! - authors = db.Select(ev); - Console.WriteLine(authors.Count); - - //------------------------------------------------------------------- - authors = db.Select(); - - Console.WriteLine("Rows in Author : '{0}'",authors.Count); - - foreach(Author a in authors){ - Console.WriteLine("Id :{0} - Name : {1} -- Earnings {2}", a.Id, - a.Name, - a.Earnings.HasValue? a.Earnings.Value: 0.0m); - } - - author= authors.FirstOrDefault(r=>r.Name=="Angel Colmenares"); - if( author != default(Author) ){ - - db.Insert( new Book(){ - IdAuthor= author.Id, - Title= "The big book", - Price= 18.55m, - }); - Console.WriteLine("{0} == {1}", db.Exists( author), true ) ; - } - else{ - Console.WriteLine("Something wrong "); - } - - - author= authors.FirstOrDefault(r=>r.Name=="Adam Witco"); - if( author != default(Author) ){ - - - Console.WriteLine("{0} == {1}", db.Exists( author), false ) ; - } - else{ - Console.WriteLine("Something wrong "); - } - - var books = db.Select(); - - foreach(var b in books){ - Console.WriteLine("Title {0} Price {1}",b.Title, b.Price); - } - - ev.Select(r=>new { r.Name, r.Active}).Where(); // only Name and Active fields will be retrived - - authors = db.Select(ev); - Console.WriteLine(ev.SelectExpression); - - foreach(Author r in authors){ - Console.WriteLine("'{0}' '{1}' '{2}'", r.Name, r.Active, r.Id); - } - - db.DeleteAll(); - db.DeleteAll(); - - //} - - //catch(Exception e){ - // Console.WriteLine("Error : " + e.Message); - // return; - //} - Console.WriteLine("This is The End my friend !"); - } - } - } -} \ No newline at end of file diff --git a/src/OracleTests/TestLiteOracle00/TestLiteOracle00.csproj b/src/OracleTests/TestLiteOracle00/TestLiteOracle00.csproj deleted file mode 100644 index 4c2797fd7..000000000 --- a/src/OracleTests/TestLiteOracle00/TestLiteOracle00.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {81280460-2358-40D2-94AA-85951612EA04} - Exe - TestLiteFirebird00 - TestLiteFirebird00 - v4.0 - - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - {517B64BA-D7A6-4A15-8719-821B38147C61} - ServiceStack.OrmLite.Oracle - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - - \ No newline at end of file diff --git a/src/OracleTests/TestLiteOracle00/app.config b/src/OracleTests/TestLiteOracle00/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/OracleTests/TestLiteOracle00/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/OracleTests/TestLiteOracle04/AssemblyInfo.cs b/src/OracleTests/TestLiteOracle04/AssemblyInfo.cs deleted file mode 100644 index e6722e0b3..000000000 --- a/src/OracleTests/TestLiteOracle04/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestLiteOracled04")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestLiteOracle04/Company.cs b/src/OracleTests/TestLiteOracle04/Company.cs deleted file mode 100644 index 5cf7566c0..000000000 --- a/src/OracleTests/TestLiteOracle04/Company.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; - -using ServiceStack.Common; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; -using ServiceStack.OrmLite; - -namespace Database.Records -{ - [Alias("COMPANY")] - public partial class Company:IHasId{ - - public Company(){} - - [Alias("ID")] - [Sequence("COMPANY_ID_GEN")] - [PrimaryKey] - [AutoIncrement] - public System.Int32 Id { get; set;} - - [Alias("NAME")] - public System.String Name { get; set;} - - [Alias("TURNOVER")] - public System.Single? Turnover { get; set;} - - [Alias("STARTED")] - public System.DateTime? Started { get; set;} - - [Alias("EMPLOYEES")] - public System.Int32? Employees { get; set;} - - [Alias("CREATED_DATE")] - public System.DateTime? CreatedDate { get; set;} - - [Alias("GUID")] - public System.Guid? Guid { get; set;} - - [Alias("SOMEDOUBLE")] - public Double SomeDouble { get; set;} - - [Alias("SOMEBOOL")] - public bool SomeBoolean { get; set;} - - - public static class Me { - - public static string TableName { get { return "COMPANY"; }} - public static string Id { get { return "ID"; }} - public static string Name { get { return "NAME"; }} - public static string Turnover { get { return "TURNOVER"; }} - public static string Started { get { return "STARTED"; }} - public static string Employees { get { return "EMPLOYEES"; }} - public static string CreatedDate { get { return "CREATED_DATE"; }} - public static string Guid { get { return "GUID"; }} - - } - } -} \ No newline at end of file diff --git a/src/OracleTests/TestLiteOracle04/DbMethodsIn.cs b/src/OracleTests/TestLiteOracle04/DbMethodsIn.cs deleted file mode 100644 index c5c5a7082..000000000 --- a/src/OracleTests/TestLiteOracle04/DbMethodsIn.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Collections.Generic; -namespace ServiceStack.OrmLite -{ - public static class DbMethods - { - public static bool In(this T value, IList list) { - foreach( Object obj in list){ - if(obj==null || value==null ) continue; - if( obj.ToString() == value.ToString() ) return true; - } - return false; - } - - public static string Desc(this T value) { - return value==null? "": value.ToString() + " DESC"; - } - - public static string As(this T value, string asValue) { - return value==null? "": string.Format("{0} AS {1}", value.ToString(), asValue); - } - - public static T Sum(this T value) { - return value; - } - - public static T Count(this T value) { - return value; - } - - public static T Min(this T value) { - return value; - } - - public static T Avg(this T value) { - return value; - } - } - -} - -//class DbMehods.In, As , Desc, Sum, Count : methdos DbMethodName - -/* - public static T Sum(params T[] args) where T: struct - { - - T total = default(T); - Func addMethod = CreateAdd(); - - foreach (T val in args) - { - total = addMethod(total, val); - } - - return total; - } - - - private static Func CreateAdd() - { - ParameterExpression lhs = Expression.Parameter(typeof(T), "lhs"); - ParameterExpression rhs = Expression.Parameter(typeof(T), "rhs"); - Expression> addExpr = Expression>. - - Lambda>( - Expression.Add(lhs, rhs), - new ParameterExpression[] { lhs, rhs }); - - Func addMethod = addExpr.Compile(); - - return addMethod; - } - - } -*/ \ No newline at end of file diff --git a/src/OracleTests/TestLiteOracle04/Main.cs b/src/OracleTests/TestLiteOracle04/Main.cs deleted file mode 100644 index b261404ca..000000000 --- a/src/OracleTests/TestLiteOracle04/Main.cs +++ /dev/null @@ -1,286 +0,0 @@ -using System; -using System.Linq; -using System.Data; -using System.Collections.Generic; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Oracle; - -using Database.Records; - -namespace TestLiteOracle04 -{ - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - OrmLiteConfig.DialectProvider = new OracleOrmLiteDialectProvider(); - - ServiceStack.OrmLite.SqlExpression sql = - OrmLiteConfig.DialectProvider.SqlExpression(); - - List names = new List(); - names.Add("SOME COMPANY"); - names.Add("XYZ"); - - - List ids = new List(); - ids.Add(1); - ids.Add(2); - - - using (IDbConnection db = - "Data Source=x;User Id=x;Password=x;".OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - - Company company = new Company() { Id = 1, Name = "XYZ" }; - Console.WriteLine(company.Id.In(ids)); - Console.WriteLine(company.Name.In(names)); - - db.Insert(company); - - sql.Where(cp => cp.Name == "On more Company"); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => cp.Name != "On more Company"); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - - sql.Where(cp => cp.Name == null); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => cp.Name != null); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - - sql.Where(cp => cp.SomeBoolean); // TODO : fix - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => !cp.SomeBoolean && 1 == 1); //TODO : fix - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => cp.SomeBoolean && 1 == 1); //TODO : fix - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => 1 == 1); // TODO : fix ? - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => "1" == "1"); // TODO : fix ? - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => "1" == "0"); // TODO : fix ? - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => 1 != 1); //ok - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => cp.SomeBoolean == true); //OK - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => cp.SomeBoolean == false); //OK - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => !cp.SomeBoolean); // OK - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name == cp.Name)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name == "On more Company" || cp.Id > 30)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.CreatedDate == DateTime.Today)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.CreatedDate == DateTime.Today && (cp.Name == "On more Company" || cp.Id > 30))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name.ToUpper() == "ONE MORE COMPANY")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name.ToLower() == "ONE MORE COMPANY".ToLower())); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name.ToLower().StartsWith("one"))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name.ToUpper().EndsWith("COMPANY"))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name.ToUpper().Contains("MORE"))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name.Substring(0) == "ONE MORE COMPANY")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Name.ToUpper().Substring(0, 7) == "ONE MOR")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - - sql.Where(cp => (cp.CreatedDate >= new DateTime(2000, 1, 1))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Employees / 2 > 10.0)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (cp.Employees * 2 > 10.0 / 5)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => ((cp.Employees + 3) > (10.0 + 5))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => ((cp.Employees - 3) > (10.0 + 5))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => ((cp.Employees % 3) > (10.0 + 5))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - - sql.Where(cp => (Math.Round(cp.SomeDouble) > (10.0 + 5))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (Math.Round(cp.SomeDouble, 3) > (10.0 + 5))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (Math.Floor(cp.SomeDouble) > (10.0 + 5))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (Math.Ceiling(cp.SomeDouble) > (10.0 + 5))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - - sql.Where(cp => (string.Concat(cp.SomeDouble, "XYZ") == "SOME COMPANY XYZ")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (string.Concat(cp.SomeDouble, "X", "Y", "Z") == "SOME COMPANY XYZ")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (string.Concat(cp.Name, "X", "Y", "Z") == "SOME COMPANY XYZ")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (string.Concat(cp.SomeDouble.ToString(), "X", "Y", "Z") == "SOME COMPANY XYZ")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => ((cp.CreatedDate ?? DateTime.Today) == DateTime.Today)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => ((cp.Turnover ?? 0) > 15)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (Math.Abs(cp.Turnover ?? 0) > 15)); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (Sql.In(cp.Name, names))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => (Sql.In(cp.Id, ids))); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - - sql.OrderBy(cp => cp.Name); - Console.WriteLine("{0}", sql.OrderByExpression); - db.Select(sql); - - sql.OrderBy(cp => new { cp.Name, cp.Id }); - Console.WriteLine("{0}", sql.OrderByExpression); - db.Select(sql); - - sql.OrderBy(cp => new { cp.Name, Id = cp.Id * -1 }); - Console.WriteLine("{0}", sql.OrderByExpression); - db.Select(sql); - - sql.OrderByDescending(cp => cp.Name); - Console.WriteLine("{0}", sql.OrderByExpression); - db.Select(sql); - - sql.OrderBy(cp => new { cp.Name, X = cp.Id.Desc() }); - Console.WriteLine("{0}", sql.OrderByExpression); - db.Select(sql); - - sql.Where(cp => (string.Concat(cp.Name, "_", cp.Employees) == "SOME COMPANY XYZ_2")); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - sql.Where(cp => cp.Id != 1); - Console.WriteLine(sql.WhereExpression); - db.Select(sql); - - - sql.Select(cp => new { cp.Employees, cp.Name }); - Console.WriteLine("To Select:'{0}' ", sql.SelectExpression); - db.Select(sql); - - sql.Select(cp => new { cp.Employees, cp.Name, Some = (cp.Id * 4).As("SomeExpression") }); - Console.WriteLine("To Select:'{0}' ", sql.SelectExpression); - db.Select(sql); - - sql.Select(cp => new { cp.Employees, cp.Name, Some = cp.Turnover.Sum().As("SomeExpression") }); - Console.WriteLine("To Select:'{0}' ", sql.SelectExpression); - db.Select(sql); - - sql.Select(cp => new { cp.Employees, cp.Name, Some = DbMethods.Sum(cp.Turnover ?? 0).As("SomeExpression") }); - Console.WriteLine("To Select:'{0}' ", sql.SelectExpression); - db.Select(sql); - - - sql.Update(cp => new { cp.Employees, cp.Name }); - Console.WriteLine("To Update:'{0}' ", string.Join(",", sql.UpdateFields.ToArray())); - db.Select(sql); - - sql.Insert(cp => new { cp.Id, cp.Employees, cp.Name }); - Console.WriteLine("To Insert:'{0}' ", string.Join(",", sql.InsertFields.ToArray())); - db.Select(sql); - } - - Console.WriteLine("This is The End my friend!"); - } - } -} - diff --git a/src/OracleTests/TestLiteOracle04/TestLiteOracle04.csproj b/src/OracleTests/TestLiteOracle04/TestLiteOracle04.csproj deleted file mode 100644 index 4a4648246..000000000 --- a/src/OracleTests/TestLiteOracle04/TestLiteOracle04.csproj +++ /dev/null @@ -1,74 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {583D79EF-27D8-4725-B706-BFE041F096A4} - Exe - TestLiteFirebird04 - TestLiteFirebird04 - v4.0 - - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - {517B64BA-D7A6-4A15-8719-821B38147C61} - ServiceStack.OrmLite.Oracle - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - - - \ No newline at end of file diff --git a/src/OracleTests/TestLiteOracle04/app.config b/src/OracleTests/TestLiteOracle04/app.config deleted file mode 100644 index e36560333..000000000 --- a/src/OracleTests/TestLiteOracle04/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/OracleTests/TestSimpleOracle01/AssemblyInfo.cs b/src/OracleTests/TestSimpleOracle01/AssemblyInfo.cs deleted file mode 100644 index 875d4c3ab..000000000 --- a/src/OracleTests/TestSimpleOracle01/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebird01")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestSimpleOracle01/Main.cs b/src/OracleTests/TestSimpleOracle01/Main.cs deleted file mode 100644 index bbdc1d137..000000000 --- a/src/OracleTests/TestSimpleOracle01/Main.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using System.Collections.Generic; -using System.Data; - -using ServiceStack.Common.Utils; -using ServiceStack.DataAnnotations; -using ServiceStack.Common.Extensions; -using System.Reflection; - -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - -namespace TestLiteFirebird01 -{ - - [Alias("USERS")] - public class User - { - - [Alias("ID")] - [Sequence("USERS_ID_GEN")] - public int Id { get; set; } - [Alias("NAME")] - public string Name { get; set; } - [Alias("PASSWORD")] - public string Password { get; set; } - [Alias("COL1")] - public string Col1 { get; set; } - [Alias("COL2")] - public string Col2 { get; set; } - [Alias("COL3")] - public string Col3 { get; set; } - - [Alias("ACTIVEINTEGER")] - public bool Active { get; set; } - - [Alias("ACTIVECHAR")] - public bool Active2 { get; set; } - - [Ignore] - public string SomeStringProperty { - get{ return "SomeValue No from dB!!!";} - } - - [Ignore] - public Int32 SomeInt32Property { - get{ return 35;} - } - - [Ignore] - public DateTime SomeDateTimeProperty { - get{ return DateTime.Now ;} - } - - [Ignore] - public Int32? SomeInt32NullableProperty { - get{ return null;} - } - - [Ignore] - public DateTime? SomeDateTimeNullableProperty { - get{ return null ;} - } - - - - } - - class MainClass - { - public static void Main (string[] args) - { - - - //Set one before use (i.e. in a static constructor). - - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - using ( IDbCommand dbConn = db.CreateCommand()) - { - //try{ - - - dbConn.Insert(new User - { - Name= string.Format("Hello, World! {0}", DateTime.Now), - Password="jkkoo", - Col1="01", - Col2="02", - Col3="03" - - }); - - User user = new User(){ - Name="New User ", - Password= "kka", - Col1="XX", - Col2="YY", - Col3="ZZ", - Active=true - }; - - - dbConn.Insert(user); - - Console.WriteLine("++++++++++Id for {0} {1}",user.Name, user.Id); - - - var rows = dbConn.Select(); - - Console.WriteLine("++++++++++++++records in users {0}", rows.Count); - foreach(User u in rows){ - Console.WriteLine("{0} -- {1} -- {2} -- {3} -{4} --{5} ", u.Id, u.Name, u.SomeStringProperty, u.SomeDateTimeProperty, - (u.SomeInt32NullableProperty.HasValue)?u.SomeDateTimeNullableProperty.Value.ToString(): "", - u.Active); - dbConn.Delete(u); - } - - rows = dbConn.Select(); - - Console.WriteLine("-------------records in users after delete {0}", rows.Count); - - //} - - //catch(Exception e){ - // Console.WriteLine(e); - //} - } - - } - } -} - diff --git a/src/OracleTests/TestSimpleOracle01/TestLiteOracle01.csproj b/src/OracleTests/TestSimpleOracle01/TestLiteOracle01.csproj deleted file mode 100644 index d719b8dda..000000000 --- a/src/OracleTests/TestSimpleOracle01/TestLiteOracle01.csproj +++ /dev/null @@ -1,62 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003} - Exe - TestSimpleFirebird01 - TestSimpleFirebird01 - v3.5 - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - \ No newline at end of file diff --git a/src/OracleTests/TestSimpleOracle02/AssemblyInfo.cs b/src/OracleTests/TestSimpleOracle02/AssemblyInfo.cs deleted file mode 100644 index 017906d02..000000000 --- a/src/OracleTests/TestSimpleOracle02/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebird02")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestSimpleOracle02/Company.cs b/src/OracleTests/TestSimpleOracle02/Company.cs deleted file mode 100644 index ad3e8fdc7..000000000 --- a/src/OracleTests/TestSimpleOracle02/Company.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using ServiceStack.Common; -using ServiceStack.DataAnnotations; -using ServiceStack.DesignPatterns.Model; -using ServiceStack.OrmLite; - -namespace Database.Records -{ - [Alias("COMPANY")] - public partial class Company:IHasId{ - - public Company(){} - - [Alias("ID")] - [Sequence("COMPANY_ID_GEN")] - [PrimaryKey] - [AutoIncrement] - public System.Int32 Id { get; set;} - - [Alias("NAME")] - public System.String Name { get; set;} - - [Alias("TURNOVER")] - public System.Single? Turnover { get; set;} - - [Alias("STARTED")] - public System.DateTime? Started { get; set;} - - [Alias("EMPLOYEES")] - public System.Int32? Employees { get; set;} - - [Alias("CREATED_DATE")] - public System.DateTime? CreatedDate { get; set;} - - [Alias("GUID")] - public System.Guid? Guid { get; set;} - - - public static class Me { - - public static string TableName { get { return "COMPANY"; }} - public static string Id { get { return "ID"; }} - public static string Name { get { return "NAME"; }} - public static string Turnover { get { return "TURNOVER"; }} - public static string Started { get { return "STARTED"; }} - public static string Employees { get { return "EMPLOYEES"; }} - public static string CreatedDate { get { return "CREATED_DATE"; }} - public static string Guid { get { return "GUID"; }} - - } - } -} \ No newline at end of file diff --git a/src/OracleTests/TestSimpleOracle02/Main.cs b/src/OracleTests/TestSimpleOracle02/Main.cs deleted file mode 100644 index 46e0ec8db..000000000 --- a/src/OracleTests/TestSimpleOracle02/Main.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Linq; -using System.Data; -using System.ComponentModel.DataAnnotations; -using System.Collections.Generic; - -using ServiceStack.Common.Utils; -using ServiceStack.DataAnnotations; -using ServiceStack.Common.Extensions; -using ServiceStack.DesignPatterns.Model; - -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; -using Database.Records; - -namespace Database.Records{ - - public partial class Company{ - - [Ignore] - public string UpperName{ - get { return Name.ToUpper();} - } - } -} - - -namespace TestLiteFirebird2 -{ - - class MainClass - { - public static void Main (string[] args) - { - - //Set one before use (i.e. in a static constructor). - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - using ( IDbCommand dbConn = db.CreateCommand()) - { - try{ - - Console.WriteLine( dbConn.HasChildren( new Company(){Id=1000} ) ); - - Console.WriteLine(dbConn.HasChildren( new Company(){Id=5} )) ; - - Console.WriteLine( dbConn.Exists( Company.Me.Id+"={0}",5 ) ); - - Console.WriteLine(dbConn.Exists( Company.Me.Id+"={0}",1000 )) ; - - - var rows = dbConn.Select(); - Console.WriteLine("Company: rows before insert :{0}", rows.Count); - - Company cp = new Company{ - Name="One More Company", Employees=10, - Started= DateTime.Today, Turnover= 12525, - CreatedDate= DateTime.Now - }; - - - dbConn.Insert( cp); - - rows = dbConn.Select(); - Console.WriteLine("Company: rows after insert :{0}", rows.Count); - foreach(Company u in rows){ - Console.WriteLine("{0} -- {1}" , u.Id, u.Name); - } - Console.WriteLine("----------------------"); - - rows = dbConn.Select(Company.Me.Id+">={0} order by " +Company.Me.Id+" descending rows 5", - 10); - Console.WriteLine(rows.Count); - foreach(Company u in rows){ - Console.WriteLine("{0} -- {1} -- {2} -- {3} -- {4} -- {5} --{6}", u.Id, u.Name, - (u.Employees.HasValue)?u.Employees.Value.ToString():"", - u.Started.HasValue?u.Started.Value.ToString():"", - u.Turnover.HasValue?u.Turnover.Value.ToString():"", - u.CreatedDate.HasValue?u.CreatedDate.Value.ToString():"", - u.UpperName - ); - } - - - - } - - catch(Exception e){ - Console.WriteLine(e); - } - - - - } - } - - - } - - - //s.Substring(7, s.IndexOf("FROM")-8) --> columns - //s.Substring( s.IndexOf("FROM")+5) - -} diff --git a/src/OracleTests/TestSimpleOracle02/TestLiteOracle02.csproj b/src/OracleTests/TestSimpleOracle02/TestLiteOracle02.csproj deleted file mode 100644 index 4404dee30..000000000 --- a/src/OracleTests/TestSimpleOracle02/TestLiteOracle02.csproj +++ /dev/null @@ -1,63 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {924A8BBF-4D88-41A3-9F83-4332B0019D0C} - Exe - TestSimpleFirebird02 - TestSimpleFirebird02 - v3.5 - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - \ No newline at end of file diff --git a/src/OracleTests/TestSimpleOracle03/AssemblyInfo.cs b/src/OracleTests/TestSimpleOracle03/AssemblyInfo.cs deleted file mode 100644 index 1330c74e5..000000000 --- a/src/OracleTests/TestSimpleOracle03/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebird03")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestSimpleOracle03/Main.cs b/src/OracleTests/TestSimpleOracle03/Main.cs deleted file mode 100644 index adae6a7e1..000000000 --- a/src/OracleTests/TestSimpleOracle03/Main.cs +++ /dev/null @@ -1,123 +0,0 @@ - -using System; -using System.Data; -using System.Collections.Generic; - -using ServiceStack.Common.Utils; -using ServiceStack.DataAnnotations; -using ServiceStack.Common.Extensions; - -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - -namespace TestLiteFirebir03 -{ - class MainClass - { - public static void Main (string[] args) - { - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - { - - Schema fbd= new Schema(){ - Connection = db - }; - - Console.WriteLine("--------TABLES-------------"); - - var tables = fbd.Tables; - - foreach(Table t in tables){ - Console.WriteLine(t.Name); - } - - Console.WriteLine("-------users's owner--------------"); - - - Table t1 = fbd.GetTable("USERS"); - Console.WriteLine(t1.Owner); - - Console.WriteLine ("---------user's columns ----------------"); - - var Columns = fbd.GetColumns("USERS"); - - foreach(Column cl in Columns){ - Console.WriteLine("{0}--{1}--{2}--{3} -- {4}-- {5}--{6} ", - cl.Name,cl.Position, cl.Nullable, cl.Length, cl.DbType, cl.NetType, cl.Sequence); - } - - Console.WriteLine("--------------------------------------------"); - - Console.WriteLine("EMPLOYEE's Columns "); - - Columns = fbd.GetColumns("EMPLOYEE"); - - foreach(Column cl in Columns){ - Console.WriteLine("{0}--{1}--{2}--{3} -- {4}-- {5}--{6} -- Computed {7} ", - cl.Name,cl.Position, cl.Nullable, cl.Length, cl.DbType, - cl.NetType, cl.Sequence,cl.IsComputed); - } - - Columns = fbd.GetColumns("COMPANY"); - - foreach(Column cl in Columns){ - Console.WriteLine("{0}--{1}--{2}--{3} -- {4}-- {5}--{6} ", - cl.Name,cl.Position, cl.Nullable, cl.Length, cl.DbType, cl.NetType, cl.Sequence); - } - - Console.WriteLine("--------------------------------------------"); - - Console.WriteLine("-----------------Procedure---------------------------"); - - Console.WriteLine ("----- ADD_EMP_PROJ ----"); - - Procedure p = fbd.GetProcedure("ADD_EMP_PROJ"); - Console.WriteLine("p.Name {0} p.Owner {1} p.Inputs {2} p.Outputs {3} p.Type {4}", - p.Name, p.Owner, p.Inputs, p.Outputs, p.Type); - - var parameters = fbd.GetParameters(p); - foreach( var par in parameters){ - Console.WriteLine("p.ProcedureName {0} p.Name {1} p.Position {2} p.ParameterType {3} p.DbType {4} p.NetType {5}", - par.ProcedureName, par.Name, par.Position, par.Direction, par.DbType, par.NetType); - } - - - Console.WriteLine ("----- ALL_LANGS ----"); - p = fbd.GetProcedure("ALL_LANGS"); - Console.WriteLine("p.Name {0} p.Owner {1} p.Inputs {2} p.Outputs {3} p.Type {4}", - p.Name, p.Owner, p.Inputs, p.Outputs, p.Type); - - - parameters = fbd.GetParameters(p); - - parameters = fbd.GetParameters(p); - foreach( var par in parameters){ - Console.WriteLine("p.ProcedureName {0} p.Name {1} p.Position {2} p.ParameterType {3} p.DbType {4} p.NetType {5}", - par.ProcedureName, par.Name, par.Position, par.Direction, par.DbType, par.NetType); - } - - - ClassWriter cw = new ClassWriter(){ - Schema=fbd, - }; - - cw.WriteClass( new Table(){Name="EMPLOYEE"} ); - - - Console.WriteLine("This is The End my friend"); - - //DTOGenerator - - } - - - - - } - } -} - diff --git a/src/OracleTests/TestSimpleOracle03/TestSimpleOracle03.csproj b/src/OracleTests/TestSimpleOracle03/TestSimpleOracle03.csproj deleted file mode 100644 index e9f2236a3..000000000 --- a/src/OracleTests/TestSimpleOracle03/TestSimpleOracle03.csproj +++ /dev/null @@ -1,62 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {E4489930-7E42-43B8-93C3-7E1974845D88} - Exe - TestSimpleFirebird03 - TestSimpleFirebird03 - v3.5 - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - \ No newline at end of file diff --git a/src/OracleTests/TestSimpleOracleProcedures/AssemblyInfo.cs b/src/OracleTests/TestSimpleOracleProcedures/AssemblyInfo.cs deleted file mode 100644 index 88a32b5e7..000000000 --- a/src/OracleTests/TestSimpleOracleProcedures/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("TestSimpleFirebirdProcedures")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/OracleTests/TestSimpleOracleProcedures/Main.cs b/src/OracleTests/TestSimpleOracleProcedures/Main.cs deleted file mode 100644 index 598551f57..000000000 --- a/src/OracleTests/TestSimpleOracleProcedures/Main.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using System.Collections.Generic; -using System.Data; - -using ServiceStack.DataAnnotations; -using System.Reflection; - -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Firebird; - - -namespace TestLiteFirebirdProcedures -{ - - [Alias("EMPLOYEE")] - public class Employee{ - - [Alias("EMP_NO")] - [Sequence("EMP_NO_GEN")] - public Int16 Id{ - get; set; - } - - [Alias("FIRST_NAME")] - [Required] - public string FirstName{ - get; set; - } - - [Alias("LAST_NAME")] - [Required] - public string LastName{ - get; set; - } - - [Alias("PHONE_EXT")] - public string PhoneExtension{ - get; set; - } - - [Alias("HIRE_DATE")] - [Required] - public DateTime HireDate{ - get; set; - } - - [Alias("DEPT_NO")] - [Required] - public string DepartamentNumber{ - get; set; - } - - [Alias("JOB_CODE")] - [Required] - public string JobCode{ - get; set; - } - - [Alias("JOB_GRADE")] - public Int16 JobGrade{ - get; set; - } - - - [Alias("JOB_COUNTRY")] - [Required] - public string JobCountry{ - get; set; - } - - [Alias("SALARY")] - [Required] - public Decimal Salary{ - get; set; - } - - } - - [Alias("DELETE_EMPLOYEE")] - public class ProcedureDeleteEmployee - { - [Alias("EMP_NUM")] - public Int16 EmployeeNumber{ - get ; set; - } - - } - - [Alias("SUB_TOT_BUDGET")] - public class ProcedureSubTotalBudgetParameters{ - - [Alias("HEAD_DEPT")] - public string HeadDepartament{ - get; set; - } - - } - - public class ProcedureSubTotalBudgetResult{ - - [Alias("TOT_BUDGET")] - public decimal Total { - get; set; - } - - [Alias("AVG_BUDGET")] - public decimal Average { - get; set; - } - - [Alias("MAX_BUDGET")] - public decimal Max { - get; set; - } - - [Alias("MIN_BUDGET")] - public decimal Min { - get; set; - } - } - - - [Alias("SHOW_LANGS")] - public class ProcedureShowLangsParameters{ - - [Alias("CODE")] - public string Code{ - get; set; - } - - [Alias("GRADE")] - public Int16 Grade{ - get; set; - } - - [Alias("CTY")] - public string Country{ - get; set; - } - - } - - - public class ProcedureShowLangsResult{ - - [Alias("LANGUAGES")] - public string Language{ - get; set; - } - } - - [Alias("ALL_LANGS")] - public class ProcedureAllLangs{ - - public List Execute(IDbCommand dbConn){ - return dbConn.SelectFromProcedure(this); - } - - //public List Results{ - // get; set; - //} - - public class ProcedureAllLangsResult{ - - [Alias("CODE")] - public string Code{ - get; set; - } - - [Alias("GRADE")] - public string Grade{ - get; set; - } - - [Alias("COUNTRY")] - public string Country{ - get; set; - } - - [Alias("LANG")] - public string Language{ - get; set; - } - - } - - } - - - - - - - - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - using (IDbConnection db = - "User=SYSDBA;Password=masterkey;Database=employee.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - using ( IDbCommand dbConn = db.CreateCommand()) - { - try{ - - var employees = dbConn.Select(); - Console.WriteLine("Total Employees '{0}'", employees.Count); - - Employee employee = new Employee(){ - FirstName="LILA", - LastName= "FUTURAMA", - PhoneExtension="0002", - HireDate= DateTime.Now, - DepartamentNumber= "900", - JobCode="Eng", - JobGrade=2, - JobCountry="USA", - Salary=75000 - }; - int count = employees.Count; - - dbConn.Insert(employee); - Console.WriteLine ("Id for new employee : '{0}'", employee.Id); - - employees = dbConn.Select(); - Console.WriteLine("Total Employees '{0}' = '{1}'", employees.Count, count+1); - - Console.WriteLine("Executing 'DELETE_EMPLOYEE' for '{0}' - {1}", employee.Id, employee.LastName ); - ProcedureDeleteEmployee de = new ProcedureDeleteEmployee(); - de.EmployeeNumber= employee.Id; - dbConn.ExecuteProcedure(de); - - employees = dbConn.Select(); - Console.WriteLine("Total Employees '{0}'= '{1}' ", employees.Count, count); - - } - catch(Exception e){ - Console.WriteLine(e.Message); - } - - - try{ - - ProcedureSubTotalBudgetParameters p = new ProcedureSubTotalBudgetParameters() - { - HeadDepartament="000" - }; - - var results = dbConn.SelectFromProcedure(p, ""); - - - foreach(var r in results){ - Console.WriteLine("r.Total:{0} r.Average:{1} r.Max:{2} r.Min:{3}", r.Total, r.Average, r.Max, r.Min); - } - } - catch(Exception e){ - Console.WriteLine(e.Message); - } - - try{ - - ProcedureShowLangsParameters l = new ProcedureShowLangsParameters() - { - Code ="Sales", - Grade =3, - Country ="England" - }; - - var ls = dbConn.SelectFromProcedure(l,""); - - foreach(var lr in ls){ - Console.WriteLine(lr.Language); - } - } - catch(Exception e){ - Console.WriteLine(e.Message); - } - - try{ - - ProcedureAllLangs l = new ProcedureAllLangs(); - - //var ls = dbConn.SelectFromProcedure(l); - //dbConn.SelectFromProcedure(l); - - - var ls = l.Execute(dbConn); // better ? - - foreach(var lr in ls){ - Console.WriteLine("lr.Code:{0} lr.Country:{1} lr.Grade:{2} lr.Language:{3}", - lr.Code, lr.Country, lr.Grade, lr.Language); - } - } - catch(Exception e){ - Console.WriteLine(e.Message); - } - - - Console.WriteLine ("This is The End my friend!"); - } - - } - } -} - diff --git a/src/OracleTests/TestSimpleOracleProcedures/TestSimpleOracleProcedures.csproj b/src/OracleTests/TestSimpleOracleProcedures/TestSimpleOracleProcedures.csproj deleted file mode 100644 index 73f859dd1..000000000 --- a/src/OracleTests/TestSimpleOracleProcedures/TestSimpleOracleProcedures.csproj +++ /dev/null @@ -1,62 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {60B6BD41-6415-418E-A71F-FB6622C379D9} - Exe - TestSimpleFirebirdProcedures - TestSimpleFirebirdProcedures - v3.5 - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - - - - - - ..\..\..\lib\ServiceStack.Common.dll - - - ..\..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\..\lib\ServiceStack.Text.dll - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - \ No newline at end of file diff --git a/src/PostgreSQLExpressionsTest/AssemblyInfo.cs b/src/PostgreSQLExpressionsTest/AssemblyInfo.cs deleted file mode 100644 index 998a7f854..000000000 --- a/src/PostgreSQLExpressionsTest/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("PostgreSQLExpressionsTest")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("angel")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/src/PostgreSQLExpressionsTest/Main.cs b/src/PostgreSQLExpressionsTest/Main.cs deleted file mode 100644 index 8a27d5ee6..000000000 --- a/src/PostgreSQLExpressionsTest/Main.cs +++ /dev/null @@ -1,262 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.PostgreSQL; - - -namespace PostgreSQLExpressionsTest -{ - public class Author - { - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - public DateTime Birthday { get; set;} - public DateTime ? LastActivity { get; set;} - public Decimal? Earnings { get; set;} - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - public Int16 Rate{ get; set;} - } - - - - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - OrmLiteConfig.DialectProvider = PostgreSQLDialectProvider.Instance; - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (IDbConnection db = - "Server=localhost;Port=5432;User Id=postgres; Password=postgres; Database=ormlite".OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.DeleteAll(); - - List authors = new List(); - authors.Add(new Author(){Name="Demis Bellot",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 99.9m,Comments="CSharp books", Rate=10, City="London"}); - authors.Add(new Author(){Name="Angel Colmenares",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 50.0m,Comments="CSharp books", Rate=5, City="Bogota"}); - authors.Add(new Author(){Name="Adam Witco",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 80.0m,Comments="Math Books", Rate=9, City="London"}); - authors.Add(new Author(){Name="Claudia Espinel",Birthday= DateTime.Today.AddYears(-23),Active=true,Earnings= 60.0m,Comments="Cooking books", Rate=10, City="Bogota"}); - authors.Add(new Author(){Name="Libardo Pajaro",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 80.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Jorge Garzon",Birthday= DateTime.Today.AddYears(-28),Active=true,Earnings= 70.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Alejandro Isaza",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 70.0m,Comments="Java books", Rate=0, City="Bogota"}); - authors.Add(new Author(){Name="Wilmer Agamez",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 30.0m,Comments="Java books", Rate=0, City="Cartagena"}); - authors.Add(new Author(){Name="Rodger Contreras",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 90.0m,Comments="CSharp books", Rate=8, City="Cartagena"}); - authors.Add(new Author(){Name="Chuck Benedict",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="CSharp books", Rate=8, City="London"}); - authors.Add(new Author(){Name="James Benedict II",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="Java books", Rate=5, City="Berlin"}); - authors.Add(new Author(){Name="Ethan Brown",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 45.0m,Comments="CSharp books", Rate=5, City="Madrid"}); - authors.Add(new Author(){Name="Xavi Garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 75.0m,Comments="CSharp books", Rate=9, City="Madrid"}); - authors.Add(new Author(){Name="Luis garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.0m,Comments="CSharp books", Rate=10, City="Mexico"}); - - db.InsertAll(authors); - - - // lets start ! - - // select authors born 20 year ago - int year = DateTime.Today.AddYears(-20).Year; - int expected=5; - - ev.Where(rn=> rn.Birthday>=new DateTime(year, 1,1) && rn.Birthday<=new DateTime(year, 12,31)); - List result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31))); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected=6; - ev.Where(rn=> Sql.In( rn.City, new object[]{"London", "Madrid", "Berlin"}) ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors from Bogota and Cartagena : 7 - expected=7; - ev.Where(rn => Sql.In(rn.City, new object[] { "Bogota", "Cartagena" })); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name starts with A - expected=3; - ev.Where(rn=> rn.Name.StartsWith("A") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.ToUpper().EndsWith("GARZON") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors which name ends with garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.EndsWith("garzon") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors which name contains Benedict - expected=2; - ev.Where(rn=> rn.Name.Contains("Benedict") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // select authors with Earnings <= 50 - expected=3; - ev.Where(rn=> rn.Earnings<=50 ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // select authors with Rate = 10 and city=Mexio - expected=1; - ev.Where(rn=> rn.Rate==10 && rn.City=="Mexico"); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected=2; - ev.Where(rn=> rn.Rate==0 ).Update(rn=> rn.Active); - var rows = db.UpdateOnly( new Author(){ Active=false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected=4; - ev.Insert(rn =>new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate} ); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Victor Grozny", Birthday=DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Ivan Chorny", Birthday=DateTime.Today.AddYears(-19) }, ev); - ev.Where(rn=> !rn.Active); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - //update comment for City == null - expected=2; - ev.Where( rn => rn.City==null ).Update(rn=> rn.Comments); - rows=db.UpdateOnly(new Author(){Comments="No comments"}, ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // delete where City is null - expected=2; - rows = db.Delete( ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected=14; - ev.Where().OrderBy(rn=> new{ at=Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - Console.WriteLine(ev.OrderByExpression); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel", author.Name, "Claudia Espinel"==author.Name); - - // select only first 5 rows .... - - expected=5; - ev.Limit(5); // note: order is the same as in the last sentence - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn=> new { at= Sql.As( rn.Name.ToUpper(), "Name" ), rn.City} ); - Console.WriteLine(ev.SelectExpression); - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - //paging : - ev.Limit(0,4);// first page, page size=4; - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - ev.Limit(4,4);// second page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper()==author.Name); - - ev.Limit(8,4);// third page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper()==author.Name); - - - // select distinct.. - ev.Limit().OrderBy(); // clear limit and order for postgres - ev.SelectDistinct(r=>r.City); - expected=6; - result=db.Select(ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - Console.WriteLine(); - // Tests for predicate overloads that make use of the expression visitor - Console.WriteLine("First author by name (exists)"); - author = db.Single(a => a.Name == "Jorge Garzon"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon", author.Name, "Jorge Garzon" == author.Name); - - try - { - Console.WriteLine("First author by name (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - - Console.WriteLine("Expected exception thrown, OK? False"); - } - catch - { - Console.WriteLine("Expected exception thrown, OK? True"); - } - - Console.WriteLine("First author or default (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - Console.WriteLine("Expected:null ; OK? {0}", author == null); - - Console.WriteLine("First author or default by city (multiple matches)"); - author = db.Single(a => a.City == "Bogota"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Angel Colmenares", author.Name, "Angel Colmenares" == author.Name); - - Console.ReadLine(); - Console.WriteLine("Press Enter to continue"); - - } - - Console.WriteLine ("This is The End my friend!"); - } - } -} \ No newline at end of file diff --git a/src/PostgreSQLExpressionsTest/PostgreSQLExpressionsTest.csproj b/src/PostgreSQLExpressionsTest/PostgreSQLExpressionsTest.csproj deleted file mode 100644 index df4f945b5..000000000 --- a/src/PostgreSQLExpressionsTest/PostgreSQLExpressionsTest.csproj +++ /dev/null @@ -1,75 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {348E82EE-7D30-4D60-90E5-CA60C290C589} - Exe - PostgreSQLExpressionsTest - PostgreSQLExpressionsTest - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - none - false - bin\Release - prompt - 4 - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - - - - ..\..\lib\Mono.Security.dll - - - ..\..\lib\Npgsql.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5} - ServiceStack.OrmLite.PostgreSQL - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Android.sln b/src/ServiceStack.OrmLite.Android.sln deleted file mode 100644 index 59701b4f1..000000000 --- a/src/ServiceStack.OrmLite.Android.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Android", "ServiceStack.OrmLite\ServiceStack.OrmLite.Android.csproj", "{42BF9D4F-100D-4577-8538-5FD309D2CBEB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Sqlite.Android", "ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.Android.csproj", "{85DC23CC-BB59-4775-AA9C-552FF2BBEB22}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {42BF9D4F-100D-4577-8538-5FD309D2CBEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {42BF9D4F-100D-4577-8538-5FD309D2CBEB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {42BF9D4F-100D-4577-8538-5FD309D2CBEB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {42BF9D4F-100D-4577-8538-5FD309D2CBEB}.Release|Any CPU.Build.0 = Release|Any CPU - {85DC23CC-BB59-4775-AA9C-552FF2BBEB22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {85DC23CC-BB59-4775-AA9C-552FF2BBEB22}.Debug|Any CPU.Build.0 = Debug|Any CPU - {85DC23CC-BB59-4775-AA9C-552FF2BBEB22}.Release|Any CPU.ActiveCfg = Release|Any CPU - {85DC23CC-BB59-4775-AA9C-552FF2BBEB22}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = ServiceStack.OrmLite\ServiceStack.OrmLite.Android.csproj - EndGlobalSection -EndGlobal diff --git a/src/ServiceStack.OrmLite.DDLTest/ServiceStack.OrmLite.DDLTest.csproj b/src/ServiceStack.OrmLite.DDLTest/ServiceStack.OrmLite.DDLTest.csproj deleted file mode 100644 index 06b767e9c..000000000 --- a/src/ServiceStack.OrmLite.DDLTest/ServiceStack.OrmLite.DDLTest.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - Debug - AnyCPU - 12.0.0 - 2.0 - {E106F587-2DFF-4550-BA49-9A81A2EC344F} - Library - ServiceStack.OrmLite.DDLTest - ServiceStack.OrmLite.DDLTest - v4.5 - - ..\ - true - - - True - full - False - bin\Debug - DEBUG; - prompt - 4 - False - false - - - none - True - bin\Release - prompt - 4 - False - false - - - bin\Signed\ - true - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - - ..\packages\MySql.Data.6.9.5\lib\net45\MySql.Data.dll - - - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\FirebirdSql.Data.FirebirdClient.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - {fd20f088-acc0-4979-ac0c-8c541c2e7de5} - ServiceStack.OrmLite.MySql - - - {1887dc99-9139-43e3-a7aa-6d74714b3a5d} - ServiceStack.OrmLite.SqlServer - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.DDLTest/Test.cs b/src/ServiceStack.OrmLite.DDLTest/Test.cs deleted file mode 100644 index f7607e19a..000000000 --- a/src/ServiceStack.OrmLite.DDLTest/Test.cs +++ /dev/null @@ -1,173 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Firebird; -using ServiceStack.OrmLite.MySql; -using ServiceStack.OrmLite.SqlServer; -using System.Collections.Generic; -using ServiceStack.Logging; - - -namespace ServiceStack.OrmLite.DDLTest -{ - - - [TestFixture()] - public class Test - { - List dialects = new List(); - - [TestFixtureSetUp] - public void TestFixtureSetup() - { - dialects.Add ( new Dialect{ - Provider= FirebirdOrmLiteDialectProvider.Instance, - AddColumnString="ALTER TABLE Model ADD Column1 VARCHAR(128) ;", - AlterColumnString="ALTER TABLE Model ALTER Column2 VARCHAR(50) ;", - ChangeColumnNameString="ALTER TABLE Model ALTER OldColumn3 TO Column3 ;", - AddFKString="ALTER TABLE Child ADD CONSTRAINT JustOneFK FOREIGN KEY (IdModel) REFERENCES Model (Id) ON DELETE CASCADE ON UPDATE NO ACTION;", - AddFKRestrictString="ALTER TABLE Child ADD CONSTRAINT JustOneMoreFK FOREIGN KEY (IdModel) REFERENCES Model (Id) ON UPDATE NO ACTION;", - CreateIndexString="CREATE UNIQUE INDEX JustIndexOnColumn3 ON Model(Column3);" - - }); - dialects.Add ( new Dialect{ - Provider= MySqlDialectProvider.Instance, - AddColumnString="ALTER TABLE `Model` ADD COLUMN `Column1` VARCHAR(255) NULL;", - AlterColumnString="ALTER TABLE `Model` MODIFY COLUMN `Column2` VARCHAR(50) NULL;", - ChangeColumnNameString="ALTER TABLE `Model` CHANGE COLUMN `OldColumn3` `Column3` VARCHAR(255) NULL;", - AddFKString="ALTER TABLE `Child` ADD CONSTRAINT `JustOneFK` FOREIGN KEY (`IdModel`) REFERENCES `Model` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION;", - AddFKRestrictString="ALTER TABLE `Child` ADD CONSTRAINT `JustOneMoreFK` FOREIGN KEY (`IdModel`) REFERENCES `Model` (`Id`) ON DELETE RESTRICT ON UPDATE NO ACTION;", - CreateIndexString="CREATE UNIQUE INDEX `JustIndexOnColumn3` ON `Model`(`Column3`);" - }); - - dialects.Add ( new Dialect{ - Provider= SqlServerOrmLiteDialectProvider.Instance, - AddColumnString = @"ALTER TABLE ""Model"" ADD ""Column1"" VARCHAR(8000) NULL;", - AlterColumnString = @"ALTER TABLE ""Model"" ALTER COLUMN ""Column2"" VARCHAR(50) NULL;", - ChangeColumnNameString = @"EXEC sp_rename 'Model.OldColumn3', 'Column3', 'COLUMN';", - AddFKString = @"ALTER TABLE ""Child"" ADD CONSTRAINT ""JustOneFK"" FOREIGN KEY (""IdModel"") REFERENCES ""Model"" (""Id"") ON DELETE CASCADE ON UPDATE NO ACTION;", - AddFKRestrictString = @"ALTER TABLE ""Child"" ADD CONSTRAINT ""JustOneMoreFK"" FOREIGN KEY (""IdModel"") REFERENCES ""Model"" (""Id"") ON UPDATE NO ACTION;", - CreateIndexString = @"CREATE UNIQUE INDEX ""JustIndexOnColumn3"" ON ""Model""(""Column3"");" - }); - - LogManager.LogFactory = new ConsoleLogFactory(); - } - - [Test()] - public void CanAddColumn () - { - var model = typeof(Model); - - foreach (var d in dialects) - { - OrmLiteConfig.DialectProvider=d.Provider; - var fielDef = ModelDefinition.Definition.GetFieldDefinition (f => f.Column1); - Assert.AreEqual(d.AddColumnString, (d.Provider.ToAddColumnStatement(model, fielDef))); - } - } - - [Test()] - public void CanAAlterColumn () - { - var model = typeof(Model); - - foreach (var d in dialects) - { - OrmLiteConfig.DialectProvider=d.Provider; - var fielDef = ModelDefinition.Definition.GetFieldDefinition (f => f.Column2); - Assert.AreEqual(d.AlterColumnString, (d.Provider.ToAlterColumnStatement(model, fielDef))); - } - - } - - - [Test()] - public void CanChangeColumnName () - { - var model = typeof(Model); - - foreach (var d in dialects) - { - OrmLiteConfig.DialectProvider=d.Provider; - var fielDef = ModelDefinition.Definition.GetFieldDefinition (f => f.Column3); - Assert.AreEqual(d.ChangeColumnNameString,(d.Provider.ToChangeColumnNameStatement(model, fielDef,"OldColumn3"))); - - } - - } - - [Test()] - public void CanAddForeignKey () - { - - foreach (var d in dialects) - { - OrmLiteConfig.DialectProvider=d.Provider; - Assert.AreEqual(d.AddFKString, - d.Provider.ToAddForeignKeyStatement(f=>f.IdModel, - fk=>fk.Id,OnFkOption.NoAction,OnFkOption.Cascade, "JustOneFK")); - } - } - - [Test()] - public void CanAddForeignKeyRestrict () - { - - foreach (var d in dialects) - { - OrmLiteConfig.DialectProvider=d.Provider; - Assert.AreEqual(d.AddFKRestrictString, - d.Provider.ToAddForeignKeyStatement(f=>f.IdModel, - fk=>fk.Id,OnFkOption.NoAction,OnFkOption.Restrict, "JustOneMoreFK")); - } - } - - - [Test()] - public void CanCreateIndex () - { - - foreach (var d in dialects) - { - OrmLiteConfig.DialectProvider=d.Provider; - Assert.AreEqual(d.CreateIndexString, d.Provider.ToCreateIndexStatement(f=>f.Column3, "JustIndexOnColumn3", true) ); - - } - - } - - - } - - public class Model - { - public Model() - { - } - public int Id { get; set; } - public string Column1{ get; set; } - [StringLength(50)] - public string Column2{ get; set; } - public string Column3{ get; set; } - - } - - public class Child - { - public Child(){} - public int Id{ get; set;} - public int IdModel{ get; set;} - - } - - public class Dialect - { - public IOrmLiteDialectProvider Provider { get; set; } - public string AddColumnString { get; set; } - public string AlterColumnString { get; set; } - public string ChangeColumnNameString { get; set; } - public string AddFKString { get; set; } - public string AddFKRestrictString { get; set; } - public string CreateIndexString { get; set; } - - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.DDLTest/app.config b/src/ServiceStack.OrmLite.DDLTest/app.config deleted file mode 100644 index 5fc726c03..000000000 --- a/src/ServiceStack.OrmLite.DDLTest/app.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.DDLTest/packages.config b/src/ServiceStack.OrmLite.DDLTest/packages.config deleted file mode 100644 index 9ac31173e..000000000 --- a/src/ServiceStack.OrmLite.DDLTest/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdBoolConverter.cs b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdBoolConverter.cs new file mode 100644 index 000000000..851e7195f --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdBoolConverter.cs @@ -0,0 +1,13 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Firebird.Converters +{ + public class FirebirdBoolConverter : BoolAsIntConverter + { + public override string ColumnDefinition + { + get { return "INTEGER"; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdByteArrayConverter.cs b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdByteArrayConverter.cs new file mode 100644 index 000000000..1382258d4 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdByteArrayConverter.cs @@ -0,0 +1,13 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Firebird.Converters +{ + public class FirebirdByteArrayConverter : ByteArrayConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + return "x'" + BitConverter.ToString((byte[])value).Replace("-", "") + "'"; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdDateTimeConverter.cs b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdDateTimeConverter.cs new file mode 100644 index 000000000..18f7b4342 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdDateTimeConverter.cs @@ -0,0 +1,24 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Firebird.Converters +{ + public class FirebirdDateTimeConverter : DateTimeConverter + { + public override string ColumnDefinition + { + get { return "TIMESTAMP"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var dateTime = (DateTime)value; + var iso8601Format = dateTime.ToString("yyyy-MM-dd HH:mm:ss.fff") + .EndsWith("00:00:00.000") + ? "yyyy-MM-dd" + : "yyyy-MM-dd HH:mm:ss.fff"; + + return DateTimeFmt(dateTime, iso8601Format); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdDateTimeOffsetConverter.cs b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdDateTimeOffsetConverter.cs new file mode 100644 index 000000000..2bd393f47 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdDateTimeOffsetConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Firebird.Converters +{ + public class FirebirdDateTimeOffsetConverter : DateTimeOffsetConverter + { + public override string ColumnDefinition + { + get { return "VARCHAR(255)"; } + } + + public override DbType DbType + { + get { return DbType.DateTime; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdFloatConverters.cs b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdFloatConverters.cs new file mode 100644 index 000000000..fe99d4698 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdFloatConverters.cs @@ -0,0 +1,46 @@ +using System; +using System.Globalization; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Firebird.Converters +{ + public class FirebirdFloatConverter : FloatConverter + { + public override string ColumnDefinition + { + get { return "FLOAT"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var s = ((float)value).ToString(CultureInfo.InvariantCulture); + if (s.Length > 20) s = s.Substring(0, 20); + return "'" + s + "'"; // when quoted exception is more clear! + } + } + + public class FirebirdDoubleConverter : FloatConverter + { + public override string ColumnDefinition + { + get { return "FLOAT"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var s = ((double)value).ToString(CultureInfo.InvariantCulture); + if (s.Length > 20) s = s.Substring(0, 20); + return "'" + s + "'"; // when quoted exception is more clear! + } + } + + public class FirebirdDecimalConverter : DecimalConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + var s = ((decimal)value).ToString(CultureInfo.InvariantCulture); + if (s.Length > 20) s = s.Substring(0, 20); + return "'" + s + "'"; // when quoted exception is more clear! + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdGuidConverter.cs b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdGuidConverter.cs new file mode 100644 index 000000000..4b2f18a17 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdGuidConverter.cs @@ -0,0 +1,52 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Firebird.Converters +{ + public class FirebirdGuidConverter : GuidConverter + { + public override string ColumnDefinition + { + get { return "VARCHAR(37)"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + return string.Format("CAST('{0}' AS {1})", (Guid)value, ColumnDefinition); // TODO : check this !!! + } + + public override object FromDbValue(Type fieldType, object value) + { + return new Guid(value.ToString()); + } + + public override object ToDbValue(Type fieldType, object value) + { + return base.ToDbValue(fieldType, value); + } + } + + public class FirebirdCompactGuidConverter : GuidConverter + { + public override string ColumnDefinition + { + get { return "CHAR(16) CHARACTER SET OCTETS"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + return "X'" + ((Guid)value).ToString("N") + "'"; + } + + public override object FromDbValue(Type fieldType, object value) + { + //BitConverter.IsLittleEndian // TODO: check big endian + + byte[] raw = ((Guid)value).ToByteArray(); + return new Guid(System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt32(raw, 0)), + System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt16(raw, 4)), + System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt16(raw, 6)), + raw[8], raw[9], raw[10], raw[11], raw[12], raw[13], raw[14], raw[15]); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdStringConverters.cs b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdStringConverters.cs new file mode 100644 index 000000000..a95b8c30e --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Converters/FirebirdStringConverters.cs @@ -0,0 +1,38 @@ +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Firebird.Converters +{ + public class FirebirdStringConverter : StringConverter + { + public FirebirdStringConverter() : base(128) {} + + public override string MaxColumnDefinition + { + get + { + //Max field is 32767 but using lower limit to avoid 64kb max row limit + return maxColumnDefinition ?? GetColumnDefinition(10000); + } + } + + public override string GetColumnDefinition(int? stringLength) + { + if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText) + return MaxColumnDefinition; + + return $"VARCHAR({stringLength.GetValueOrDefault(StringLength)})"; + } + } + + public class FirebirdCharArrayConverter : CharArrayConverter + { + public override string MaxColumnDefinition => DialectProvider.GetStringConverter().MaxColumnDefinition; + + public override string GetColumnDefinition(int? stringLength) + { + return MaxColumnDefinition; + } + } + +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/DbSchema/PocoCreator.cs b/src/ServiceStack.OrmLite.Firebird/DbSchema/PocoCreator.cs index 198d8cace..712e0d389 100644 --- a/src/ServiceStack.OrmLite.Firebird/DbSchema/PocoCreator.cs +++ b/src/ServiceStack.OrmLite.Firebird/DbSchema/PocoCreator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using System.Collections.Generic; using System.Globalization; @@ -220,7 +220,7 @@ public partial class {1} }}"; private string serviceTemplate =@"using System; -using ServiceStack.CacheAccess; + using ServiceStack.CacheAccess; using ServiceStack.Common; using ServiceStack.ServiceHost; using ServiceStack.ServiceInterface; diff --git a/src/ServiceStack.OrmLite.Firebird/FbSchema/Schema.cs b/src/ServiceStack.OrmLite.Firebird/FbSchema/Schema.cs index 81d393629..d051f40ab 100644 --- a/src/ServiceStack.OrmLite.Firebird/FbSchema/Schema.cs +++ b/src/ServiceStack.OrmLite.Firebird/FbSchema/Schema.cs @@ -4,6 +4,7 @@ using System.Text; using System.Data; using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Legacy; using ServiceStack.OrmLite.Firebird.DbSchema; namespace ServiceStack.OrmLite.Firebird @@ -26,21 +27,15 @@ public Schema() Init(); } - public List
Tables - { - get - { - return Connection.SelectFmt
(sqlTables); - } - } + public List
Tables => Connection.Select
(sqlTables); public Table GetTable(string name) { string sql = sqlTables + - string.Format(" AND a.rdb$relation_name ='{0}' ", name); + $" AND a.rdb$relation_name ='{name}' "; - var query = Connection.SelectFmt
(sql); + var query = Connection.Select
(sql); return query.FirstOrDefault(); } @@ -48,20 +43,17 @@ public List GetColumns(string tableName) { string sql = string.Format(sqlColumns.ToString(), - string.IsNullOrEmpty(tableName) ? "idx.rdb$relation_name" : - string.Format("'{0}'", tableName), - string.IsNullOrEmpty(tableName) ? "r.rdb$relation_name" : - string.Format("'{0}'", tableName)); + string.IsNullOrEmpty(tableName) ? "idx.rdb$relation_name" : $"'{tableName}'", + string.IsNullOrEmpty(tableName) ? "r.rdb$relation_name" : $"'{tableName}'"); - List columns =Connection.SelectFmt(sql); + List columns =Connection.Select(sql); - List gens = Connection.SelectFmt(sqlGenerator.ToString()); + List gens = Connection.Select(sqlGenerator.ToString()); sql = string.Format(sqlFieldGenerator.ToString(), - string.IsNullOrEmpty(tableName) ? "TRIGGERS.RDB$RELATION_NAME" : - string.Format("'{0}'", tableName)); + string.IsNullOrEmpty(tableName) ? "TRIGGERS.RDB$RELATION_NAME" : $"'{tableName}'"); - List fg = Connection.SelectFmt(sql); + List fg = Connection.Select(sql); foreach (var record in columns) { @@ -74,7 +66,7 @@ public List GetColumns(string tableName) else { string g = (from gen in gens - where gen.Name == tableName + "_" + record.Name + "_GEN" + where gen.Name == $"{tableName}_{record.Name}_GEN" select gen.Name).FirstOrDefault(); if (!string.IsNullOrEmpty(g)) record.Sequence = g.Trim(); @@ -93,19 +85,13 @@ public List GetColumns(Table table) public Procedure GetProcedure(string name) { string sql= sqlProcedures.ToString() + - string.Format("WHERE b.rdb$procedure_name ='{0}'", name); + $"WHERE b.rdb$procedure_name ='{name}'"; - var query = Connection.SelectFmt(sql); + var query = Connection.Select(sql); return query.FirstOrDefault(); } - public List Procedures - { - get - { - return Connection.SelectFmt(sqlProcedures.ToString()); - } - } + public List Procedures => Connection.Select(sqlProcedures.ToString()); public List GetParameters(Procedure procedure) { @@ -116,10 +102,9 @@ public List GetParameters(string procedureName) { string sql = string.Format(sqlParameters.ToString(), - string.IsNullOrEmpty(procedureName) ? "a.rdb$procedure_name" : - string.Format("'{0}'", procedureName)); + string.IsNullOrEmpty(procedureName) ? "a.rdb$procedure_name" : $"'{procedureName}'"); - return Connection.SelectFmt(sql); + return Connection.Select(sql); } private void Init() diff --git a/src/ServiceStack.OrmLite.Firebird/Firebird.cs b/src/ServiceStack.OrmLite.Firebird/Firebird.cs deleted file mode 100644 index e6953441e..000000000 --- a/src/ServiceStack.OrmLite.Firebird/Firebird.cs +++ /dev/null @@ -1,9 +0,0 @@ -using ServiceStack.OrmLite.Firebird; - -namespace ServiceStack.OrmLite -{ - public static class FirebirdDialect - { - public static IOrmLiteDialectProvider Provider { get { return FirebirdOrmLiteDialectProvider.Instance; } } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Firebird4NamingStrategy.cs b/src/ServiceStack.OrmLite.Firebird/Firebird4NamingStrategy.cs new file mode 100644 index 000000000..c44e20a13 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Firebird4NamingStrategy.cs @@ -0,0 +1,10 @@ +using System; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Firebird +{ + public class Firebird4NamingStrategy : FirebirdNamingStrategy + { + public Firebird4NamingStrategy() : base(63) { } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/Firebird4OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Firebird/Firebird4OrmLiteDialectProvider.cs new file mode 100644 index 000000000..71c7d1939 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/Firebird4OrmLiteDialectProvider.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Reflection; +using System.Text; +using System.Linq; +using FirebirdSql.Data.FirebirdClient; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite; +using ServiceStack.OrmLite.Firebird.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Firebird +{ + public class Firebird4OrmLiteDialectProvider : FirebirdOrmLiteDialectProvider + { + private readonly bool usesCompactGuid; + + public new static List RESERVED = new List(new[] { + "ADD","ADMIN","ALL","ALTER","AND","ANY","AS","AT","AVG","BEGIN","BETWEEN","BIGINT","BIT_LENGTH","BLOB","BOTH","BY","CASE","CAST", + "CHAR","CHAR_LENGTH","CHARACTER","CHARACTER_LENGTH","CHECK","CLOSE","COLLATE","COLUMN","COMMIT","CONNECT","CONSTRAINT","COUNT","CREATE", + "CROSS","CURRENT","CURRENT_CONNECTION","CURRENT_DATE","CURRENT_ROLE","CURRENT_TIME","CURRENT_TIMESTAMP","CURRENT_TRANSACTION","CURRENT_USER", + "CURSOR","DATE","DAY","DEC","DECIMAL","DECLARE","DEFAULT","DELETE","DISCONNECT","DISTINCT","DOUBLE","DROP","ELSE","END","ESCAPE", + "EXECUTE","EXISTS","EXTERNAL","EXTRACT","FETCH","FILTER","FLOAT","FOR","FOREIGN","FROM","FULL","FUNCTION","GDSCODE","GLOBAL","GRANT","GROUP", + "HAVING","HOUR","IN","INDEX","INNER","INSENSITIVE","INSERT","INT","INTEGER","INTO","IS","JOIN","LEADING","LEFT","LIKE","LONG","LOWER","MAX", + "MAXIMUM_SEGMENT","MERGE","MIN","MINUTE","MONTH","NATIONAL","NATURAL","NCHAR","NO","NOT","NULL","NUMERIC","OCTET_LENGTH","OF","ON","ONLY", + "OPEN","OR","ORDER","OUTER","PARAMETER","PLAN","POSITION","POST_EVENT","PRECISION","PRIMARY","PROCEDURE","RDB$DB_KEY","REAL","RECORD_VERSION", + "RECREATE","RECURSIVE","REFERENCES","RELEASE","RETURNING_VALUES","RETURNS","REVOKE","RIGHT","ROLLBACK","ROW_COUNT","ROWS","SAVEPOINT","SECOND", + "SELECT","SENSITIVE","SET","SIMILAR","SMALLINT","SOME","SQLCODE","SQLSTATE","START","SUM","TABLE","THEN","TIME","TIMESTAMP","TO","TRAILING", + "TRIGGER","TRIM","UNION","UNIQUE","UPDATE","UPPER","USER","USING","VALUE","VALUES","VARCHAR","VARIABLE","VARYING","VIEW","WHEN","WHERE","WHILE", + "WITH","YEAR", + "PASSWORD","ACTIVE","LEFT","DATETIME","TYPE","KEY", + // new in FB3 + "INSERTING","UPDATING","DELETING","REGR_AVGX","SCROLL","CORR","REGR_AVGY","COVAR_POP","REGR_COUNT","STDDEV_POP", + "COVAR_SAMP","REGR_INTERCEPT","STDDEV_SAMP","REGR_R2","TRUE","DETERMINISTIC","REGR_SLOPE","UNKNOWN","FALSE","REGR_SXX", + "REGR_SXY","VAR_POP","OFFSET","REGR_SYY","VAR_SAMP","OVER","RETURN","RDB$RECORD_VERSION","ROW","BOOLEAN", + // new in FB4 + "BINARY","VARBINARY","DECFLOAT" + }); + + public new static Firebird4OrmLiteDialectProvider Instance = new Firebird4OrmLiteDialectProvider(); + + public Firebird4OrmLiteDialectProvider() : this(true) { } + + public Firebird4OrmLiteDialectProvider(bool compactGuid): base(compactGuid) + { + usesCompactGuid = compactGuid; + + // FB4 now has identity columns + base.AutoIncrementDefinition = " GENERATED ALWAYS AS IDENTITY "; + NamingStrategy = new Firebird4NamingStrategy(); + + base.RemoveConverter(); + + this.Variables = new Dictionary + { + { OrmLiteVariables.SystemUtc, "CURRENT_TIMESTAMP" }, + { OrmLiteVariables.MaxText, "VARCHAR(1000)" }, + { OrmLiteVariables.MaxTextUnicode, "VARCHAR(2048)" }, + { OrmLiteVariables.True, SqlBool(true) }, + { OrmLiteVariables.False, SqlBool(false) }, + }; + } + + public override string ToCreateTableStatement(Type tableType) + { + var sbColumns = StringBuilderCache.Allocate(); + var sbConstraints = StringBuilderCacheAlt.Allocate(); + + var sbPk = new StringBuilder(); + + var modelDef = GetModel(tableType); + foreach (var fieldDef in CreateTableFieldsStrategy(modelDef)) + { + if (fieldDef.CustomSelect != null || (fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; + + if (fieldDef.IsPrimaryKey) + sbPk.AppendFormat(sbPk.Length != 0 ? ",{0}" : "{0}", GetQuotedColumnName(fieldDef.FieldName)); + + if (sbColumns.Length != 0) + sbColumns.Append(", \n "); + + var columnDefinition = GetColumnDefinition(fieldDef); + sbColumns.Append(columnDefinition); + + if (fieldDef.ForeignKey == null || OrmLiteConfig.SkipForeignKeys) + continue; + + var refModelDef = GetModel(fieldDef.ForeignKey.ReferenceType); + + var fkName = NamingStrategy.ApplyNameRestrictions(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef)).ToLower(); + sbConstraints.AppendFormat(", \n\n CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2} ({3})", + GetQuotedName(fkName), + GetQuotedColumnName(fieldDef.FieldName), + GetQuotedTableName(refModelDef), + GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)); + + sbConstraints.Append(GetForeignKeyOnDeleteClause(fieldDef.ForeignKey)); + sbConstraints.Append(GetForeignKeyOnUpdateClause(fieldDef.ForeignKey)); + } + + if (sbPk.Length != 0) + sbColumns.AppendFormat(", \n PRIMARY KEY({0})", sbPk); + + var sql = $"RECREATE TABLE {GetQuotedTableName(modelDef)} \n(\n {StringBuilderCache.ReturnAndFree(sbColumns)}{StringBuilderCacheAlt.ReturnAndFree(sbConstraints)} \n); \n"; + + return sql; + } + + public override List ToCreateSequenceStatements(Type tableType) + { + var gens = new List(); + var modelDef = GetModel(tableType); + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (!fieldDef.AutoIncrement || fieldDef.Sequence.IsNullOrEmpty()) continue; + + // https://firebirdsql.org/refdocs/langrefupd21-ddl-sequence.html + var sequence = Sequence(modelDef.ModelName, fieldDef.FieldName, fieldDef.Sequence).ToUpper(); + gens.Add(GetCreateSequenceSql(sequence)); + } + return gens; + } + + protected override void EnsureAutoIncrementSequence(ModelDefinition modelDef, FieldDefinition fieldDef) + { + if (fieldDef.AutoIncrement && !string.IsNullOrEmpty(fieldDef.Sequence)) + { + fieldDef.Sequence = Sequence(modelDef.ModelName, fieldDef.FieldName, fieldDef.Sequence); + } + } + + public override string GetColumnDefinition(FieldDefinition fieldDef) + { + var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) + ?? GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale); + + var sql = StringBuilderCache.Allocate(); + sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldDef.FieldName), fieldDefinition); + + var defaultValue = GetDefaultValue(fieldDef); + if (fieldDef.IsRowVersion) + { + sql.AppendFormat(DefaultValueFormat, 1L); + } + else if (!string.IsNullOrEmpty(defaultValue)) + { + sql.AppendFormat(DefaultValueFormat, defaultValue); + } + + if (fieldDef.AutoIncrement && string.IsNullOrEmpty(fieldDef.Sequence)) + { + sql.Append(AutoIncrementDefinition); + } + else + // Identity columns must accept null to generate a new value. + if (!fieldDef.IsNullable) + { + sql.Append(" NOT NULL"); + } + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } + + return StringBuilderCacheAlt.ReturnAndFree(sql); + } + + public override void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null, + Func shouldInclude=null) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var sbReturningColumns = StringBuilderCacheAlt.Allocate(); + var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T)); + + cmd.Parameters.Clear(); + cmd.CommandTimeout = OrmLiteConfig.CommandTimeout; + + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) + { + if (ShouldReturnOnInsert(modelDef, fieldDef)) + { + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append(GetQuotedColumnName(fieldDef.FieldName)); + } + + if ((ShouldSkipInsert(fieldDef) || (fieldDef.AutoIncrement && string.IsNullOrEmpty(fieldDef.Sequence))) + && shouldInclude?.Invoke(fieldDef) != true) + continue; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + + // in FB4 only use 'next value for' if the fielddef has a sequence explicitly. + if (fieldDef.AutoIncrement && !string.IsNullOrEmpty(fieldDef.Sequence)) + { + EnsureAutoIncrementSequence(modelDef, fieldDef); + sbColumnValues.Append("NEXT VALUE FOR " + fieldDef.Sequence); + } + if (fieldDef.AutoId && usesCompactGuid) + { + sbColumnValues.Append("GEN_UUID()"); + } + else + { + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName),fieldDef.CustomInsert)); + AddParameter(cmd, fieldDef); + } + } + catch (Exception ex) + { + Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex); + throw; + } + } + + var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns); + cmd.CommandText = string.Format("INSERT INTO {0} ({1}) VALUES ({2}) {3}", + GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sbColumnNames), + StringBuilderCacheAlt.ReturnAndFree(sbColumnValues), + strReturning.Length > 0 ? "RETURNING " + strReturning : ""); + } + } +} + diff --git a/src/ServiceStack.OrmLite.Firebird/FirebirdDialect.cs b/src/ServiceStack.OrmLite.Firebird/FirebirdDialect.cs new file mode 100644 index 000000000..119389a95 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/FirebirdDialect.cs @@ -0,0 +1,16 @@ +using ServiceStack.OrmLite.Firebird; + +namespace ServiceStack.OrmLite +{ + public static class FirebirdDialect + { + public static IOrmLiteDialectProvider Provider => FirebirdOrmLiteDialectProvider.Instance; + public static FirebirdOrmLiteDialectProvider Instance => FirebirdOrmLiteDialectProvider.Instance; + } + + public static class Firebird4Dialect + { + public static IOrmLiteDialectProvider Provider => Firebird4OrmLiteDialectProvider.Instance; + public static Firebird4OrmLiteDialectProvider Instance => Firebird4OrmLiteDialectProvider.Instance; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/FirebirdNamingStrategy.cs b/src/ServiceStack.OrmLite.Firebird/FirebirdNamingStrategy.cs new file mode 100644 index 000000000..c1d399f50 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/FirebirdNamingStrategy.cs @@ -0,0 +1,80 @@ +using System; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Firebird +{ + public class FirebirdNamingStrategy : OrmLiteNamingStrategyBase + { + private static int MaxNameLength { get; set; } + + public FirebirdNamingStrategy() : this(31) { } + + public FirebirdNamingStrategy(int maxNameLength) + { + MaxNameLength = maxNameLength; + } + + public override string GetSchemaName(string name) + { + return name != null + ? ApplyNameRestrictions(name).ToUpper() + : null; + } + + public override string GetTableName(string name) + { + return ApplyNameRestrictions(name).ToUpper(); + } + + public override string GetColumnName(string name) + { + return ApplyNameRestrictions(name).ToUpper(); + } + + public override string GetSequenceName(string modelName, string fieldName) + { + var seqName = ApplyNameRestrictions($"GEN_{modelName}_{fieldName}").ToUpper(); + return seqName; + } + + public override string ApplyNameRestrictions(string name) + { + name = name.Replace(" ", "_"); + if (name.Length > MaxNameLength) + name = Squash(name); + + return name.TrimStart('_'); + } + + public override string GetTableName(ModelDefinition modelDef) + { + return GetTableName(modelDef.ModelName); + } + + private static string Squash(string name) + { + name.Print(); + + // First try squashing out the vowels + var removeVowels = new[] {"a", "A", "e", "E", "i", "I", "o", "O", "u", "U", "y", "Y"}; + var squashed = name; + foreach (var removeVowel in removeVowels) + { + squashed = squashed.Replace(removeVowel, ""); + if (squashed.Length <= MaxNameLength) + return squashed; + } + + if (squashed.Length > MaxNameLength) + { // Still too long, squash out every 4th letter, starting at the 3rd + for (var i = 2; i < squashed.Length - 1; i += 4) + squashed = squashed.Substring(0, i) + squashed.Substring(i + 1); + } + if (squashed.Length > MaxNameLength) + { // Still too long, truncate + squashed = squashed.Substring(0, MaxNameLength); + } + return squashed; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Firebird/FirebirdOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Firebird/FirebirdOrmLiteDialectProvider.cs index bcc5833f6..cebc7166d 100644 --- a/src/ServiceStack.OrmLite.Firebird/FirebirdOrmLiteDialectProvider.cs +++ b/src/ServiceStack.OrmLite.Firebird/FirebirdOrmLiteDialectProvider.cs @@ -2,47 +2,70 @@ using System.Collections.Generic; using System.Data; using System.Reflection; -using ServiceStack.Text; using System.Text; +using System.Linq; using FirebirdSql.Data.FirebirdClient; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite; +using ServiceStack.OrmLite.Firebird.Converters; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Firebird { public class FirebirdOrmLiteDialectProvider : OrmLiteDialectProviderBase { + protected virtual string GetCreateSequenceSql(string sequence) => $@" + EXECUTE BLOCK AS BEGIN + if (not exists(select 1 FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME = '{sequence}')) then + begin + execute statement 'CREATE SEQUENCE {sequence};'; + end + END"; + public static List RESERVED = new List(new[] { - "USER","ORDER","PASSWORD", "ACTIVE","LEFT","DOUBLE", "FLOAT", "DECIMAL","STRING", "DATE","DATETIME", "TYPE","TIMESTAMP", - "INDEX","UNIQUE", "PRIMARY", "KEY", "ALTER", "DROP", "CREATE", "DELETE", "VALUES", "FUNCTION" - }); + "USER","ORDER","PASSWORD", "ACTIVE","LEFT","DOUBLE", "FLOAT", "DECIMAL","STRING", "DATE","DATETIME", "TYPE","TIMESTAMP", + "INDEX","UNIQUE", "PRIMARY", "KEY", "ALTER", "DROP", "CREATE", "DELETE", "VALUES", "FUNCTION", "INT", "LONG", "CHAR", "VALUE", "TIME" + }); public static FirebirdOrmLiteDialectProvider Instance = new FirebirdOrmLiteDialectProvider(); internal long LastInsertId { get; set; } - protected bool CompactGuid; - internal const string DefaultGuidDefinition = "VARCHAR(37)"; - internal const string CompactGuidDefinition = "CHAR(16) CHARACTER SET OCTETS"; - - public FirebirdOrmLiteDialectProvider() - : this(false) - { - } + public FirebirdOrmLiteDialectProvider() : this(false) { } public FirebirdOrmLiteDialectProvider(bool compactGuid) { - CompactGuid = compactGuid; - base.BoolColumnDefinition = base.IntColumnDefinition; - base.GuidColumnDefinition = CompactGuid ? CompactGuidDefinition : DefaultGuidDefinition; base.AutoIncrementDefinition = string.Empty; - base.DateTimeColumnDefinition = "TIMESTAMP"; - base.TimeColumnDefinition = "TIME"; - base.RealColumnDefinition = "FLOAT"; - base.DefaultStringLength = 128; - base.MaxStringColumnDefinition = "VARCHAR(32767)"; + DefaultValueFormat = " DEFAULT {0}"; + NamingStrategy = new FirebirdNamingStrategy(); + base.InitColumnTypeMap(); - DefaultValueFormat = " DEFAULT '{0}'"; - NamingStrategy = new UpperCaseNamingStrategy(); + if (compactGuid) + base.RegisterConverter(new FirebirdCompactGuidConverter()); + else + base.RegisterConverter(new FirebirdGuidConverter()); + + base.RegisterConverter(new FirebirdDateTimeConverter()); + base.RegisterConverter(new FirebirdDateTimeOffsetConverter()); + + base.RegisterConverter(new FirebirdBoolConverter()); + base.RegisterConverter(new FirebirdStringConverter()); + base.RegisterConverter(new FirebirdCharArrayConverter()); + base.RegisterConverter(new FirebirdByteArrayConverter()); + + base.RegisterConverter(new FirebirdFloatConverter()); + base.RegisterConverter(new FirebirdDoubleConverter()); + base.RegisterConverter(new FirebirdDecimalConverter()); + + this.Variables = new Dictionary + { + { OrmLiteVariables.SystemUtc, "CURRENT_TIMESTAMP" }, + { OrmLiteVariables.MaxText, "VARCHAR(1000)" }, + { OrmLiteVariables.MaxTextUnicode, "VARCHAR(1000)" }, + { OrmLiteVariables.True, SqlBool(true) }, + { OrmLiteVariables.False, SqlBool(false) }, + }; } public override IDbConnection CreateConnection(string connectionString, Dictionary options) @@ -63,98 +86,24 @@ public override long GetLastInsertId(IDbCommand dbCmd) return LastInsertId; } - public override object ConvertDbValue(object value, Type type) - { - if (value == null || value is DBNull) return null; - - if (type == typeof(bool)) - { - var intVal = int.Parse(value.ToString()); - return intVal != 0; - } - - if (type == typeof(System.Double)) - return double.Parse(value.ToString()); - - if (type == typeof(Guid) && BitConverter.IsLittleEndian) // TODO: check big endian - { - if (CompactGuid) - { - byte[] raw = ((Guid)value).ToByteArray(); - return new Guid(System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt32(raw, 0)), - System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt16(raw, 4)), - System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt16(raw, 6)), - raw[8], raw[9], raw[10], raw[11], raw[12], raw[13], raw[14], raw[15]); - } - return new Guid(value.ToString()); - } - - if (type == typeof(byte[]) && value.GetType() == typeof(byte[])) - return value; - - try - { - return base.ConvertDbValue(value, type); - } - catch (Exception) - { - throw; - } - } - - public override string GetQuotedValue(object value, Type fieldType) + public override string ToRowCountStatement(string innerSql) { - - if (value == null) return "NULL"; - - if (fieldType == typeof(Guid)) - { - if (CompactGuid) - return "X'" + ((Guid)value).ToString("N") + "'"; - else - return string.Format("CAST('{0}' AS {1})", (Guid)value, DefaultGuidDefinition); // TODO : check this !!! - } - if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?)) - { - var dateValue = (DateTime)value; - string iso8601Format = dateValue.ToString("yyyy-MM-dd HH:mm:ss.fff").EndsWith("00:00:00.000") ? - "yyyy-MM-dd" - : "yyyy-MM-dd HH:mm:ss.fff"; - return base.GetQuotedValue(dateValue.ToString(iso8601Format), typeof(string)); - } - if (fieldType == typeof(bool?) || fieldType == typeof(bool)) - { - var boolValue = (bool)value; - return base.GetQuotedValue(boolValue ? "1" : "0", typeof(string)); - } - - if (fieldType == typeof(decimal?) || fieldType == typeof(decimal) || - fieldType == typeof(double?) || fieldType == typeof(double) || - fieldType == typeof(float?) || fieldType == typeof(float)) - { - var s = base.GetQuotedValue(value, fieldType); - if (s.Length > 20) s = s.Substring(0, 20); - return "'" + s + "'"; // when quoted exception is more clear! - } - - return base.GetQuotedValue(value, fieldType); + return "SELECT COUNT(*) FROM ({0})".Fmt(innerSql); } public override string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams) { - var sql = new StringBuilder(); - const string SelectStatement = "SELECT "; var modelDef = GetModel(tableType); - var isFullSelectStatement = - !string.IsNullOrEmpty(sqlFilter) - && sqlFilter.Length > SelectStatement.Length - && sqlFilter.Substring(0, SelectStatement.Length).ToUpper().Equals(SelectStatement); + sqlFilter = (sqlFilter ?? "").TrimStart(); + + if (IsFullSelectStatement(sqlFilter)) + return sqlFilter.SqlFmt(filterParams); - if (isFullSelectStatement) return sqlFilter.SqlFmt(filterParams); + var sql = StringBuilderCache.Allocate() + .AppendFormat("SELECT {0} FROM {1}", + GetColumnNames(modelDef), + GetQuotedTableName(modelDef)); - sql.AppendFormat("SELECT {0} \nFROM {1}", - GetColumnNames(modelDef), - GetQuotedTableName(modelDef)); if (!string.IsNullOrEmpty(sqlFilter)) { sqlFilter = sqlFilter.SqlFmt(filterParams); @@ -165,193 +114,228 @@ public override string ToSelectStatement(Type tableType, string sqlFilter, param } sql.Append(sqlFilter); } - return sql.ToString(); + + return StringBuilderCache.ReturnAndFree(sql); } - public override string ToInsertRowStatement(IDbCommand dbCommand, object objWithProperties, ICollection insertFields = null) + public override string ToInsertRowStatement(IDbCommand cmd, object objWithProperties, ICollection insertFields = null) { - if (insertFields == null) - insertFields = new List(); - - var sbColumnNames = new StringBuilder(); - var sbColumnValues = new StringBuilder(); - + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var sbReturningColumns = StringBuilderCacheAlt.Allocate(); var tableType = objWithProperties.GetType(); var modelDef = GetModel(tableType); - foreach (var fieldDef in modelDef.FieldDefinitions) + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) { + if (ShouldReturnOnInsert(modelDef, fieldDef)) + { + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append(GetQuotedColumnName(fieldDef.FieldName)); + } - if (fieldDef.IsComputed) continue; - if (insertFields.Count > 0 && !insertFields.Contains(fieldDef.Name)) continue; + if (ShouldSkipInsert(fieldDef)) + continue; if ((fieldDef.AutoIncrement || !string.IsNullOrEmpty(fieldDef.Sequence) || fieldDef.Name == OrmLiteConfig.IdField) - && dbCommand != null) + && cmd != null) { + EnsureAutoIncrementSequence(modelDef, fieldDef); - if (fieldDef.AutoIncrement && string.IsNullOrEmpty(fieldDef.Sequence)) - { - fieldDef.Sequence = Sequence( - (modelDef.IsInSchema - ? modelDef.Schema + "_" + NamingStrategy.GetTableName(modelDef.ModelName) - : NamingStrategy.GetTableName(modelDef.ModelName)), - fieldDef.FieldName, fieldDef.Sequence); - } + var result = GetNextValue(cmd, fieldDef.Sequence, fieldDef.GetValue(objWithProperties)); - PropertyInfo pi = tableType.GetProperty(fieldDef.Name, - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); - - var result = GetNextValue(dbCommand, fieldDef.Sequence, pi.GetValue(objWithProperties, new object[] { })); - if (pi.PropertyType == typeof(String)) - pi.SetProperty(objWithProperties, result.ToString()); - else if (pi.PropertyType == typeof(Int16)) - pi.SetProperty(objWithProperties, Convert.ToInt16(result)); - else if (pi.PropertyType == typeof(Int32)) - pi.SetProperty(objWithProperties, Convert.ToInt32(result)); - else if (pi.PropertyType == typeof(Guid)) - pi.SetProperty(objWithProperties, result); - else - pi.SetProperty(objWithProperties, Convert.ToInt64(result)); + var fieldValue = this.ConvertNumber(fieldDef.FieldType, result); + fieldDef.SetValueFn(objWithProperties, fieldValue); } - if (sbColumnNames.Length > 0) sbColumnNames.Append(","); - if (sbColumnValues.Length > 0) sbColumnValues.Append(","); + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); try { - sbColumnNames.Append(string.Format("{0}", GetQuotedColumnName(fieldDef.FieldName))); - if (!string.IsNullOrEmpty(fieldDef.Sequence) && dbCommand == null) - sbColumnValues.Append(string.Format("@{0}", fieldDef.Name)); - else - sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties)); + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); + + AddParameter(cmd, fieldDef); } - catch (Exception) + catch (Exception ex) { + Log.Error("ERROR in ToInsertRowStatement(): " + ex.Message, ex); throw; } } - var sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2});", - GetQuotedTableName(modelDef), sbColumnNames, sbColumnValues); + var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns); + var sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2}) {3};", + GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sbColumnNames), + StringBuilderCacheAlt.ReturnAndFree(sbColumnValues), + strReturning.Length > 0 ? "RETURNING " + strReturning : ""); return sql; } + protected virtual void EnsureAutoIncrementSequence(ModelDefinition modelDef, FieldDefinition fieldDef) + { + if (fieldDef.AutoIncrement && string.IsNullOrEmpty(fieldDef.Sequence)) + { + fieldDef.Sequence = Sequence(modelDef.ModelName, fieldDef.FieldName, fieldDef.Sequence); + } + } + + protected override bool ShouldSkipInsert(FieldDefinition fieldDef) => + fieldDef.ShouldSkipInsert() || (fieldDef.IsComputed && !fieldDef.IsPersisted); + + protected virtual bool ShouldReturnOnInsert(ModelDefinition modelDef, FieldDefinition fieldDef) => + fieldDef.ReturnOnInsert || (fieldDef.IsPrimaryKey && fieldDef.AutoIncrement && HasInsertReturnValues(modelDef)) || fieldDef.AutoId; - public override string ToUpdateRowStatement(object objWithProperties, ICollection updateFields = null) + public override bool HasInsertReturnValues(ModelDefinition modelDef) => + modelDef.FieldDefinitions.Any(x => x.ReturnOnInsert || (x.AutoId && x.FieldType == typeof(Guid))); + + public override void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null, + Func shouldInclude=null) { - if (updateFields == null) - updateFields = new List(); + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var sbReturningColumns = StringBuilderCacheAlt.Allocate(); + var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T)); - var sqlFilter = new StringBuilder(); - var sql = new StringBuilder(); - var tableType = objWithProperties.GetType(); - var modelDef = GetModel(tableType); + cmd.Parameters.Clear(); + cmd.CommandTimeout = OrmLiteConfig.CommandTimeout; - foreach (var fieldDef in modelDef.FieldDefinitions) + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) { - if (fieldDef.IsComputed) continue; + if (ShouldReturnOnInsert(modelDef, fieldDef)) + { + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append(GetQuotedColumnName(fieldDef.FieldName)); + } + + + if ((ShouldSkipInsert(fieldDef) && !fieldDef.AutoIncrement && !fieldDef.AutoId && string.IsNullOrEmpty(fieldDef.Sequence)) + && shouldInclude?.Invoke(fieldDef) != true) + continue; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); try { - if ((fieldDef.IsPrimaryKey || fieldDef.Name == OrmLiteConfig.IdField) - && updateFields.Count == 0) - { - if (sqlFilter.Length > 0) sqlFilter.Append(" AND "); - - sqlFilter.AppendFormat("{0} = {1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties)); + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); - continue; + if (fieldDef.AutoIncrement || !string.IsNullOrEmpty(fieldDef.Sequence)) + { + EnsureAutoIncrementSequence(modelDef, fieldDef); + sbColumnValues.Append("NEXT VALUE FOR " + fieldDef.Sequence); + } + else + { + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName),fieldDef.CustomInsert)); + AddParameter(cmd, fieldDef); } - if (updateFields.Count > 0 && !updateFields.Contains(fieldDef.Name)) continue; - if (sql.Length > 0) sql.Append(","); - sql.AppendFormat("{0} = {1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties)); } - catch (Exception) + catch (Exception ex) { + Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex); throw; } } - var updateSql = string.Format("UPDATE {0} \nSET {1} {2}", - GetQuotedTableName(modelDef), sql, (sqlFilter.Length > 0 ? "\nWHERE " + sqlFilter : "")); - - return updateSql; + var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns); + cmd.CommandText = string.Format("INSERT INTO {0} ({1}) VALUES ({2}) {3}", + GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sbColumnNames), + StringBuilderCacheAlt.ReturnAndFree(sbColumnValues), + strReturning.Length > 0 ? "RETURNING " + strReturning : ""); } - - public override string ToDeleteRowStatement(object objWithProperties) + public override void PrepareUpdateRowStatement(IDbCommand dbCmd, object objWithProperties, ICollection updateFields = null) { + if (updateFields == null) + updateFields = new List(); + + var sql = StringBuilderCache.Allocate(); + var sqlFilter = StringBuilderCacheAlt.Allocate(); var tableType = objWithProperties.GetType(); var modelDef = GetModel(tableType); - var sqlFilter = new StringBuilder(); - foreach (var fieldDef in modelDef.FieldDefinitions) { - try - { - if (fieldDef.IsPrimaryKey || fieldDef.Name == OrmLiteConfig.IdField) - { - if (sqlFilter.Length > 0) sqlFilter.Append(" AND "); - sqlFilter.AppendFormat("{0} = {1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties)); - } - } - catch (Exception) + if ((fieldDef.IsComputed && !fieldDef.IsPersisted) || fieldDef.IgnoreOnUpdate) + continue; + + if ((fieldDef.IsPrimaryKey || fieldDef.Name == OrmLiteConfig.IdField) + && updateFields.Count == 0) { - throw; + if (sqlFilter.Length > 0) + sqlFilter.Append(" AND "); + + sqlFilter + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.AddQueryParam(dbCmd, fieldDef.GetValue(objWithProperties), fieldDef).ParameterName); + + continue; } - } - var deleteSql = string.Format("DELETE FROM {0} WHERE {1}", - GetQuotedTableName(modelDef), sqlFilter); + if (updateFields.Count > 0 && !updateFields.Contains(fieldDef.Name, StringComparer.OrdinalIgnoreCase)) + continue; + + if (sql.Length > 0) + sql.Append(","); + + sql + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.GetUpdateParam(dbCmd, fieldDef.GetValue(objWithProperties), fieldDef)); + } - return deleteSql; + var strFilter = StringBuilderCacheAlt.ReturnAndFree(sqlFilter); + dbCmd.CommandText = string.Format("UPDATE {0} \nSET {1} {2}", + GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sql), + strFilter.Length > 0 ? "\nWHERE " + strFilter : ""); } public override string ToCreateTableStatement(Type tableType) { - var sbColumns = new StringBuilder(); - var sbConstraints = new StringBuilder(); + var sbColumns = StringBuilderCache.Allocate(); + var sbConstraints = StringBuilderCacheAlt.Allocate(); + var sbPk = new StringBuilder(); var modelDef = GetModel(tableType); - foreach (var fieldDef in modelDef.FieldDefinitions) + foreach (var fieldDef in CreateTableFieldsStrategy(modelDef)) { + if (fieldDef.CustomSelect != null) + continue; + if (fieldDef.IsPrimaryKey) - { sbPk.AppendFormat(sbPk.Length != 0 ? ",{0}" : "{0}", GetQuotedColumnName(fieldDef.FieldName)); - } - if (sbColumns.Length != 0) sbColumns.Append(", \n "); - - var columnDefinition = GetColumnDefinition( - fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); + if (sbColumns.Length != 0) + sbColumns.Append(", \n "); + var columnDefinition = GetColumnDefinition(fieldDef); sbColumns.Append(columnDefinition); - if (fieldDef.ForeignKey == null) continue; + if (fieldDef.ForeignKey == null || OrmLiteConfig.SkipForeignKeys) + continue; var refModelDef = GetModel(fieldDef.ForeignKey.ReferenceType); + var fkName = NamingStrategy.ApplyNameRestrictions(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef)).ToLower(); sbConstraints.AppendFormat(", \n\n CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2} ({3})", - GetQuotedName(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef)), + GetQuotedName(fkName), GetQuotedColumnName(fieldDef.FieldName), GetQuotedTableName(refModelDef), GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)); @@ -360,16 +344,12 @@ public override string ToCreateTableStatement(Type tableType) sbConstraints.Append(GetForeignKeyOnUpdateClause(fieldDef.ForeignKey)); } - if (sbPk.Length != 0) sbColumns.AppendFormat(", \n PRIMARY KEY({0})", sbPk); - - var sql = new StringBuilder(string.Format( - "CREATE TABLE {0} \n(\n {1}{2} \n); \n", - GetQuotedTableName(modelDef), - sbColumns, - sbConstraints)); + if (sbPk.Length != 0) + sbColumns.AppendFormat(", \n PRIMARY KEY({0})", sbPk); - return sql.ToString(); + var sql = $"RECREATE TABLE {GetQuotedTableName(modelDef)} \n(\n {StringBuilderCache.ReturnAndFree(sbColumns)}{StringBuilderCacheAlt.ReturnAndFree(sbConstraints)} \n); \n"; + return sql; } public override List ToCreateSequenceStatements(Type tableType) @@ -381,58 +361,44 @@ public override List ToCreateSequenceStatements(Type tableType) { if (fieldDef.AutoIncrement || !fieldDef.Sequence.IsNullOrEmpty()) { - gens.Add("CREATE GENERATOR " - + Sequence((modelDef.IsInSchema - ? modelDef.Schema + "_" + NamingStrategy.GetTableName(modelDef.ModelName) - : NamingStrategy.GetTableName(modelDef.ModelName)), fieldDef.FieldName, fieldDef.Sequence) + ";"); + // https://firebirdsql.org/refdocs/langrefupd21-ddl-sequence.html + var sequence = Sequence(modelDef.ModelName, fieldDef.FieldName, fieldDef.Sequence).ToUpper(); + gens.Add(GetCreateSequenceSql(sequence)); } } return gens; } - public override string GetColumnDefinition(string fieldName, Type fieldType, - bool isPrimaryKey, bool autoIncrement, bool isNullable, bool isRowVersion, - int? fieldLength, int? scale, string defaultValue, string customFieldDefinition) + public override string GetColumnDefinition(FieldDefinition fieldDef) { - string fieldDefinition; + var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) + ?? GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale); - if (customFieldDefinition != null) - { - fieldDefinition = customFieldDefinition; - } - else if (fieldType == typeof(string)) - { - fieldDefinition = string.Format(StringLengthColumnDefinitionFormat, - fieldLength.GetValueOrDefault(DefaultStringLength)); - } - else if (fieldType == typeof(Decimal)) + var sql = StringBuilderCache.Allocate(); + sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldDef.FieldName), fieldDefinition); + + var defaultValue = GetDefaultValue(fieldDef); + if (fieldDef.IsRowVersion) { - fieldDefinition = string.Format("{0} ({1},{2})", DecimalColumnDefinition, - fieldLength.GetValueOrDefault(DefaultDecimalPrecision), - scale.GetValueOrDefault(DefaultDecimalScale)); + sql.AppendFormat(DefaultValueFormat, 1L); } - else - { - fieldDefinition = GetColumnTypeDefinition(fieldType); - } - - var sql = new StringBuilder(); - sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldName), fieldDefinition); - - if (!string.IsNullOrEmpty(defaultValue)) + else if (!string.IsNullOrEmpty(defaultValue)) { sql.AppendFormat(DefaultValueFormat, defaultValue); } - if (!isNullable) + if (!fieldDef.IsNullable) { sql.Append(" NOT NULL"); } + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } - return sql.ToString(); + return StringBuilderCacheAlt.ReturnAndFree(sql); } - public override List ToCreateIndexStatements(Type tableType) { var sqlIndexes = new List(); @@ -442,20 +408,16 @@ public override List ToCreateIndexStatements(Type tableType) { if (!fieldDef.IsIndexed) continue; - var indexName = GetIndexName( - fieldDef.IsUnique, - (modelDef.IsInSchema - ? modelDef.Schema + "_" + modelDef.ModelName - : modelDef.ModelName).SafeVarName(), - fieldDef.FieldName); + var indexName = fieldDef.IndexName ?? GetIndexName( + fieldDef.IsUniqueIndex, modelDef.ModelName, fieldDef.FieldName); sqlIndexes.Add( - ToCreateIndexStatement(fieldDef.IsUnique, indexName, modelDef, fieldDef.FieldName, false)); + ToCreateIndexStatement(fieldDef.IsUniqueIndex, indexName, modelDef, fieldDef.FieldName, false)); } foreach (var compositeIndex in modelDef.CompositeIndexes) { - var indexName = GetCompositeIndexNameWithSchema(compositeIndex, modelDef); + var indexName = GetCompositeIndexName(compositeIndex, modelDef); var indexNames = string.Join(",", compositeIndex.FieldNames.ToArray()); sqlIndexes.Add( @@ -465,16 +427,41 @@ public override List ToCreateIndexStatements(Type tableType) return sqlIndexes; } + protected override string GetIndexName(bool isUnique, string modelName, string fieldName) + { + return NamingStrategy.ApplyNameRestrictions( + $"{(isUnique ? "u" : "")}idx_{modelName}_{fieldName}".ToLower()); + } + protected override string ToCreateIndexStatement(bool isUnique, string indexName, ModelDefinition modelDef, string fieldName, bool isCombined = false, FieldDefinition fieldDef = null) { - return string.Format("CREATE {0} INDEX {1} ON {2} ({3} ); \n", - isUnique ? "UNIQUE" : "", - indexName, - GetQuotedTableName(modelDef), - GetQuotedColumnName(fieldName)); + var fieldNames = fieldName.Split(',') + .Map(x => NamingStrategy.GetColumnName(x.LeftPart(' '))); + + return $"CREATE {(isUnique ? "UNIQUE" : "")} INDEX {indexName} ON {GetQuotedTableName(modelDef)} ({string.Join(",", fieldNames.ToArray())}); \n"; } + public static string RowVersionTriggerFormat = "{0}RowVersionUpdateTrigger"; + public override string ToPostCreateTableStatement(ModelDefinition modelDef) + { + if (modelDef.RowVersion != null) + { + var triggerName = NamingStrategy.ApplyNameRestrictions( + RowVersionTriggerFormat.Fmt(modelDef.ModelName)); + var triggerBody = "new.{0} = old.{0}+1;".Fmt( + modelDef.RowVersion.FieldName.SqlColumn(this)); + + var sql = "CREATE OR ALTER TRIGGER {0} BEFORE UPDATE ON {1} AS BEGIN {2} END;".Fmt( + Quote(triggerName), + GetTableName(modelDef.ModelName, modelDef.Schema), + triggerBody); + + return sql; + } + + return null; + } public override string ToExistStatement(Type fromTableType, object objWithProperties, @@ -483,10 +470,11 @@ public override string ToExistStatement(Type fromTableType, { var fromModelDef = GetModel(fromTableType); - var sql = new StringBuilder(); + var sql = StringBuilderCache.Allocate(); sql.AppendFormat("SELECT 1 \nFROM {0}", GetQuotedTableName(fromModelDef)); - var filter = new StringBuilder(); + var filter = StringBuilderCacheAlt.Allocate(); + var hasFilter = false; if (objWithProperties != null) { @@ -505,21 +493,18 @@ public override string ToExistStatement(Type fromTableType, foreach (var fieldDef in fromModelDef.FieldDefinitions) { - if (fieldDef.IsComputed) continue; - try - { - if (fieldDef.ForeignKey != null - && GetModel(fieldDef.ForeignKey.ReferenceType).ModelName == modelDef.ModelName) - { - if (filter.Length > 0) filter.Append(" AND "); - filter.AppendFormat("{0} = {1}", GetQuotedColumnName(fieldDef.FieldName), - fpk[i].GetQuotedValue(objWithProperties)); - i++; - } - } - catch (Exception) + if (fieldDef.IsComputed) + continue; + + if (fieldDef.ForeignKey != null + && GetModel(fieldDef.ForeignKey.ReferenceType).ModelName == modelDef.ModelName) { - throw; + if (filter.Length > 0) + filter.Append(" AND "); + + filter.AppendFormat("{0} = {1}", GetQuotedColumnName(fieldDef.FieldName), + fpk[i].GetQuotedValue(objWithProperties)); + i++; } } @@ -529,25 +514,22 @@ public override string ToExistStatement(Type fromTableType, var modelDef = GetModel(tableType); foreach (var fieldDef in modelDef.FieldDefinitions) { - if (fieldDef.IsComputed) continue; - try - { - if (fieldDef.IsPrimaryKey) - { - if (filter.Length > 0) filter.Append(" AND "); - filter.AppendFormat("{0} = {1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties)); - } - } - catch (Exception) + if (fieldDef.IsComputed) + continue; + + if (fieldDef.IsPrimaryKey) { - throw; + if (filter.Length > 0) filter.Append(" AND "); + filter.AppendFormat("{0} = {1}", + GetQuotedColumnName(fieldDef.FieldName), + fieldDef.GetQuotedValue(objWithProperties)); } } } - if (filter.Length > 0) sql.AppendFormat("\nWHERE {0} ", filter); + hasFilter = filter.Length > 0; + if (hasFilter) + sql.AppendFormat("\nWHERE {0} ", StringBuilderCacheAlt.ReturnAndFree(filter)); } if (!string.IsNullOrEmpty(sqlFilter)) @@ -556,14 +538,16 @@ public override string ToExistStatement(Type fromTableType, if (!sqlFilter.StartsWith("\nORDER ", StringComparison.OrdinalIgnoreCase) && !sqlFilter.StartsWith("\nROWS ", StringComparison.OrdinalIgnoreCase)) // ROWS [TO ]) { - sql.Append(filter.Length > 0 ? " AND " : "\nWHERE "); + sql.Append(hasFilter ? " AND " : "\nWHERE "); } sql.Append(sqlFilter); } - var sb = new StringBuilder("select 1 from RDB$DATABASE where"); - sb.AppendFormat(" exists ({0})", sql.ToString()); - return sb.ToString(); + var sb = StringBuilderCacheAlt.Allocate() + .Append("select 1 from RDB$DATABASE where") + .AppendFormat(" exists ({0})", StringBuilderCache.ReturnAndFree(sql)); + + return StringBuilderCacheAlt.ReturnAndFree(sb); } public override string ToSelectFromProcedureStatement( @@ -573,7 +557,7 @@ public override string ToSelectFromProcedureStatement( params object[] filterParams) { - var sbColumnValues = new StringBuilder(); + var sbColumnValues = StringBuilderCache.Allocate(); Type fromTableType = fromObjWithProperties.GetType(); @@ -581,25 +565,20 @@ public override string ToSelectFromProcedureStatement( foreach (var fieldDef in modelDef.FieldDefinitions) { - if (sbColumnValues.Length > 0) sbColumnValues.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); - try - { - sbColumnValues.Append(fieldDef.GetQuotedValue(fromObjWithProperties)); - } - catch (Exception) - { - throw; - } + sbColumnValues.Append(fieldDef.GetQuotedValue(fromObjWithProperties)); } - var sql = new StringBuilder(); - sql.AppendFormat("SELECT {0} \nFROM {1} {2}{3}{4} \n", + var columnValues = StringBuilderCache.ReturnAndFree(sbColumnValues); + var sql = StringBuilderCache.Allocate(); + sql.AppendFormat("SELECT {0} \nFROM {1} {2}{3}{4} \n", GetColumnNames(GetModel(outputModelType)), GetQuotedTableName(modelDef), - sbColumnValues.Length > 0 ? "(" : "", - sbColumnValues, - sbColumnValues.Length > 0 ? ")" : ""); + columnValues.Length > 0 ? "(" : "", + columnValues, + columnValues.Length > 0 ? ")" : ""); if (!string.IsNullOrEmpty(sqlFilter)) { @@ -612,46 +591,37 @@ public override string ToSelectFromProcedureStatement( sql.Append(sqlFilter); } - return sql.ToString(); + return StringBuilderCache.ReturnAndFree(sql); } public override string ToExecuteProcedureStatement(object objWithProperties) { - var sbColumnValues = new StringBuilder(); + var sbColumnValues = StringBuilderCache.Allocate(); var tableType = objWithProperties.GetType(); var modelDef = GetModel(tableType); foreach (var fieldDef in modelDef.FieldDefinitions) { - if (sbColumnValues.Length > 0) sbColumnValues.Append(","); - try - { - sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties)); - } - catch (Exception) - { - throw; - } + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties)); } - var sql = string.Format("EXECUTE PROCEDURE {0} {1}{2}{3};", - GetQuotedTableName(modelDef), - sbColumnValues.Length > 0 ? "(" : "", - sbColumnValues, - sbColumnValues.Length > 0 ? ")" : ""); + var columnValues = StringBuilderCache.ReturnAndFree(sbColumnValues); + var sql = + $"EXECUTE PROCEDURE {GetQuotedTableName(modelDef)} {(columnValues.Length > 0 ? "(" : "")}{columnValues}{(columnValues.Length > 0 ? ")" : "")};"; return sql; } private object GetNextValue(IDbCommand dbCmd, string sequence, object value) { - Object retObj; - if (value.ToString() != "0") { - long nv; - if (long.TryParse(value.ToString(), out nv)) + object retObj; + if (long.TryParse(value.ToString(), out var nv)) { LastInsertId = nv; retObj = LastInsertId; @@ -662,10 +632,9 @@ private object GetNextValue(IDbCommand dbCmd, string sequence, object value) retObj = value; } return retObj; - } - dbCmd.CommandText = string.Format("select next value for {0} from RDB$DATABASE", Quote(sequence)); + dbCmd.CommandText = $"select next value for {Quote(sequence)} from RDB$DATABASE"; long result = (long)dbCmd.ExecuteScalar(); LastInsertId = result; return result; @@ -676,41 +645,43 @@ private object GetNextValue(IDbCommand dbCmd, string sequence, object value) private string Quote(string name) { return QuoteNames - ? string.Format("\"{0}\"", name) + ? $"\"{name}\"" : RESERVED.Contains(name.ToUpper()) - ? string.Format("\"{0}\"", name) + ? $"\"{name}\"" : name; } - public override string GetColumnNames(ModelDefinition modelDef) + public override string EscapeWildcards(string value) { - if (QuoteNames) return modelDef.GetColumnNames(this); - var sqlColumns = new StringBuilder(); - modelDef.FieldDefinitions.ForEach(x => - sqlColumns.AppendFormat("{0} {1}", - sqlColumns.Length > 0 ? "," : "", - GetQuotedColumnName(x.FieldName))); - - return sqlColumns.ToString(); + return value?.Replace("^", @"^^") + .Replace("_", @"^_") + .Replace("%", @"^%"); } - public override string GetQuotedName(string fieldName) + public override string GetQuotedName(string name) { - return Quote(fieldName); + return Quote(name); } - public virtual string GetTableName(string table, string schema = null) + public override string GetTableName(ModelDefinition modelDef) { - return schema != null - ? string.Format("{0}_{1}", - NamingStrategy.GetSchemaName(schema), - NamingStrategy.GetTableName(table)) - : NamingStrategy.GetTableName(table); + return GetTableName(modelDef.ModelName, modelDef.Schema); } - public virtual string GetTableName(ModelDefinition modelDef) + public override string GetTableName(string table, string schema = null) => GetTableName(table, schema, useStrategy: true); + + public override string GetTableName(string table, string schema, bool useStrategy) { - return GetTableName(modelDef.ModelName, modelDef.Schema); + if (useStrategy) + { + return schema != null + ? $"{NamingStrategy.GetSchemaName(schema)}_{NamingStrategy.GetTableName(table)}" + : NamingStrategy.GetTableName(table); + } + + return schema != null + ? $"{schema}_{table}" + : table; } public override string GetQuotedTableName(ModelDefinition modelDef) @@ -726,10 +697,10 @@ public override string GetQuotedColumnName(string fieldName) return Quote(NamingStrategy.GetColumnName(fieldName)); } - private string Sequence(string modelName, string fieldName, string sequence) + protected string Sequence(string modelName, string fieldName, string sequence) { return sequence.IsNullOrEmpty() - ? Quote(modelName + "_" + fieldName + "_GEN") + ? Quote(NamingStrategy.GetSequenceName(modelName, fieldName)) : Quote(sequence); } @@ -738,24 +709,53 @@ public override SqlExpression SqlExpression() return new FirebirdSqlExpression(this); } + public override IDbDataParameter CreateParam() + { + return new FbParameter(); + } + + public override bool DoesSchemaExist(IDbCommand dbCmd, string schemaName) + { + dbCmd.CommandText = $"SELECT 1 FROM sys.schemas WHERE name = {schemaName.Quoted()}"; + var query = dbCmd.ExecuteNonQuery(); + return query == 1; + } + + public override string ToCreateSchemaStatement(string schemaName) + { + var sql = $"CREATE SCHEMA {GetSchemaName(schemaName)}"; + return sql; + } + public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) { + tableName = GetTableName(tableName, schema); + +// if (!QuoteNames & !RESERVED.Contains(tableName.ToUpper())) +// tableName = tableName.ToUpper(); + + var sql = $"SELECT COUNT(*) FROM rdb$relations WHERE rdb$system_flag = 0 AND rdb$view_blr IS NULL AND rdb$relation_name = '{tableName}'"; + + var result = dbCmd.ExecLongScalar(sql); + return result == 1; + } + + public override bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null) + { + var table = GetTableName(tableName, schema); + if (!QuoteNames & !RESERVED.Contains(tableName.ToUpper())) - { - tableName = tableName.ToUpper(); - } + table = table.ToUpper(); - var sql = "SELECT count(*) FROM rdb$relations " + - "WHERE rdb$system_flag = 0 AND rdb$view_blr IS NULL AND rdb$relation_name ={0}" - .SqlFmt(tableName); + var sql = "SELECT COUNT(*) FROM RDB$RELATION_FIELDS " + + " WHERE RDB$RELATION_FIELDS.RDB$RELATION_NAME = UPPER(@table)" + + " AND RDB$RELATION_FIELDS.RDB$FIELD_NAME = UPPER(@columnName)"; - dbCmd.CommandText = sql; - var result = dbCmd.LongScalar(); + var result = db.SqlScalar(sql, new { table, columnName }); return result > 0; } - public override string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignKey) { return (!string.IsNullOrEmpty(foreignKey.OnDelete) && foreignKey.OnDelete.ToUpper() != "RESTRICT") ? " ON DELETE " + foreignKey.OnDelete : ""; @@ -769,92 +769,68 @@ public override string GetForeignKeyOnUpdateClause(ForeignKeyConstraint foreignK #region DDL public override string ToAddColumnStatement(Type modelType, FieldDefinition fieldDef) { - - var column = GetColumnDefinition(fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - return string.Format("ALTER TABLE {0} ADD {1} ;", - GetQuotedTableName(GetModel(modelType)), - column); + var column = GetColumnDefinition(fieldDef); + return $"ALTER TABLE {GetQuotedTableName(GetModel(modelType))} ADD {column} ;"; } public override string ToAlterColumnStatement(Type modelType, FieldDefinition fieldDef) { - - var column = GetColumnDefinition(fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - return string.Format("ALTER TABLE {0} ALTER {1} ;", - GetQuotedTableName(GetModel(modelType)), - column); + var column = GetColumnDefinition(fieldDef); + return $"ALTER TABLE {GetQuotedTableName(GetModel(modelType))} ALTER {column} ;"; } - public override string ToChangeColumnNameStatement(Type modelType, - FieldDefinition fieldDef, - string oldColumnName) + public override string ToChangeColumnNameStatement(Type modelType, FieldDefinition fieldDef, string oldColumnName) { - return string.Format("ALTER TABLE {0} ALTER {1} TO {2} ;", - GetQuotedTableName(GetModel(modelType)), - GetQuotedColumnName(oldColumnName), - GetQuotedColumnName(fieldDef.FieldName)); + return string.Format("ALTER TABLE {0} ALTER {1} TO {2};", + GetQuotedTableName(GetModel(modelType)), + GetQuotedColumnName(oldColumnName), + GetQuotedColumnName(fieldDef.FieldName)); } #endregion DDL - public override string ToSelectStatement(ModelDefinition modelDef, + public override string ToSelectStatement(QueryType queryType, ModelDefinition modelDef, string selectExpression, string bodyExpression, string orderByExpression = null, int? offset = null, - int? rows = null) + int? rows = null, + ISet tags=null) { + var sb = StringBuilderCache.Allocate(); + ApplyTags(sb,tags); - var sb = new StringBuilder(selectExpression); - sb.Append(bodyExpression); - if (orderByExpression != null) - { + sb.Append(selectExpression) + .Append(bodyExpression); + + if (!string.IsNullOrEmpty(orderByExpression)) sb.Append(orderByExpression); - } - if (offset != null) + if ((queryType == QueryType.Select || (rows == 1 && offset is null or 0)) && (offset != null || rows != null)) { - int fromRow = offset.Value + 1; - if (fromRow <= 0) - throw new ArgumentException( - string.Format("Skip value:'{0}' must be>=0", offset.Value)); - string toRow; - if (rows.HasValue) - { - if (rows.Value < 0) - { - throw new ArgumentException(string.Format("Rows value:'{0}' must be>=0", rows.Value)); - } - toRow = string.Format("TO {0}", fromRow + rows.Value - 1); - } - else - { - toRow = string.Empty; - } - sb.Append(string.Format("\nROWS {0} {1}", fromRow, toRow)); + var sqlPrefix = "SELECT"; + if (rows != null) + sqlPrefix += " FIRST " + rows; + if (offset != null) + sqlPrefix += " SKIP " + offset; + + var sql = StringBuilderCache.ReturnAndFree(sb); + return sqlPrefix + sql.Substring("SELECT".Length); } - return sb.ToString(); + return StringBuilderCache.ReturnAndFree(sb); } - } + public override void DropColumn(IDbConnection db, Type modelType, string columnName) + { + var provider = db.GetDialectProvider(); + var command = + $"ALTER TABLE {provider.GetQuotedTableName(modelType.GetModelMetadata().ModelName)} DROP {provider.GetQuotedColumnName(columnName)};"; + + db.ExecuteSql(command); + } + + public override string SqlConcat(IEnumerable args) => string.Join(" || ", args); + } } /* @@ -862,4 +838,3 @@ public override string ToSelectStatement(ModelDefinition modelDef, DEFINE GENERATOR failed attempt to store duplicate value (visible to active transactions) in unique index "RDB$INDEX_11" */ - diff --git a/src/ServiceStack.OrmLite.Firebird/FirebirdSqlExpression.cs b/src/ServiceStack.OrmLite.Firebird/FirebirdSqlExpression.cs index 268623491..617f1edfa 100644 --- a/src/ServiceStack.OrmLite.Firebird/FirebirdSqlExpression.cs +++ b/src/ServiceStack.OrmLite.Firebird/FirebirdSqlExpression.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -6,156 +5,31 @@ namespace ServiceStack.OrmLite.Firebird { public class FirebirdSqlExpression : SqlExpression { - private readonly string _trueExpression; - private readonly string _falseExpression; - public FirebirdSqlExpression(IOrmLiteDialectProvider dialectProvider) - : base(dialectProvider) - { - _trueExpression = string.Format("({0}={1})", GetQuotedTrueValue(), GetQuotedTrueValue()); - _falseExpression = string.Format("({0}={1})", GetQuotedTrueValue(), GetQuotedFalseValue()); - } - - protected override object VisitBinary(BinaryExpression b) - { - object left, right; - var operand = BindOperant(b.NodeType); //sep= " " ?? - if (operand == "AND" || operand == "OR") - { - var m = b.Left as MemberExpression; - if (m != null && m.Expression != null - && m.Expression.NodeType == ExpressionType.Parameter) - left = new PartialSqlString(string.Format("{0}={1}", VisitMemberAccess(m), GetQuotedTrueValue())); - else - left = Visit(b.Left); - - m = b.Right as MemberExpression; - if (m != null && m.Expression != null - && m.Expression.NodeType == ExpressionType.Parameter) - right = new PartialSqlString(string.Format("{0}={1}", VisitMemberAccess(m), GetQuotedTrueValue())); - else - right = Visit(b.Right); - - if (left as PartialSqlString == null && right as PartialSqlString == null) - { - var result = Expression.Lambda(b).Compile().DynamicInvoke(); - return new PartialSqlString(base.DialectProvider.GetQuotedValue(result, result.GetType())); - } - - if (left as PartialSqlString == null) - left = ((bool)left) ? GetTrueExpression() : GetFalseExpression(); - if (right as PartialSqlString == null) - right = ((bool)right) ? GetTrueExpression() : GetFalseExpression(); - } - else - { - left = Visit(b.Left); - right = Visit(b.Right); - - if (left as EnumMemberAccess != null) - { - var enumType = ((EnumMemberAccess)left).EnumType; - - //enum value was returned by Visit(b.Right) - long numvericVal; - if (Int64.TryParse(right.ToString(), out numvericVal)) - right = base.DialectProvider.GetQuotedValue(Enum.ToObject(enumType, numvericVal).ToString(), - typeof(string)); - else - right = base.DialectProvider.GetQuotedValue(right, right.GetType()); - } - else if (right as EnumMemberAccess != null) - { - var enumType = ((EnumMemberAccess)right).EnumType; - - //enum value was returned by Visit(b.Left) - long numvericVal; - if (Int64.TryParse(left.ToString(), out numvericVal)) - left = base.DialectProvider.GetQuotedValue(Enum.ToObject(enumType, numvericVal).ToString(), - typeof(string)); - else - left = base.DialectProvider.GetQuotedValue(left, left.GetType()); - } - else if (left as PartialSqlString == null && right as PartialSqlString == null) - { - var result = Expression.Lambda(b).Compile().DynamicInvoke(); - return result; - } - else if (left as PartialSqlString == null) - left = base.DialectProvider.GetQuotedValue(left, left != null ? left.GetType() : null); - else if (right as PartialSqlString == null) - right = base.DialectProvider.GetQuotedValue(right, right != null ? right.GetType() : null); - - } - - if (operand == "=" && right.ToString() == "null") operand = "is"; - else if (operand == "<>" && right.ToString() == "null") operand = "is not"; - else if (operand == "=" || operand == "<>") - { - if (IsTrueExpression(right)) right = GetQuotedTrueValue(); - else if (IsFalseExpression(right)) right = GetQuotedFalseValue(); - - if (IsTrueExpression(left)) left = GetQuotedTrueValue(); - else if (IsFalseExpression(left)) left = GetQuotedFalseValue(); - - } - - switch (operand) - { - case "MOD": - case "COALESCE": - return new PartialSqlString(string.Format("{0}({1},{2})", operand, left, right)); - default: - return new PartialSqlString("(" + left + Sep + operand + Sep + right + ")"); - } - } - - protected override object VisitConstant(ConstantExpression c) - { - if (c.Value == null) - return new PartialSqlString("null"); - - if (c.Value is bool) - { - object o = base.DialectProvider.GetQuotedValue(c.Value, c.Value.GetType()); - return new PartialSqlString(string.Format("({0}={1})", GetQuotedTrueValue(), o)); - } - - return c.Value; - } + : base(dialectProvider) {} protected override object VisitColumnAccessMethod(MethodCallExpression m) { - List args = this.VisitExpressionList(m.Arguments); + var args = this.VisitExpressionList(m.Arguments); var quotedColName = Visit(m.Object); var statement = ""; switch (m.Method.Name) { case "Trim": - statement = string.Format("trim({0})", quotedColName); + statement = $"trim({quotedColName})"; break; case "LTrim": - statement = string.Format("trim(leading from {0})", quotedColName); + statement = $"trim(leading from {quotedColName})"; break; case "RTrim": - statement = string.Format("trim(trailing from {0})", quotedColName); + statement = $"trim(trailing from {quotedColName})"; break; default: return base.VisitColumnAccessMethod(m); } return new PartialSqlString(statement); } - - private bool IsTrueExpression(object exp) - { - return (exp.ToString() == _trueExpression); - } - - private bool IsFalseExpression(object exp) - { - return (exp.ToString() == _falseExpression); - } } } diff --git a/src/ServiceStack.OrmLite.Firebird/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Firebird/Properties/AssemblyInfo.cs index 5953cde43..22ae012d6 100644 --- a/src/ServiceStack.OrmLite.Firebird/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite.Firebird/Properties/AssemblyInfo.cs @@ -1,22 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("ServiceStack.OrmLite.Firebird")] -[assembly: AssemblyDescription("POCO ORM for FirebirdSql")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("aicl")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - -[assembly: AssemblyVersion("4.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.Firebird/ServiceStack.OrmLite.Firebird.Core.csproj b/src/ServiceStack.OrmLite.Firebird/ServiceStack.OrmLite.Firebird.Core.csproj new file mode 100644 index 000000000..712bfeab4 --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/ServiceStack.OrmLite.Firebird.Core.csproj @@ -0,0 +1,22 @@ + + + + ServiceStack.OrmLite.Firebird.Core + ServiceStack.OrmLite.Firebird + ServiceStack.OrmLite.Firebird + netstandard2.0;net6.0 + ServiceStack.OrmLite.Firebird .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite.Firebird + + Firebird;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.Firebird/ServiceStack.OrmLite.Firebird.csproj b/src/ServiceStack.OrmLite.Firebird/ServiceStack.OrmLite.Firebird.csproj index 3f5ee90f4..841862f07 100644 --- a/src/ServiceStack.OrmLite.Firebird/ServiceStack.OrmLite.Firebird.csproj +++ b/src/ServiceStack.OrmLite.Firebird/ServiceStack.OrmLite.Firebird.csproj @@ -1,84 +1,22 @@ - - + + - Debug - AnyCPU - 10.0.0 - 2.0 - {317B64BA-D7A6-4A15-8719-821B38147C63} - Library - ServiceStack.OrmLite.Firebird + ServiceStack.OrmLite.Firebird ServiceStack.OrmLite.Firebird - v4.0 - + net472;netstandard2.0;net6.0 + OrmLite.Firebird - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for Firebird. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Firebird. + + Firebird;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - none - false - bin\Release - prompt - 4 - false - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\ServiceStack.Text.dll - - - - - - ..\..\lib\FirebirdSql.Data.FirebirdClient.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - - - - - - - - - - - - - - - - - - - - - - + - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - + + + - \ No newline at end of file + + diff --git a/src/ServiceStack.OrmLite.Firebird/app.config b/src/ServiceStack.OrmLite.Firebird/app.config new file mode 100644 index 000000000..36b9bd30a --- /dev/null +++ b/src/ServiceStack.OrmLite.Firebird/app.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.MySql.Tests/CustomSqlTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/CustomSqlTests.cs deleted file mode 100644 index 4c70ff76a..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/CustomSqlTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Data; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - public class LetterFrequency - { - [AutoIncrement] - public int Id { get; set; } - - public string Letter { get; set; } - } - - [TestFixture] - public class CustomSqlTests : OrmLiteTestBase - { - string spSql = @"DROP PROCEDURE IF EXISTS spSearchLetters; - CREATE PROCEDURE spSearchLetters (IN pLetter varchar(10), OUT pTotal int) - BEGIN - SELECT COUNT(*) FROM LetterFrequency WHERE Letter = pLetter INTO pTotal; - SELECT * FROM LetterFrequency WHERE Letter = pLetter; - END"; - - [Test] - public void Can_execute_stored_procedure_using_SqlList_with_out_params() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); - db.InsertAll(rows); - - db.ExecuteSql(spSql); - - IDbDataParameter pTotal = null; - var results = db.SqlList("spSearchLetters", - cmd => - { - cmd.CommandType = CommandType.StoredProcedure; - cmd.AddParam("pLetter", "C"); - pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); - }); - - Assert.That(results.Count, Is.EqualTo(3)); - Assert.That(pTotal.Value, Is.EqualTo(3)); - } - } - - [Test] - public void Can_execute_stored_procedure_using_SqlProc_with_out_params() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); - db.InsertAll(rows); - - db.ExecuteSql(spSql); - - var cmd = db.SqlProc("spSearchLetters", new { pLetter = "C" }); - - Assert.That(((OrmLiteCommand)cmd).IsDisposed, Is.False); - - var pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); - var results = cmd.ConvertToList(); - - Assert.That(results.Count, Is.EqualTo(3)); - Assert.That(pTotal.Value, Is.EqualTo(3)); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/DateTimeColumnTest.cs b/src/ServiceStack.OrmLite.MySql.Tests/DateTimeColumnTest.cs deleted file mode 100644 index 5fbdc2df6..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/DateTimeColumnTest.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - [TestFixture] - public class DateTimeColumnTest - : OrmLiteTestBase - { - [Test] - public void Can_create_table_containing_DateTime_column() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_store_DateTime_Value() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var obj = new Analyze { - Id = 1, - Date = DateTime.Now, - Url = "http://www.google.com" - }; - - db.Save(obj); - } - } - - [Test] - public void Can_store_and_retrieve_DateTime_Value() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var obj = new Analyze { - Id = 1, - Date = DateTime.Now, - Url = "http://www.google.com" - }; - - db.Save(obj); - - var id = (int)db.LastInsertId(); - var target = db.SingleById(id); - - Assert.IsNotNull(target); - Assert.AreEqual(id, target.Id); - Assert.AreEqual(obj.Date.ToString("yyyy-MM-dd HH:mm:ss"), target.Date.ToString("yyyy-MM-dd HH:mm:ss")); - Assert.AreEqual(obj.Url, target.Url); - } - } - - /// - /// Provided by RyogoNA in issue #38 https://github.com/ServiceStack/ServiceStack.OrmLite/issues/38#issuecomment-4625178 - /// - [Alias("Analyzes")] - public class Analyze : IHasId - { - [AutoIncrement] - [PrimaryKey] - public int Id - { - get; - set; - } - [Alias("AnalyzeDate")] - public DateTime Date - { - get; - set; - } - public string Url - { - get; - set; - } - } - } -} diff --git a/src/ServiceStack.OrmLite.MySql.Tests/EnumTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/EnumTests.cs deleted file mode 100644 index f0899a0e4..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/EnumTests.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - public class EnumTests : OrmLiteTestBase - { - [Test] - public void CanCreateTable() - { - OpenDbConnection().CreateTable(true); - } - - [Test] - public void CanStoreEnumValue() - { - using(var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum {Id = 1, EnumValue = SomeEnum.Value1}); - } - } - - [Test] - public void CanGetEnumValue() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; - con.Save(obj); - var target = con.SingleById(obj.Id); - Assert.AreEqual(obj.Id, target.Id); - Assert.AreEqual(obj.EnumValue, target.EnumValue); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_expression() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1}); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Select(q => q.EnumValue == SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_string() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.SelectFmt("EnumValue = {0}", SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Test] - public void CanQueryByEnumValue_using_where_with_AnonType() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Where(new { EnumValue = SomeEnum.Value1 }); - - Assert.AreEqual(2, target.Count()); - } - } - } - - public enum SomeEnum : long - { - Value1 = 2147483648, - Value2, - Value3 - } - - public class TypeWithEnum - { - public int Id { get; set; } - public SomeEnum EnumValue { get; set; } - } -} diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/AuthorUseCase.cs b/src/ServiceStack.OrmLite.MySql.Tests/Expressions/AuthorUseCase.cs deleted file mode 100644 index aac0509a5..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/AuthorUseCase.cs +++ /dev/null @@ -1,373 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.MySql.Tests.Expressions -{ - public class AuthorUseCase : OrmLiteTestBase - { - private List authors; - - public AuthorUseCase() - { - authors = new List(); - authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); - authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); - authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); - authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); - authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); - authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); - authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); - authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); - authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); - authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); - authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); - authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico", LastActivity = DateTime.Today }); - } - - [SetUp] - public void Setup() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.SaveAll(authors); - } - } - - [Test] - public void AuthorUsesCases() - { - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (var db = OpenDbConnection()) - { - int year = DateTime.Today.AddYears(-20).Year; - var lastDay = new DateTime(year, 12, 31); - int expected = 5; - - ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - List result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - Assert.AreEqual(expected, result.Count); - Author a = new Author() { Birthday = lastDay }; - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); - Assert.AreEqual(expected, result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected = 6; - //Sql.In can take params object[] - var city = "Berlin"; - ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); - Assert.AreEqual(expected, result.Count); - - // select authors from Bogota and Cartagena : 7 - expected = 7; - //... or Sql.In can take List - city = "Bogota"; - List cities = new List(); - cities.Add(city); - cities.Add("Cartagena"); - ev.Where().Where(rn => Sql.In(rn.City, cities)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name starts with A - expected = 3; - ev.Where().Where(rn => rn.Name.StartsWith("A")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.StartsWith("A")); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected = 3; - var name = "GARZON"; - ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected = 3; - ev.Where().Where(rn => rn.Name.EndsWith("garzon")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name contains Benedict - expected = 2; - name = "Benedict"; - ev.Where().Where(rn => rn.Name.Contains(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Assert.AreEqual(expected, result.Count); - a.Name = name; - result = db.Select(rn => rn.Name.Contains(a.Name)); - Assert.AreEqual(expected, result.Count); - - - // select authors with Earnings <= 50 - expected = 3; - var earnings = 50; - ev.Where().Where(rn => rn.Earnings <= earnings); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Earnings <= 50); - Assert.AreEqual(expected, result.Count); - - // select authors with Rate = 10 and city=Mexio - expected = 1; - city = "Mexico"; - ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Assert.AreEqual(expected, result.Count); - - a.City = city; - result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); - Assert.AreEqual(expected, result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected = 2; - var rate = 0; - ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); - Assert.AreEqual(expected, rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected = 4; - ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); - ev.Where().Where(rn => !rn.Active); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - //update comment for City == null - expected = 2; - ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); - Assert.AreEqual(expected, rows); - - // delete where City is null - expected = 2; - rows = db.Delete(ev); - Assert.AreEqual(expected, rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected = 14; - ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - var author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel", author.Name); - - // select only first 5 rows .... - expected = 5; - ev.Limit(5); // note: order is the same as in the last sentence - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - //paging : - ev.Limit(0, 4);// first page, page size=4; - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Limit(4, 4);// second page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Jorge Garzon".ToUpper(), author.Name); - - ev.Limit(8, 4);// third page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Rodger Contreras".ToUpper(), author.Name); - - // select distinct.. - ev.Limit().OrderBy(); // clear limit, clear order for postres - ev.SelectDistinct(r => r.City); - expected = 6; - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); - result = db.Select(ev); - var expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - var r1 = db.Single(ev); - Assert.AreEqual(expectedResult, r1.Birthday); - - var r2 = db.Scalar(e => Sql.Max(e.Birthday)); - Assert.AreEqual(expectedResult, r2); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - var expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - r1 = db.Single(ev); - Assert.AreEqual(expectedStringResult, r1.City); - - var expectedDecimal = authors.Max(e => e.Earnings); - Decimal? r3 = db.Scalar(e => Sql.Max(e.Earnings)); - Assert.AreEqual(expectedDecimal, r3.Value); - - var expectedString = authors.Max(e => e.Name); - string r4 = db.Scalar(e => Sql.Max(e.Name)); - Assert.AreEqual(expectedString, r4); - - var expectedDate = authors.Max(e => e.LastActivity); - DateTime? r5 = db.Scalar(e => Sql.Max(e.LastActivity)); - Assert.AreEqual(expectedDate, r5); - - var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); - DateTime? r51 = db.Scalar( - e => Sql.Max(e.LastActivity), - e => e.City == "Bogota"); - Assert.AreEqual(expectedDate51, r51); - - try - { - var expectedBool = authors.Max(e => e.Active); - bool r6 = db.Scalar(e => Sql.Max(e.Active)); - Assert.AreEqual(expectedBool, r6); - } - catch (Exception e) - { - //???? - //if (dialect.Name == "PostgreSQL") - // Console.WriteLine("OK PostgreSQL: " + e.Message); - //else - // Console.WriteLine("************** FAILED *************** " + e.Message); - } - - - - // Tests for predicate overloads that make use of the expression visitor - author = db.Single(q => q.Name == "Jorge Garzon"); - - try - { - author = db.Single(q => q.Name == "Does not exist"); - Assert.Fail(); - } - catch - { - //"Expected exception thrown, OK? True" - } - - author = db.Single(q => q.Name == "Does not exist"); - Assert.IsNull(author); - - author = db.Single(q => q.City == "Bogota"); - Assert.AreEqual("Angel Colmenares", author.Name); - - a.City = "Bogota"; - author = db.Single(q => q.City == a.City); - Assert.AreEqual("Angel Colmenares", author.Name); - - // count test - - var expectedCount = authors.Count(); - long r7 = db.Scalar(e => Sql.Count(e.Id)); - Assert.AreEqual(expectedCount, r7); - - expectedCount = authors.Count(e => e.City == "Bogota"); - r7 = db.Scalar( - e => Sql.Count(e.Id), - e => e.City == "Bogota"); - Assert.AreEqual(expectedCount, r7); - - ev.Update();// all fields will be updated - // select and update - expected = 1; - var rr = db.Single(rn => rn.Name == "Luis garzon"); - rr.City = "Madrid"; - rr.Comments = "Updated"; - ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated - rows = db.UpdateOnly(rr, ev); // == dbCmd.Update(rr) but it returns void - Assert.AreEqual(expected, rows); - - expected = 0; - ev.Where().Where(r => r.City == "Ciudad Gotica"); - rows = db.UpdateOnly(rr, ev); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.City == "Madrid").Count; - author = new Author() { Active = false }; - rows = db.UpdateOnly(author, x => x.Active, x => x.City == "Madrid"); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.Active == false).Count; - rows = db.Delete(x => x.Active == false); - Assert.AreEqual(expected, rows); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.MySql.Tests/ForeignKeyAttributeTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/ForeignKeyAttributeTests.cs deleted file mode 100644 index d674aca2a..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/ForeignKeyAttributeTests.cs +++ /dev/null @@ -1,180 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - [TestFixture] - public class ForeignKeyAttributeTests : OrmLiteTestBase - { - [TestFixtureSetUp] - public void Setup() - { - using (var db = OpenDbConnection()) - { - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - - db.CreateTable(); - } - } - - [Test] - public void CanCreateSimpleForeignKey() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascade() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void CascadesOnDelete() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Save(new ReferencedType { Id = 1 }); - db.Save(new TypeWithOnDeleteCascade { RefId = 1 }); - - Assert.AreEqual(1, db.Select().Count); - Assert.AreEqual(1, db.Select().Count); - - db.Delete(r => r.Id == 1); - - Assert.AreEqual(0, db.Select().Count); - Assert.AreEqual(0, db.Select().Count); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteNoAction() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteRestrict() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [NUnit.Framework.Ignore("Not supported in MySQL")] - [Test] - public void CanCreateForeignWithOnDeleteSetDefault() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteSetNull() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - } - - public class ReferencedType - { - public int Id { get; set; } - } - - - public class TypeWithSimpleForeignKey - { - [AutoIncrement] - public int Id { get; set; } - [References(typeof(ReferencedType))] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteAndUpdateCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteNoAction - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteRestrict - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteSetDefault - { - [AutoIncrement] - public int Id { get; set; } - - [Default(typeof(int), "17")] - [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT")] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteSetNull - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL")] - public int? RefId { get; set; } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/LocalizationTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/LocalizationTests.cs deleted file mode 100644 index 73719f767..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/LocalizationTests.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Globalization; -using System.Threading; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - [TestFixture] - public class LocalizationTests - : OrmLiteTestBase - { - private readonly CultureInfo CurrentCulture = Thread.CurrentThread.CurrentCulture; - private readonly CultureInfo CurrentUICulture = Thread.CurrentThread.CurrentUICulture; - - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - Thread.CurrentThread.CurrentCulture = new CultureInfo("vi-VN"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("vi-VN"); - - OrmLiteConfig.DialectProvider = MySqlDialectProvider.Instance; - } - - [TestFixtureTearDown] - public void TestFixtureTearDown() - { - Thread.CurrentThread.CurrentCulture = CurrentCulture; - Thread.CurrentThread.CurrentUICulture = CurrentUICulture; - } - - public class Point - { - [AutoIncrement] - public int Id { get; set; } - public short Width { get; set; } - public float Height { get; set; } - public double Top { get; set; } - public decimal Left { get; set; } - } - - [Test] - public void Can_query_using_float_in_alernate_culuture() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Insert(new Point { Width = 4, Height = 1.123f, Top = 3.456d, Left = 2.345m}); - - var points = db.SelectFmt("Height={0}", 1.123f); - - Console.WriteLine(points.Dump()); - - Assert.That(points[0].Width, Is.EqualTo(4)); - Assert.That(points[0].Height, Is.EqualTo(1.123f)); - Assert.That(points[0].Top, Is.EqualTo(3.456d)); - Assert.That(points[0].Left, Is.EqualTo(2.345m)); - } - } - - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableTests.cs deleted file mode 100644 index 5860130a6..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableTests.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - [TestFixture] - public class OrmLiteCreateTableTests - : OrmLiteTestBase - { - - [Test] - public void Can_create_ModelWithIdOnly_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_create_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_create_ModelWithLongIdAndStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_create_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_preserve_ModelWithIdOnly_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Insert(new ModelWithIdOnly(1)); - db.Insert(new ModelWithIdOnly(2)); - - db.CreateTable(false); - - var rows = db.Select(); - - Assert.That(rows, Has.Count.EqualTo(2)); - } - } - - [Test] - public void Can_preserve_ModelWithIdAndName_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Insert(new ModelWithIdAndName(1)); - db.Insert(new ModelWithIdAndName(2)); - - db.CreateTable(false); - - var rows = db.Select(); - - Assert.That(rows, Has.Count.EqualTo(2)); - } - } - - [Test] - public void Can_overwrite_ModelWithIdOnly_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Insert(new ModelWithIdOnly(1)); - db.Insert(new ModelWithIdOnly(2)); - - db.CreateTable(true); - - var rows = db.Select(); - - Assert.That(rows, Has.Count.EqualTo(0)); - } - } - - [Test] - public void Can_create_multiple_tables() - { - using (var db = OpenDbConnection()) - { - db.CreateTables(true, typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); - - db.Insert(new ModelWithIdOnly(1)); - db.Insert(new ModelWithIdOnly(2)); - - db.Insert(new ModelWithIdAndName(1)); - db.Insert(new ModelWithIdAndName(2)); - - var rows1 = db.Select(); - var rows2 = db.Select(); - - Assert.That(rows1, Has.Count.EqualTo(2)); - Assert.That(rows2, Has.Count.EqualTo(2)); - } - } - - - [Test] - public void Can_create_ModelWithIdAndName_table_with_specified_DefaultStringLength() - { - OrmLiteConfig.DialectProvider.DefaultStringLength = 255; - var createTableSql = OrmLiteConfig.DialectProvider.ToCreateTableStatement(typeof(ModelWithIdAndName)); - - Console.WriteLine("createTableSql: " + createTableSql); - Assert.That(createTableSql.Contains("VARCHAR(255)"), Is.True); - } - - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithNamingStrategyTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithNamingStrategyTests.cs deleted file mode 100644 index fb4a5fb39..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithNamingStrategyTests.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System; -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - - [TestFixture] - public class OrmLiteCreateTableWithNamigStrategyTests - : OrmLiteTestBase - { - - [Test] - public void Can_create_TableWithNamigStrategy_table_prefix() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix ="tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - [Test] - public void Can_create_TableWithNamigStrategy_table_lowered() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new LowercaseNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - - [Test] - public void Can_create_TableWithNamigStrategy_table_nameUnderscoreCoumpound() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new UnderscoreSeparatedCompoundNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - [Test] - public void Can_get_data_from_TableWithNamigStrategy_with_GetById() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id= "999", AlbumId = "112", AlbumName="ElectroShip", Name = "MyNameIsBatman"}; - - db.Save(m); - var modelFromDb = db.SingleById("999"); - - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - - [Test] - public void Can_get_data_from_TableWithNamigStrategy_with_query_by_example() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - - [Test] - public void Can_get_data_from_TableWithNamigStrategy_AfterChangingNamingStrategy() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - - modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - - modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - - modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - } - - public class PrefixNamingStrategy : OrmLiteNamingStrategyBase - { - - public string TablePrefix { get; set; } - - public string ColumnPrefix { get; set; } - - public override string GetTableName(string name) - { - return TablePrefix + name; - } - - public override string GetColumnName(string name) - { - return ColumnPrefix + name; - } - - } - - public class LowercaseNamingStrategy : OrmLiteNamingStrategyBase - { - - public override string GetTableName(string name) - { - return name.ToLower(); - } - - public override string GetColumnName(string name) - { - return name.ToLower(); - } - - } - - public class UnderscoreSeparatedCompoundNamingStrategy : OrmLiteNamingStrategyBase - { - - public override string GetTableName(string name) - { - return toUnderscoreSeparatedCompound(name); - } - - public override string GetColumnName(string name) - { - return toUnderscoreSeparatedCompound(name); - } - - - string toUnderscoreSeparatedCompound(string name) - { - - string r = char.ToLower(name[0]).ToString(); - - for (int i = 1; i < name.Length; i++) - { - char c = name[i]; - if (char.IsUpper(name[i])) - { - r += "_"; - r += char.ToLower(name[i]); - } - else - { - r += name[i]; - } - } - return r; - } - - } - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteGetScalarTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteGetScalarTests.cs deleted file mode 100644 index 5c00cc64e..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteGetScalarTests.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - [TestFixture] - public class OrmLiteGetScalarTests:OrmLiteTestBase - { - - [Test] - public void Can_get_scalar_value(){ - - List authors = new List(); - authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London", FloatProperty=10.25f, DoubleProperty=3.23 }); - authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota",FloatProperty=7.59f,DoubleProperty=4.23 }); - authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London",FloatProperty=15.5f,DoubleProperty=5.42 }); - authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota",FloatProperty=0.57f, DoubleProperty=8.76}); - authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=8.43f, DoubleProperty=7.35}); - authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=1.25f, DoubleProperty=0.3652}); - authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota", FloatProperty=1.5f, DoubleProperty=100.563}); - authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena", FloatProperty=3.5f,DoubleProperty=7.23 }); - authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena", FloatProperty=0.25f,DoubleProperty=9.23 }); - authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London", FloatProperty=9.95f,DoubleProperty=4.91 }); - authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin",FloatProperty=4.44f,DoubleProperty=6.41 }); - authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid", FloatProperty=6.67f, DoubleProperty=8.05 }); - authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid", FloatProperty=1.25f, DoubleProperty=3.99}); - authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, - City = "Mexico", - LastActivity= DateTime.Today, - NRate=5, - FloatProperty=1.25f, - NFloatProperty=3.15f, - DoubleProperty= 1.25, - NDoubleProperty= 8.25 - }); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - db.DeleteAll(); - - db.InsertAll(authors); - - var expectedDate = authors.Max(e=>e.Birthday); - var r1 = db.Scalar( e => Sql.Max(e.Birthday) ); - Assert.That(expectedDate, Is.EqualTo(r1)); - - expectedDate = authors.Where(e=>e.City=="London").Max(e=>e.Birthday); - r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="London" ); - Assert.That(expectedDate, Is.EqualTo(r1)); - - r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="SinCity" ); - Assert.That( default(DateTime), Is.EqualTo(r1)); - - - var expectedNullableDate= authors.Max(e=>e.LastActivity); - DateTime? r2 = db.Scalar(e=> Sql.Max(e.LastActivity)); - Assert.That(expectedNullableDate, Is.EqualTo(r2)); - - expectedNullableDate= authors.Where(e=> e.City=="Bogota").Max(e=>e.LastActivity); - r2 = db.Scalar( - e=> Sql.Max(e.LastActivity), - e=> e.City=="Bogota" ); - Assert.That(expectedNullableDate, Is.EqualTo(r2)); - - r2 = db.Scalar( e => Sql.Max(e.LastActivity), e=>e.City=="SinCity" ); - Assert.That( default(DateTime?), Is.EqualTo(r2)); - - - var expectedDecimal= authors.Max(e=>e.Earnings); - decimal r3 = db.Scalar(e=> Sql.Max(e.Earnings)); - Assert.That(expectedDecimal, Is.EqualTo(r3)); - - expectedDecimal= authors.Where(e=>e.City=="London").Max(e=>e.Earnings); - r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="London"); - Assert.That(expectedDecimal, Is.EqualTo(r3)); - - r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="SinCity"); - Assert.That( default(decimal), Is.EqualTo(r3)); - - - var expectedNullableDecimal= authors.Max(e=>e.NEarnings); - decimal? r4 = db.Scalar(e=> Sql.Max(e.NEarnings)); - Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); - - expectedNullableDecimal= authors.Where(e=>e.City=="London").Max(e=>e.NEarnings); - r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="London"); - Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); - - r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="SinCity"); - Assert.That( default(decimal?), Is.EqualTo(r4)); - - - var expectedDouble =authors.Max(e=>e.DoubleProperty); - double r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty)); - Assert.That(expectedDouble, Is.EqualTo(r5)); - - expectedDouble =authors.Where(e=>e.City=="London").Max(e=>e.DoubleProperty); - r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="London"); - Assert.That(expectedDouble, Is.EqualTo(r5)); - - r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="SinCity"); - Assert.That(default(double),Is.EqualTo(r5)); - - - var expectedNullableDouble =authors.Max(e=>e.NDoubleProperty); - double? r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty)); - Assert.That(expectedNullableDouble, Is.EqualTo(r6)); - - - expectedNullableDouble =authors.Where(e=>e.City=="London").Max(e=>e.NDoubleProperty); - r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="London"); - Assert.That(expectedNullableDouble, Is.EqualTo(r6)); - - r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="SinCity"); - Assert.That(default(double?),Is.EqualTo(r6)); - - - - var expectedFloat =authors.Max(e=>e.FloatProperty); - var r7 = db.Scalar(e=> Sql.Max(e.FloatProperty)); - Assert.That(expectedFloat, Is.EqualTo(r7)); - - expectedFloat =authors.Where(e=>e.City=="London").Max(e=>e.FloatProperty); - r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="London"); - Assert.That(expectedFloat, Is.EqualTo(r7)); - - r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="SinCity"); - Assert.That(default(float),Is.EqualTo(r7)); - - - var expectedNullableFloat =authors.Max(e=>e.NFloatProperty); - var r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty)); - Assert.That(expectedNullableFloat, Is.EqualTo(r8)); - - expectedNullableFloat =authors.Where(e=>e.City=="London").Max(e=>e.NFloatProperty); - r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="London"); - Assert.That(expectedNullableFloat, Is.EqualTo(r8)); - - r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="SinCity"); - Assert.That(default(float?),Is.EqualTo(r8)); - - - var expectedString=authors.Min(e=>e.Name); - var r9 = db.Scalar(e=> Sql.Min(e.Name)); - Assert.That(expectedString, Is.EqualTo(r9)); - - expectedString=authors.Where(e=>e.City=="London").Min(e=>e.Name); - r9 = db.Scalar(e=> Sql.Min(e.Name), e=>e.City=="London"); - Assert.That(expectedString, Is.EqualTo(r9)); - - r9 = db.Scalar(e=> Sql.Max(e.Name), e=>e.City=="SinCity"); - Assert.IsNullOrEmpty(r9); - - var expectedBool=authors.Min(e=>e.Active); - var r10 = db.Scalar(e=> Sql.Min(e.Active)); - Assert.That(expectedBool, Is.EqualTo(r10)); - - expectedBool=authors.Max(e=>e.Active); - r10 = db.Scalar(e=> Sql.Max(e.Active)); - Assert.That(expectedBool, Is.EqualTo(r10)); - - r10 = db.Scalar(e=> Sql.Max(e.Active), e=>e.City=="SinCity"); - Assert.IsFalse(r10); - - - - var expectedShort =authors.Max(e=>e.Rate); - var r11 = db.Scalar(e=> Sql.Max(e.Rate)); - Assert.That(expectedShort, Is.EqualTo(r11)); - - expectedShort =authors.Where(e=>e.City=="London").Max(e=>e.Rate); - r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="London"); - Assert.That(expectedShort, Is.EqualTo(r11)); - - r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="SinCity"); - Assert.That(default(short),Is.EqualTo(r7)); - - - var expectedNullableShort =authors.Max(e=>e.NRate); - var r12 = db.Scalar(e=> Sql.Max(e.NRate)); - Assert.That(expectedNullableShort, Is.EqualTo(r12)); - - expectedNullableShort =authors.Where(e=>e.City=="London").Max(e=>e.NRate); - r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="London"); - Assert.That(expectedNullableShort, Is.EqualTo(r12)); - - r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="SinCity"); - Assert.That(default(short?),Is.EqualTo(r12)); - - } - - } - - } - - - public class Author - { - public Author(){} - - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - - public DateTime Birthday { get; set;} - public DateTime? LastActivity { get; set;} - public decimal Earnings { get; set;} - public decimal? NEarnings { get; set;} - - public bool Active { get; set; } - - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - - public short Rate{ get; set;} - public short? NRate{ get; set;} - public float FloatProperty { get; set;} - public float? NFloatProperty { get; set;} - public double DoubleProperty { get; set;} - public double? NDoubleProperty { get; set;} - - } - - -} - diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteSelectTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteSelectTests.cs deleted file mode 100644 index f4e31734c..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteSelectTests.cs +++ /dev/null @@ -1,304 +0,0 @@ -using System.Collections.Generic; -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - [TestFixture] - public class OrmLiteSelectTests - : OrmLiteTestBase - { - - [Test] - public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var row = db.SingleById(1); - - Assert.That(row.Id, Is.EqualTo(1)); - } - } - - [Test] - public void Can_GetById_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var row = db.SingleById("id-1"); - - Assert.That(row.Id, Is.EqualTo("id-1")); - } - } - - [Test] - public void Can_GetByIds_int_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var rows = db.SelectByIds(rowIds); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_GetByIds_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var rows = db.SelectByIds(rowIds); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; - - db.Insert(filterRow); - - var rows = db.SelectFmt("AlbumName = {0}", filterRow.AlbumName); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } - - [Test] - public void Can_select_scalar_value() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var count = db.ScalarFmt("SELECT COUNT(*) FROM ModelWithIdAndName"); - - Assert.That(count, Is.EqualTo(n)); - } - } - - [Test] - public void Can_loop_each_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var dbRowIds = new List(); - foreach (var row in db.SelectLazy()) - { - dbRowIds.Add(row.Id); - } - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; - - db.Insert(filterRow); - - var dbRowIds = new List(); - var rows = db.SelectLazyFmt("AlbumName = {0}", filterRow.AlbumName); - foreach (var row in rows) - { - dbRowIds.Add(row.Id); - } - - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } - - [Test] - public void Can_GetFirstColumn() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var ids = db.ColumnFmt("SELECT Id FROM ModelWithIdAndName"); - - Assert.That(ids.Count, Is.EqualTo(n)); - } - } - - [Test] - public void Can_GetFirstColumnDistinct() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var ids = db.ColumnDistinctFmt("SELECT Id FROM ModelWithIdAndName"); - - Assert.That(ids.Count, Is.EqualTo(n)); - } - } - - [Test] - public void Can_GetLookup() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => { - var row = ModelWithIdAndName.Create(x); - row.Name = x % 2 == 0 ? "OddGroup" : "EvenGroup"; - db.Insert(row); - }); - - var lookup = db.LookupFmt("SELECT Name, Id FROM ModelWithIdAndName"); - - Assert.That(lookup, Has.Count.EqualTo(2)); - Assert.That(lookup["OddGroup"], Has.Count.EqualTo(3)); - Assert.That(lookup["EvenGroup"], Has.Count.EqualTo(2)); - } - } - - [Test] - public void Can_GetDictionary() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var dictionary = db.Dictionary("SELECT Id, Name FROM ModelWithIdAndName"); - - Assert.That(dictionary, Has.Count.EqualTo(5)); - - //Console.Write(dictionary.Dump()); - } - } - - [Test] - public void Can_Select_subset_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var rows = db.SelectFmt("SELECT Id, Name FROM ModelWithFieldsOfDifferentTypes"); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_Select_Into_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var rows = db.Select(typeof(ModelWithFieldsOfDifferentTypes)); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_Select_In_for_string_value() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var selectInNames = new[] {"Name1", "Name2"}; - var rows = db.SelectFmt("Name IN ({0})", selectInNames.SqlInValues()); - - Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); - } - } - - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteTestBase.cs b/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteTestBase.cs deleted file mode 100644 index 3dbce8f91..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteTestBase.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Configuration; -using System.Data; -using NUnit.Framework; -using ServiceStack.Logging; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - public class OrmLiteTestBase - { - protected virtual string ConnectionString { get; set; } - - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - LogManager.LogFactory = new ConsoleLogFactory(); - - OrmLiteConfig.DialectProvider = MySqlDialectProvider.Instance; - ConnectionString = ConfigurationManager.ConnectionStrings["testDb"].ConnectionString; - } - - public void Log(string text) - { - Console.WriteLine(text); - } - - public virtual IDbConnection OpenDbConnection(string connString = null) - { - connString = connString ?? ConnectionString; - return connString.OpenDbConnection(); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.MySql.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index ef9f8574e..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.MySql.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.MySql.Tests")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("6753faeb-f6c3-4aa1-bca0-2a15d2bf1522")] - diff --git a/src/ServiceStack.OrmLite.MySql.Tests/ServiceStack.OrmLite.MySql.Tests.csproj b/src/ServiceStack.OrmLite.MySql.Tests/ServiceStack.OrmLite.MySql.Tests.csproj deleted file mode 100644 index 7404e6e10..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/ServiceStack.OrmLite.MySql.Tests.csproj +++ /dev/null @@ -1,161 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {21EBB2F6-030B-492C-963B-2FC447684CCD} - Library - Properties - ServiceStack.OrmLite.MySql.Tests - ServiceStack.OrmLite.MySql.Tests - 512 - ..\ - true - v4.5 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - false - - - bin\Signed\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - false - - - - False - ..\packages\MySql.Data.6.9.5\lib\net45\MySql.Data.dll - - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {9b64f4a7-c008-46a8-ad6f-99626dcfefbd} - ServiceStack.OrmLite.Tests - - - {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5} - ServiceStack.OrmLite.MySql - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - Designer - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/StringColumnTests.cs b/src/ServiceStack.OrmLite.MySql.Tests/StringColumnTests.cs deleted file mode 100644 index 34aaff604..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/StringColumnTests.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Collections.Generic; - -using System.Linq; -using System.Text; -using MySql.Data.MySqlClient; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; -using ServiceStack.OrmLite.MySql.DataAnnotations; - -namespace ServiceStack.OrmLite.MySql.Tests -{ - [TestFixture] - public class StringColumnTests - : OrmLiteTestBase - { - [Test] - public void Can_create_primary_key_varchar_with_string_length_255() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_create_primary_key_varchar_without_setting_string_length() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_create_unique_key_on_varchar_without_setting_string_length() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_store_and_retrieve_string_with_8000_characters_from_varchar_field() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var obj = new TypeWithStringId { - Id = "a", - Value = CreateString(8000) - }; - - Assert.AreEqual(8000, obj.Value.Length); - - db.Save(obj); - var target = db.SingleById(obj.Id); - - Assert.AreEqual(obj.Value, target.Value); - Assert.AreEqual(8000, obj.Value.Length); - } - } - - [Test] - public void Can_store_and_retrieve_string_with_8000_characters_from_text_field() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var obj = new TypeWithTextField() { - Value = CreateString(8000) - }; - - Assert.AreEqual(8000, obj.Value.Length); - - db.Save(obj); - obj.Id = (int)db.LastInsertId(); - - var target = db.SingleById(obj.Id); - - Assert.AreEqual(obj.Value, target.Value); - Assert.AreEqual(8000, obj.Value.Length); - } - } - - #region classes - - class TypeWithUniqeKeyOnVarchar - { - public int Id { get; set; } - - [Index(true)] - public string Value { get; set; } - } - - class TypeWithUniqeKeyOnVarchar_256 - { - public int Id { get; set; } - - [StringLength(256)] - [Index(true)] - public string Value { get; set; } - } - - class TypeWithStringId : IHasStringId - { - public string Id { get; set; } - [StringLength(8000)] - public string Value { get; set; } - } - - class TypeWithUniqueIndexOnTextField - { - [AutoIncrement] - public int Id { get; set; } - - [Index(true)] - [Text] - public string Value { get; set; } - } - - class TypeWithTextField - { - [AutoIncrement] - public int Id { get; set; } - - [Text] - public string Value { get; set; } - } - - class TypeWithStringId_255 : IHasStringId - { - [StringLength(255)] - public string Id { get; set; } - public string Value { get; set; } - } - - class TypeWithStringId_256 : IHasStringId - { - [StringLength(256)] - public string Id { get; set; } - public string Value { get; set; } - } - - #endregion - - private static string CreateString(int length) - { - const string loremIpsum = - "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."; - - var retVal = ""; - - for (int i = 0; i < length / loremIpsum.Length; i++) - retVal += loremIpsum; - - return retVal + loremIpsum.Substring(0, length - retVal.Length); - } - } -} diff --git a/src/ServiceStack.OrmLite.MySql.Tests/UseCase/CustomerOrdersUseCase.cs b/src/ServiceStack.OrmLite.MySql.Tests/UseCase/CustomerOrdersUseCase.cs deleted file mode 100644 index 8eabed66f..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/UseCase/CustomerOrdersUseCase.cs +++ /dev/null @@ -1,220 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.MySql.Tests.UseCase -{ - public enum PhoneType - { - Home, - Work, - Mobile, - } - - public enum AddressType - { - Home, - Work, - Other, - } - - public class Address - { - public string Line1 { get; set; } - public string Line2 { get; set; } - public string ZipCode { get; set; } - public string State { get; set; } - public string City { get; set; } - public string Country { get; set; } - } - - public class Customer - { - public Customer() - { - this.PhoneNumbers = new Dictionary(); - this.Addresses = new Dictionary(); - } - - [AutoIncrement] // Creates Auto primary key - public int Id { get; set; } - - public string FirstName { get; set; } - - public string LastName { get; set; } - - [Index(Unique = true)] // Creates Unique Index - public string Email { get; set; } - - public Dictionary PhoneNumbers { get; set; } - - public Dictionary Addresses { get; set; } - - public DateTime CreatedAt { get; set; } - } - - public class Order - { - [AutoIncrement] - public int Id { get; set; } - - [References(typeof(Customer))] //Creates Foreign Key - public int CustomerId { get; set; } - - [References(typeof(Employee))] //Creates Foreign Key - public int EmployeeId { get; set; } - - public Address ShippingAddress { get; set; } //Blobbed (no Address table) - - public DateTime? OrderDate { get; set; } - - public DateTime? RequiredDate { get; set; } - - public DateTime? ShippedDate { get; set; } - - public int? ShipVia { get; set; } - - public decimal Freight { get; set; } - - public decimal Total { get; set; } - } - - public class OrderDetail - { - [AutoIncrement] - public int Id { get; set; } - - [References(typeof(Order))] //Creates Foreign Key - public int OrderId { get; set; } - - public int ProductId { get; set; } - - public decimal UnitPrice { get; set; } - - public short Quantity { get; set; } - - public decimal Discount { get; set; } - } - - public class Employee - { - public int Id { get; set; } - - public string Name { get; set; } - } - - public class Product - { - public int Id { get; set; } - - public string Name { get; set; } - - public decimal UnitPrice { get; set; } - } - - [TestFixture] - public class CustomerOrdersUseCase - { - //Stand-alone class, No other configs, nothing but POCOs. - [Test] - public void Run() - { - //Setup SQL Server Connection Factory - var dbFactory = new OrmLiteConnectionFactory( - ConfigurationManager.ConnectionStrings["testDb"].ConnectionString, - MySqlDialectProvider.Instance); - - //Non-intrusive: All extension methods hang off System.Data.* interfaces - IDbConnection db = dbFactory.OpenDbConnection(); - - //Re-Create all table schemas: - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - - db.Insert(new Employee { Id = 1, Name = "Employee 1" }); - db.Insert(new Employee { Id = 2, Name = "Employee 2" }); - var product1 = new Product { Id = 1, Name = "Product 1", UnitPrice = 10 }; - var product2 = new Product { Id = 2, Name = "Product 2", UnitPrice = 20 }; - db.Save(product1, product2); - - var customer = new Customer - { - FirstName = "Orm", - LastName = "Lite", - Email = "ormlite@servicestack.net", - PhoneNumbers = - { - { PhoneType.Home, "555-1234" }, - { PhoneType.Work, "1-800-1234" }, - { PhoneType.Mobile, "818-123-4567" }, - }, - Addresses = - { - { AddressType.Work, new Address { Line1 = "1 Street", Country = "US", State = "NY", City = "New York", ZipCode = "10101" } }, - }, - CreatedAt = DateTime.UtcNow, - }; - db.Insert(customer); - - var customerId = db.LastInsertId(); //Get Auto Inserted Id - customer = db.Single(new { customer.Email }); //Query - Assert.That(customer.Id, Is.EqualTo(customerId)); - - //Direct access to System.Data.Transactions: - using (var trans = db.BeginTransaction(IsolationLevel.ReadCommitted)) - { - var order = new Order - { - CustomerId = customer.Id, - EmployeeId = 1, - OrderDate = DateTime.UtcNow, - Freight = 10.50m, - ShippingAddress = new Address { Line1 = "3 Street", Country = "US", State = "NY", City = "New York", ZipCode = "12121" }, - }; - db.Save(order); //Inserts 1st time - - order.Id = (int)db.LastInsertId(); //Get Auto Inserted Id - - var orderDetails = new[] { - new OrderDetail - { - OrderId = order.Id, - ProductId = product1.Id, - Quantity = 2, - UnitPrice = product1.UnitPrice, - }, - new OrderDetail - { - OrderId = order.Id, - ProductId = product2.Id, - Quantity = 2, - UnitPrice = product2.UnitPrice, - Discount = .15m, - } - }; - - db.Insert(orderDetails); - - order.Total = orderDetails.Sum(x => x.UnitPrice * x.Quantity * x.Discount) + order.Freight; - - db.Save(order); //Updates 2nd Time - - trans.Commit(); - } - } - } - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/UseCase/SimpleUseCase.cs b/src/ServiceStack.OrmLite.MySql.Tests/UseCase/SimpleUseCase.cs deleted file mode 100644 index 2fd0fc2b2..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/UseCase/SimpleUseCase.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.MySql.Tests.UseCase -{ - [TestFixture] - public class SimpleUseCase - { - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - //Inject your database provider here - OrmLiteConfig.DialectProvider = MySqlDialectProvider.Instance; - } - - public class UserWithIndex - { - public long Id { get; set; } - - [ServiceStack.DataAnnotations.Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - } - - [Test] - public void Simple_CRUD_example() - { - using (IDbConnection db = ConfigurationManager.ConnectionStrings["testDb"].ConnectionString.OpenDbConnection()) - { - db.CreateTable(true); - - db.Insert(new UserWithIndex { Id = 1, Name = "A", CreatedDate = DateTime.Now }); - db.Insert(new UserWithIndex { Id = 2, Name = "B", CreatedDate = DateTime.Now }); - db.Insert(new UserWithIndex { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - - var rowsB = db.SelectFmt("Name = {0}", "B"); - - Assert.That(rowsB, Has.Count.EqualTo(2)); - - var rowIds = rowsB.ConvertAll(x => x.Id); - Assert.That(rowIds, Is.EquivalentTo(new List { 2, 3 })); - - rowsB.ForEach(x => db.Delete(x)); - - rowsB = db.SelectFmt("Name = {0}", "B"); - Assert.That(rowsB, Has.Count.EqualTo(0)); - - var rowsLeft = db.Select(); - Assert.That(rowsLeft, Has.Count.EqualTo(1)); - - Assert.That(rowsLeft[0].Name, Is.EqualTo("A")); - } - } - - } - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/app.config b/src/ServiceStack.OrmLite.MySql.Tests/app.config deleted file mode 100644 index 0cac99f1a..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/app.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/ServiceStack.OrmLite.MySql.Tests/packages.config b/src/ServiceStack.OrmLite.MySql.Tests/packages.config deleted file mode 100644 index 9ac31173e..000000000 --- a/src/ServiceStack.OrmLite.MySql.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlBoolConverter.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlBoolConverter.cs new file mode 100644 index 000000000..c6fedb258 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlBoolConverter.cs @@ -0,0 +1,11 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public class MySqlBoolConverter : BoolAsIntConverter + { + public override string ColumnDefinition => "tinyint(1)"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeConverter.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeConverter.cs new file mode 100644 index 000000000..4915619bf --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeConverter.cs @@ -0,0 +1,27 @@ +using System; +using ServiceStack.OrmLite.Converters; +using MySql.Data.Types; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public class MySqlDateTimeConverter : MySqlDateTimeConverterBase + { + public override object FromDbValue(object value) + { + // TODO throws error if connection string option not set - https://stackoverflow.com/questions/5754822/unable-to-convert-mysql-date-time-value-to-system-datetime + if (value is MySqlDateTime time) + { + return time.GetDateTime(); + } + return base.FromDbValue(value); + } + } + + public class MySql55DateTimeConverter : MySqlDateTimeConverter + { + /// + /// CURRENT_TIMESTAMP as a default for DATETIME type is only available in 10.x. If you're using 5.5, it should a TIMESTAMP column + /// + public override string ColumnDefinition => "TIMESTAMP"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeConverterBase.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeConverterBase.cs new file mode 100644 index 000000000..87b53cabf --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeConverterBase.cs @@ -0,0 +1,28 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public abstract class MySqlDateTimeConverterBase : DateTimeConverter + { + public int Precision { get; set; } = 0; + + public override string ColumnDefinition => Precision == 0 + ? "DATETIME" + : $"DATETIME({Precision})"; + + public override string ToQuotedString(Type fieldType, object value) + { + /* + * ms not contained in format. MySql ignores ms part anyway + * for more details see: http://dev.mysql.com/doc/refman/5.1/en/datetime.html + */ + var dateTime = (DateTime)value; + var suffix = Precision > 0 + ? "." + new string('f', Precision) + : ""; + return DateTimeFmt(dateTime, "yyyy-MM-dd HH:mm:ss" + suffix); + } + + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeOffsetConverter.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeOffsetConverter.cs new file mode 100644 index 000000000..a12c46980 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlDateTimeOffsetConverter.cs @@ -0,0 +1,9 @@ +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public class MySqlDateTimeOffsetConverter : DateTimeOffsetConverter + { + public override string ColumnDefinition => "VARCHAR(255)"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlFloatConverters.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlFloatConverters.cs new file mode 100644 index 000000000..286855a21 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlFloatConverters.cs @@ -0,0 +1,9 @@ +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public class MySqlDecimalConverter : DecimalConverter + { + public MySqlDecimalConverter() : base(38,6) { } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlGuidConverter.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlGuidConverter.cs new file mode 100644 index 000000000..d8590b277 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlGuidConverter.cs @@ -0,0 +1,16 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public class MySqlGuidConverter : GuidConverter + { + public override string ColumnDefinition => "CHAR(36)"; + + public override string ToQuotedString(Type fieldType, object value) + { + var guid = (Guid)value; + return DialectProvider.GetQuotedValue(guid.ToString("d"), typeof(string)); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlIntegerConverters.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlIntegerConverters.cs new file mode 100644 index 000000000..d08663697 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlIntegerConverters.cs @@ -0,0 +1,39 @@ +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public abstract class MySqlIntegerConverter : IntegerConverter + { + public override string ColumnDefinition => "INT(11)"; + } + + public class MySqlByteConverter : MySqlIntegerConverter + { + public override DbType DbType => DbType.Byte; + } + + public class MySqlSByteConverter : MySqlIntegerConverter + { + public override DbType DbType => DbType.SByte; + } + + public class MySqlInt16Converter : MySqlIntegerConverter + { + public override DbType DbType => DbType.Int16; + } + + public class MySqlUInt16Converter : MySqlIntegerConverter + { + public override DbType DbType => DbType.UInt16; + } + + public class MySqlInt32Converter : MySqlIntegerConverter + { + } + + public class MySqlUInt32Converter : MySqlIntegerConverter + { + public override DbType DbType => DbType.UInt32; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/Converters/MySqlStringConverters.cs b/src/ServiceStack.OrmLite.MySql/Converters/MySqlStringConverters.cs new file mode 100644 index 000000000..935d24e4f --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/Converters/MySqlStringConverters.cs @@ -0,0 +1,39 @@ +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.MySql.Converters +{ + public class MySqlStringConverter : StringConverter + { + public MySqlStringConverter() : base(255) {} + + //https://stackoverflow.com/a/37721151/85785 + public override int MaxVarCharLength => UseUnicode ? 16383 : 21844; + + public override string MaxColumnDefinition => "LONGTEXT"; + } + + public class MySqlCharArrayConverter : CharArrayConverter + { + public MySqlCharArrayConverter() : base(255) { } + + public override string MaxColumnDefinition => "LONGTEXT"; + } + + public class MySql55StringConverter : StringConverter + { + public MySql55StringConverter() : base(255) {} + + //https://stackoverflow.com/a/37721151/85785 + public override int MaxVarCharLength => UseUnicode ? 16383 : 21844; + + public override string MaxColumnDefinition => "LONGTEXT"; + } + + public class MySql55CharArrayConverter : CharArrayConverter + { + public MySql55CharArrayConverter() : base(255) { } + + public override string MaxColumnDefinition => "LONGTEXT"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/MySqlDialect.cs b/src/ServiceStack.OrmLite.MySql/MySqlDialect.cs index cda6e654c..b75d4cb80 100644 --- a/src/ServiceStack.OrmLite.MySql/MySqlDialect.cs +++ b/src/ServiceStack.OrmLite.MySql/MySqlDialect.cs @@ -1,9 +1,16 @@ -using ServiceStack.OrmLite.MySql; - -namespace ServiceStack.OrmLite -{ - public static class MySqlDialect - { - public static IOrmLiteDialectProvider Provider { get { return MySqlDialectProvider.Instance; } } - } +using ServiceStack.OrmLite.MySql; + +namespace ServiceStack.OrmLite +{ + public static class MySqlDialect + { + public static IOrmLiteDialectProvider Provider => MySqlDialectProvider.Instance; + public static MySqlDialectProvider Instance => MySqlDialectProvider.Instance; + } + + public static class MySql55Dialect + { + public static IOrmLiteDialectProvider Provider => MySql55DialectProvider.Instance; + public static MySql55DialectProvider Instance => MySql55DialectProvider.Instance; + } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/MySqlDialectProvider.cs b/src/ServiceStack.OrmLite.MySql/MySqlDialectProvider.cs index 233c3201a..3ba1619f6 100644 --- a/src/ServiceStack.OrmLite.MySql/MySqlDialectProvider.cs +++ b/src/ServiceStack.OrmLite.MySql/MySqlDialectProvider.cs @@ -1,318 +1,54 @@ using System; using System.Collections.Generic; using System.Data; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using MySql.Data.MySqlClient; -using ServiceStack.Data; -using ServiceStack.OrmLite.MySql.DataAnnotations; -using ServiceStack.Text; +using ServiceStack.OrmLite.MySql.Converters; namespace ServiceStack.OrmLite.MySql { - public class MySqlDialectProvider : OrmLiteDialectProviderBase + public class MySqlDialectProvider : MySqlDialectProviderBase { public static MySqlDialectProvider Instance = new MySqlDialectProvider(); private const string TextColumnDefinition = "TEXT"; - public MySqlDialectProvider() - { - base.AutoIncrementDefinition = "AUTO_INCREMENT"; - base.IntColumnDefinition = "int(11)"; - base.BoolColumnDefinition = "tinyint(1)"; - base.DecimalColumnDefinition = "decimal(38,6)"; - base.GuidColumnDefinition = "char(36)"; - base.DefaultStringLength = 255; - base.MaxStringColumnDefinition = "TEXT"; - base.InitColumnTypeMap(); - base.DefaultValueFormat = " DEFAULT '{0}'"; - base.SelectIdentitySql = "SELECT LAST_INSERT_ID()"; - } - - public override void OnAfterInitColumnTypeMap() - { - DbTypeMap.Set(DbType.String, GuidColumnDefinition); - DbTypeMap.Set(DbType.String, GuidColumnDefinition); - DbTypeMap.Set(DbType.DateTimeOffset, StringColumnDefinition); - DbTypeMap.Set(DbType.DateTimeOffset, StringColumnDefinition); - } - - public static string RowVersionTriggerFormat = "{0}RowVersionUpdateTrigger"; - - public override string ToPostDropTableStatement(ModelDefinition modelDef) - { - if (modelDef.RowVersion != null) - { - var triggerName = RowVersionTriggerFormat.Fmt(GetTableName(modelDef)); - return "DROP TRIGGER IF EXISTS {0}".Fmt(GetQuotedName(triggerName)); - } - - - return null; - } - - public override string ToPostCreateTableStatement(ModelDefinition modelDef) - { - if (modelDef.RowVersion != null) - { - var triggerName = RowVersionTriggerFormat.Fmt(modelDef.ModelName); - var triggerBody = "SET NEW.{0} = OLD.{0} + 1;".Fmt( - modelDef.RowVersion.FieldName.SqlColumn(this)); - - var sql = "CREATE TRIGGER {0} BEFORE UPDATE ON {1} FOR EACH ROW BEGIN {2} END;".Fmt( - triggerName, GetTableName(modelDef), triggerBody); - - return sql; - } - - return null; - } - - public override string GetQuotedValue(string paramValue) - { - return "'" + paramValue.Replace("\\", "\\\\").Replace("'", @"\'") + "'"; - } - public override IDbConnection CreateConnection(string connectionString, Dictionary options) { return new MySqlConnection(connectionString); } - public override string GetQuotedValue(object value, Type fieldType) - { - if (value == null) return "NULL"; - - if (fieldType == typeof(DateTime)) - { - var dateValue = (DateTime)value; - /* - * ms not contained in format. MySql ignores ms part anyway - * - * for more details see: http://dev.mysql.com/doc/refman/5.1/en/datetime.html - */ - const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss"; - - return base.GetQuotedValue(dateValue.ToString(dateTimeFormat), typeof(string)); - } - - if (fieldType == typeof(byte[])) - { - return "0x" + BitConverter.ToString((byte[])value).Replace("-", ""); - } - - return base.GetQuotedValue(value, fieldType); - } - - public override object ConvertDbValue(object value, Type type) - { - if (value == null || value is DBNull) return null; - - if (type == typeof(bool)) - { - return - value is bool - ? value - : (int.Parse(value.ToString()) != 0); //backward compatibility (prev version mapped bool as bit(1)) - } - - if (type == typeof(byte[])) - return value; - - return base.ConvertDbValue(value, type); - } - - public override string GetTableName(string table, string schema = null) - { - return schema != null - ? string.Format("{0}_{1}", - NamingStrategy.GetSchemaName(schema), - NamingStrategy.GetTableName(table)) - : NamingStrategy.GetTableName(table); - } - - public override string GetQuotedTableName(string tableName, string schema = null) - { - return GetQuotedName(GetTableName(tableName, schema)); - } - - public override string GetQuotedName(string name) - { - return string.Format("`{0}`", name); - } - - public override SqlExpression SqlExpression() - { - return new MySqlExpression(this); - } - - public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) - { - //Same as SQL Server apparently? - var sql = ("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " + - "WHERE TABLE_NAME = {0} AND " + - "TABLE_SCHEMA = {1}") - .SqlFmt(GetTableName(tableName, schema), dbCmd.Connection.Database); - - dbCmd.CommandText = sql; - var result = dbCmd.LongScalar(); - - return result > 0; - } - - public override string ToCreateTableStatement(Type tableType) - { - var sbColumns = new StringBuilder(); - var sbConstraints = new StringBuilder(); - - var modelDef = GetModel(tableType); - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (sbColumns.Length != 0) sbColumns.Append(", \n "); - - sbColumns.Append(GetColumnDefinition(fieldDef)); - - if (fieldDef.ForeignKey == null) continue; - - var refModelDef = GetModel(fieldDef.ForeignKey.ReferenceType); - sbConstraints.AppendFormat( - ", \n\n CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2} ({3})", - GetQuotedName(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef)), - GetQuotedColumnName(fieldDef.FieldName), - GetQuotedTableName(refModelDef), - GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)); - - if (!string.IsNullOrEmpty(fieldDef.ForeignKey.OnDelete)) - sbConstraints.AppendFormat(" ON DELETE {0}", fieldDef.ForeignKey.OnDelete); - - if (!string.IsNullOrEmpty(fieldDef.ForeignKey.OnUpdate)) - sbConstraints.AppendFormat(" ON UPDATE {0}", fieldDef.ForeignKey.OnUpdate); - } - var sql = new StringBuilder(string.Format( - "CREATE TABLE {0} \n(\n {1}{2} \n); \n", GetQuotedTableName(modelDef), sbColumns, sbConstraints)); - - return sql.ToString(); - } - - public string GetColumnDefinition(FieldDefinition fieldDefinition) - { - if (fieldDefinition.PropertyInfo.FirstAttribute() != null) - { - var sql = new StringBuilder(); - sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldDefinition.FieldName), TextColumnDefinition); - sql.Append(fieldDefinition.IsNullable ? " NULL" : " NOT NULL"); - return sql.ToString(); - } - - var ret = base.GetColumnDefinition( - fieldDefinition.FieldName, - fieldDefinition.ColumnType, - fieldDefinition.IsPrimaryKey, - fieldDefinition.AutoIncrement, - fieldDefinition.IsNullable, - fieldDefinition.IsRowVersion, - fieldDefinition.FieldLength, - null, - fieldDefinition.DefaultValue, - fieldDefinition.CustomFieldDefinition); - - if (fieldDefinition.IsRowVersion) - return ret + " DEFAULT 1"; - - return ret; - } - - protected MySqlConnection Unwrap(IDbConnection db) - { - return (MySqlConnection)db.ToDbConnection(); - } - - protected MySqlCommand Unwrap(IDbCommand cmd) - { - return (MySqlCommand)cmd.ToDbCommand(); - } - - protected MySqlDataReader Unwrap(IDataReader reader) - { - return (MySqlDataReader)reader; - } - -#if NET45 - public override Task OpenAsync(IDbConnection db, CancellationToken token) - { - return Unwrap(db).OpenAsync(token); - } - - public override Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token) - { - return Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x); - } - - public override Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token) + public MySqlDialectProvider() { - return Unwrap(cmd).ExecuteNonQueryAsync(token); + RegisterConverter(new MySqlDateTimeConverter()); } - public override Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token) + public override IDbDataParameter CreateParam() { - return Unwrap(cmd).ExecuteScalarAsync(token); + return new MySqlParameter(); } + } + + public class MySql55DialectProvider : MySqlDialectProviderBase + { + public static MySql55DialectProvider Instance = new MySql55DialectProvider(); - public override Task ReadAsync(IDataReader reader, CancellationToken token) - { - return Unwrap(reader).ReadAsync(token); - } + private const string TextColumnDefinition = "TEXT"; - public override async Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token) + public override IDbConnection CreateConnection(string connectionString, Dictionary options) { - try - { - var to = new List(); - while (await ReadAsync(reader, token).ConfigureAwait(false)) - { - var row = fn(); - to.Add(row); - } - return to; - } - finally - { - reader.Dispose(); - } + return new MySqlConnection(connectionString); } - public override async Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token) + public MySql55DialectProvider() { - try - { - while (await ReadAsync(reader, token).ConfigureAwait(false)) - { - fn(); - } - return source; - } - finally - { - reader.Dispose(); - } + RegisterConverter(new MySql55DateTimeConverter()); + RegisterConverter(new MySql55StringConverter()); + RegisterConverter(new MySql55CharArrayConverter()); } - public override async Task ReaderRead(IDataReader reader, Func fn, CancellationToken token) + public override IDbDataParameter CreateParam() { - try - { - if (await ReadAsync(reader, token).ConfigureAwait(false)) - return fn(); - - return default(T); - } - finally - { - reader.Dispose(); - } + return new MySqlParameter(); } -#endif - } } diff --git a/src/ServiceStack.OrmLite.MySql/MySqlDialectProviderBase.cs b/src/ServiceStack.OrmLite.MySql/MySqlDialectProviderBase.cs new file mode 100644 index 000000000..72c5dff32 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/MySqlDialectProviderBase.cs @@ -0,0 +1,657 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using ServiceStack.OrmLite.MySql.Converters; +using ServiceStack.OrmLite.MySql.DataAnnotations; +using ServiceStack.Script; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.MySql +{ + public abstract class MySqlDialectProviderBase : OrmLiteDialectProviderBase where TDialect : IOrmLiteDialectProvider + { + + private const string TextColumnDefinition = "TEXT"; + + public MySqlDialectProviderBase() + { + base.AutoIncrementDefinition = "AUTO_INCREMENT"; + base.DefaultValueFormat = " DEFAULT {0}"; + base.SelectIdentitySql = "SELECT LAST_INSERT_ID()"; + + base.InitColumnTypeMap(); + + base.RegisterConverter(new MySqlStringConverter()); + base.RegisterConverter(new MySqlCharArrayConverter()); + base.RegisterConverter(new MySqlBoolConverter()); + + base.RegisterConverter(new MySqlByteConverter()); + base.RegisterConverter(new MySqlSByteConverter()); + base.RegisterConverter(new MySqlInt16Converter()); + base.RegisterConverter(new MySqlUInt16Converter()); + base.RegisterConverter(new MySqlInt32Converter()); + base.RegisterConverter(new MySqlUInt32Converter()); + + base.RegisterConverter(new MySqlDecimalConverter()); + + base.RegisterConverter(new MySqlGuidConverter()); + base.RegisterConverter(new MySqlDateTimeOffsetConverter()); + + this.Variables = new Dictionary + { + { OrmLiteVariables.SystemUtc, "CURRENT_TIMESTAMP" }, + { OrmLiteVariables.MaxText, "LONGTEXT" }, + { OrmLiteVariables.MaxTextUnicode, "LONGTEXT" }, + { OrmLiteVariables.True, SqlBool(true) }, + { OrmLiteVariables.False, SqlBool(false) }, + }; + } + + public static string RowVersionTriggerFormat = "{0}RowVersionUpdateTrigger"; + + public static HashSet ReservedWords = new HashSet(new[] + { + "ACCESSIBLE", + "ADD", + "ALL", + "ALTER", + "ANALYZE", + "AND", + "AS", + "ASC", + "ASENSITIVE", + "BEFORE", + "BETWEEN", + "BIGINT", + "BINARY", + "BLOB", + "BOTH", + "BY", + "CALL", + "CASCADE", + "CASE", + "CHANGE", + "CHAR", + "CHARACTER", + "CHECK", + "COLLATE", + "COLUMN", + "CONDITION", + "CONSTRAINT", + "CONTINUE", + "CONVERT", + "CREATE", + "CROSS", + "CUBE", + "CUME_DIST", + "CURRENT_DATE", + "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "CURRENT_USER", + "CURSOR", + "DATABASE", + "DATABASES", + "DAY_HOUR", + "DAY_MICROSECOND", + "DAY_MINUTE", + "DAY_SECOND", + "DEC", + "DECIMAL", + "DECLARE", + "DEFAULT", + "DELAYED", + "DELETE", + "DENSE_RANK", + "DESC", + "DESCRIBE", + "DETERMINISTIC", + "DISTINCT", + "DISTINCTROW", + "DIV", + "DOUBLE", + "DROP", + "DUAL", + "EACH", + "ELSE", + "ELSEIF", + "EMPTY", + "ENCLOSED", + "ESCAPED", + "EXCEPT", + "EXISTS", + "EXIT", + "EXPLAIN", + "FALSE", + "FETCH", + "FIRST_VALUE", + "FLOAT", + "FLOAT4", + "FLOAT8", + "FOR", + "FORCE", + "FOREIGN", + "FROM", + "FULLTEXT", + "FUNCTION", + "GENERATED", + "GET", + "GRANT", + "GROUP", + "GROUPING", + "GROUPS", + "HAVING", + "HIGH_PRIORITY", + "HOUR_MICROSECOND", + "HOUR_MINUTE", + "HOUR_SECOND", + "IF", + "IGNORE", + "IN", + "INDEX", + "INFILE", + "INNER", + "INOUT", + "INSENSITIVE", + "INSERT", + "INT", + "INT1", + "INT2", + "INT3", + "INT4", + "INT8", + "INTEGER", + "INTERVAL", + "INTO", + "IO_AFTER_GTIDS", + "IO_BEFORE_GTIDS", + "IS", + "ITERATE", + "JOIN", + "JSON_TABLE", + "KEY", + "KEYS", + "KILL", + "LAG", + "LAST_VALUE", + "LEAD", + "LEADING", + "LEAVE", + "LEFT", + "LIKE", + "LIMIT", + "LINEAR", + "LINES", + "LOAD", + "LOCALTIME", + "LOCALTIMESTAMP", + "LOCK", + "LONG", + "LONGBLOB", + "LONGTEXT", + "LOOP", + "LOW_PRIORITY", + "MASTER_BIND", + "MASTER_SSL_VERIFY_SERVER_CERT", + "MATCH", + "MAXVALUE", + "MEDIUMBLOB", + "MEDIUMINT", + "MEDIUMTEXT", + "MIDDLEINT", + "MINUTE_MICROSECOND", + "MINUTE_SECOND", + "MOD", + "MODIFIES", + "NATURAL", + "NOT", + "NO_WRITE_TO_BINLOG", + "NTH_VALUE", + "NTILE", + "NULL", + "NUMERIC", + "OF", + "ON", + "OPTIMIZE", + "OPTIMIZER_COSTS", + "OPTION", + "OPTIONALLY", + "OR", + "ORDER", + "OUT", + "OUTER", + "OUTFILE", + "OVER", + "PARTITION", + "PERCENT_RANK", + "PERSIST", + "PERSIST_ONLY", + "PRECISION", + "PRIMARY", + "PROCEDURE", + "PURGE", + "RANGE", + "RANK", + "READ", + "READS", + "READ_WRITE", + "REAL", + "RECURSIVE", + "REFERENCES", + "REGEXP", + "RELEASE", + "RENAME", + "REPEAT", + "REPLACE", + "REQUIRE", + "RESIGNAL", + "RESTRICT", + "RETURN", + "REVOKE", + "RIGHT", + "RLIKE", + "ROW", + "ROWS", + "ROW_NUMBER", + "SCHEMA", + "SCHEMAS", + "SECOND_MICROSECOND", + "SELECT", + "SENSITIVE", + "SEPARATOR", + "SET", + "SHOW", + "SIGNAL", + "SMALLINT", + "SPATIAL", + "SPECIFIC", + "SQL", + "SQLEXCEPTION", + "SQLSTATE", + "SQLWARNING", + "SQL_BIG_RESULT", + "SQL_CALC_FOUND_ROWS", + "SQL_SMALL_RESULT", + "SSL", + "STARTING", + "STORED", + "STRAIGHT_JOIN", + "SYSTEM", + "TABLE", + "TERMINATED", + "THEN", + "TINYBLOB", + "TINYINT", + "TINYTEXT", + "TO", + "TRAILING", + "TRIGGER", + "TRUE", + "UNDO", + "UNION", + "UNIQUE", + "UNLOCK", + "UNSIGNED", + "UPDATE", + "USAGE", + "USE", + "USING", + "UTC_DATE", + "UTC_TIME", + "UTC_TIMESTAMP", + "VALUES", + "VARBINARY", + "VARCHAR", + "VARCHARACTER", + "VARYING", + "VIRTUAL", + "WHEN", + "WHERE", + "WHILE", + "WINDOW", + "WITH", + "WRITE", + "XOR", + "YEAR_MONTH", + "ZEROFILL", + }, StringComparer.OrdinalIgnoreCase); + + public override string GetLoadChildrenSubSelect(SqlExpression expr) + { + return $"SELECT * FROM ({base.GetLoadChildrenSubSelect(expr)}) AS SubQuery"; + } + public override string ToPostDropTableStatement(ModelDefinition modelDef) + { + if (modelDef.RowVersion != null) + { + var triggerName = RowVersionTriggerFormat.Fmt(GetTableName(modelDef)); + return "DROP TRIGGER IF EXISTS {0}".Fmt(GetQuotedName(triggerName)); + } + return null; + } + + public override string ToPostCreateTableStatement(ModelDefinition modelDef) + { + if (modelDef.RowVersion != null) + { + var triggerName = RowVersionTriggerFormat.Fmt(modelDef.ModelName); + var triggerBody = "SET NEW.{0} = OLD.{0} + 1;".Fmt( + modelDef.RowVersion.FieldName.SqlColumn(this)); + + var sql = "CREATE TRIGGER {0} BEFORE UPDATE ON {1} FOR EACH ROW BEGIN {2} END;".Fmt( + triggerName, GetTableName(modelDef), triggerBody); + + return sql; + } + + return null; + } + + public override string GetQuotedValue(string paramValue) + { + return "'" + paramValue.Replace("\\", "\\\\").Replace("'", @"\'") + "'"; + } + + public override string GetQuotedValue(object value, Type fieldType) + { + if (value == null) + return "NULL"; + + if (fieldType == typeof(byte[])) + return "0x" + BitConverter.ToString((byte[])value).Replace("-", ""); + + return base.GetQuotedValue(value, fieldType); + } + + public override string GetTableName(string table, string schema = null) => + GetTableName(table, schema, useStrategy:true); + + public override string GetTableName(string table, string schema, bool useStrategy) + { + if (useStrategy) + { + return schema != null && !table.StartsWithIgnoreCase(schema + "_") + ? QuoteIfRequired(NamingStrategy.GetSchemaName(schema) + "_" + NamingStrategy.GetTableName(table)) + : QuoteIfRequired(NamingStrategy.GetTableName(table)); + } + + return schema != null && !table.StartsWithIgnoreCase(schema + "_") + ? QuoteIfRequired(schema + "_" + table) + : QuoteIfRequired(table); + } + + public override bool ShouldQuote(string name) => name != null && + (ReservedWords.Contains(name) || name.IndexOf(' ') >= 0 || name.IndexOf('.') >= 0); + + public override string GetQuotedName(string name) => name == null ? null : name.FirstCharEquals('`') + ? name : '`' + name + '`'; + + public override string GetQuotedTableName(string tableName, string schema = null) + { + return GetQuotedName(GetTableName(tableName, schema)); + } + + public override SqlExpression SqlExpression() + { + return new MySqlExpression(this); + } + + public override string ToTableNamesStatement(string schema) + { + return schema == null + ? "SELECT table_name FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema = DATABASE()" + : "SELECT table_name FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema = DATABASE() AND table_name LIKE {0}".SqlFmt(this, NamingStrategy.GetSchemaName(schema) + "\\_%"); + } + + public override string ToTableNamesWithRowCountsStatement(bool live, string schema) + { + if (live) + return null; + + return schema == null + ? "SELECT table_name, table_rows FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema = DATABASE()" + : "SELECT table_name, table_rows FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema = DATABASE() AND table_name LIKE {0}".SqlFmt(this, NamingStrategy.GetSchemaName(schema) + "\\_%"); + } + + public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) + { + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = {0} AND TABLE_SCHEMA = {1}" + .SqlFmt(GetTableName(tableName, schema).StripDbQuotes(), dbCmd.Connection.Database); + + var result = dbCmd.ExecLongScalar(sql); + + return result > 0; + } + + public override async Task DoesTableExistAsync(IDbCommand dbCmd, string tableName, string schema = null, CancellationToken token=default) + { + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = {0} AND TABLE_SCHEMA = {1}" + .SqlFmt(GetTableName(tableName, schema).StripDbQuotes(), dbCmd.Connection.Database); + + var result = await dbCmd.ExecLongScalarAsync(sql, token); + + return result > 0; + } + + public override bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null) + { + tableName = GetTableName(tableName, schema).StripQuotes(); + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS" + + " WHERE TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = @schema" + .SqlFmt(GetTableName(tableName, schema).StripDbQuotes(), columnName); + + var result = db.SqlScalar(sql, new { tableName, columnName, schema = db.Database }); + + return result > 0; + } + + public override async Task DoesColumnExistAsync(IDbConnection db, string columnName, string tableName, string schema = null, CancellationToken token=default) + { + tableName = GetTableName(tableName, schema).StripQuotes(); + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS" + + " WHERE TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = @schema" + .SqlFmt(GetTableName(tableName, schema).StripDbQuotes(), columnName); + + var result = await db.SqlScalarAsync(sql, new { tableName, columnName, schema = db.Database }, token); + + return result > 0; + } + + public override string ToCreateTableStatement(Type tableType) + { + var sbColumns = StringBuilderCache.Allocate(); + var sbConstraints = StringBuilderCache.Allocate(); + + var modelDef = GetModel(tableType); + foreach (var fieldDef in CreateTableFieldsStrategy(modelDef)) + { + if (fieldDef.CustomSelect != null || (fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; + + if (sbColumns.Length != 0) sbColumns.Append(", \n "); + + sbColumns.Append(GetColumnDefinition(fieldDef)); + + var sqlConstraint = GetCheckConstraint(modelDef, fieldDef); + if (sqlConstraint != null) + { + sbConstraints.Append(",\n" + sqlConstraint); + } + + if (fieldDef.ForeignKey == null || OrmLiteConfig.SkipForeignKeys) + continue; + + var refModelDef = GetModel(fieldDef.ForeignKey.ReferenceType); + sbConstraints.AppendFormat( + ", \n\n CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2} ({3})", + GetQuotedName(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef)), + GetQuotedColumnName(fieldDef.FieldName), + GetQuotedTableName(refModelDef), + GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)); + + if (!string.IsNullOrEmpty(fieldDef.ForeignKey.OnDelete)) + sbConstraints.AppendFormat(" ON DELETE {0}", fieldDef.ForeignKey.OnDelete); + + if (!string.IsNullOrEmpty(fieldDef.ForeignKey.OnUpdate)) + sbConstraints.AppendFormat(" ON UPDATE {0}", fieldDef.ForeignKey.OnUpdate); + } + + var uniqueConstraints = GetUniqueConstraints(modelDef); + if (uniqueConstraints != null) + { + sbConstraints.Append(",\n" + uniqueConstraints); + } + + var sql = $"CREATE TABLE {GetQuotedTableName(modelDef)} \n(\n {StringBuilderCache.ReturnAndFree(sbColumns)}{StringBuilderCacheAlt.ReturnAndFree(sbConstraints)} \n); \n"; + + return sql; + } + + public override bool DoesSchemaExist(IDbCommand dbCmd, string schemaName) + { + // schema is prefixed to table name + return true; + } + + public override string ToCreateSchemaStatement(string schemaName) + { + // https://mariadb.com/kb/en/library/create-database/ + return $"SELECT 1"; + } + + public override string GetColumnDefinition(FieldDefinition fieldDef) + { + if (fieldDef.PropertyInfo?.HasAttributeCached() == true) + { + var sql = StringBuilderCache.Allocate(); + sql.AppendFormat("{0} {1}", GetQuotedName(NamingStrategy.GetColumnName(fieldDef.FieldName)), TextColumnDefinition); + sql.Append(fieldDef.IsNullable ? " NULL" : " NOT NULL"); + return StringBuilderCache.ReturnAndFree(sql); + } + + var ret = base.GetColumnDefinition(fieldDef); + if (fieldDef.IsRowVersion) + return $"{ret} DEFAULT 1"; + + return ret; + } + + public override string SqlConflict(string sql, string conflictResolution) + { + var parts = sql.SplitOnFirst(' '); + return $"{parts[0]} {conflictResolution} {parts[1]}"; + } + + public override string SqlCurrency(string fieldOrValue, string currencySymbol) => + SqlConcat(new[] {$"'{currencySymbol}'", $"cast({fieldOrValue} as decimal(15,2))"}); + + public override string SqlCast(object fieldOrValue, string castAs) => + castAs == Sql.VARCHAR + ? $"CAST({fieldOrValue} AS CHAR(1000))" + : $"CAST({fieldOrValue} AS {castAs})"; + + public override string SqlBool(bool value) => value ? "1" : "0"; + + public override void EnableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("SET FOREIGN_KEY_CHECKS=1;"); + public override Task EnableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) => + cmd.ExecNonQueryAsync("SET FOREIGN_KEY_CHECKS=1;", null, token); + public override void DisableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("SET FOREIGN_KEY_CHECKS=0;"); + public override Task DisableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) => + cmd.ExecNonQueryAsync("SET FOREIGN_KEY_CHECKS=0;", null, token); + + protected DbConnection Unwrap(IDbConnection db) + { + return (DbConnection)db.ToDbConnection(); + } + + protected DbCommand Unwrap(IDbCommand cmd) + { + return (DbCommand)cmd.ToDbCommand(); + } + + protected DbDataReader Unwrap(IDataReader reader) + { + return (DbDataReader)reader; + } + +#if ASYNC + public override Task OpenAsync(IDbConnection db, CancellationToken token = default) + { + return Unwrap(db).OpenAsync(token); + } + + public override Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default) + { + return Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x); + } + + public override Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default) + { + return Unwrap(cmd).ExecuteNonQueryAsync(token); + } + + public override Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default) + { + return Unwrap(cmd).ExecuteScalarAsync(token); + } + + public override Task ReadAsync(IDataReader reader, CancellationToken token = default) + { + return Unwrap(reader).ReadAsync(token); + } + + public override async Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = default) + { + try + { + var to = new List(); + while (await ReadAsync(reader, token).ConfigureAwait(false)) + { + var row = fn(); + to.Add(row); + } + return to; + } + finally + { + reader.Dispose(); + } + } + + public override async Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = default) + { + try + { + while (await ReadAsync(reader, token).ConfigureAwait(false)) + { + fn(); + } + return source; + } + finally + { + reader.Dispose(); + } + } + + public override async Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = default) + { + try + { + if (await ReadAsync(reader, token).ConfigureAwait(false)) + return fn(); + + return default(T); + } + finally + { + reader.Dispose(); + } + } +#endif + + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/MySqlExpression.cs b/src/ServiceStack.OrmLite.MySql/MySqlExpression.cs index a28093ce0..12c52cae8 100644 --- a/src/ServiceStack.OrmLite.MySql/MySqlExpression.cs +++ b/src/ServiceStack.OrmLite.MySql/MySqlExpression.cs @@ -1,11 +1,46 @@ namespace ServiceStack.OrmLite.MySql { - /// - /// Description of MySqlExpressionVisitor. - /// + using System; + using System.Collections.Generic; + using System.Linq.Expressions; public class MySqlExpression : SqlExpression { public MySqlExpression(IOrmLiteDialectProvider dialectProvider) - : base(dialectProvider) {} + : base(dialectProvider) { } + + protected override string ToCast(string quotedColName) + { + return $"cast({quotedColName} as char(1000))"; + } + + public override string ToDeleteRowStatement() + { + return base.tableDefs.Count > 1 + ? $"DELETE {DialectProvider.GetQuotedTableName(modelDef)} {FromExpression} {WhereExpression}" + : base.ToDeleteRowStatement(); + } + + protected override object VisitColumnAccessMethod(MethodCallExpression m) + { + if (m.Method.Name == nameof(ToString) && m.Object?.Type == typeof(DateTime)) + { + List args = this.VisitExpressionList(m.Arguments); + var quotedColName = Visit(m.Object); + if (!IsSqlClass(quotedColName)) + quotedColName = ConvertToParam(quotedColName); + + var statement = ""; + var arg = args.Count > 0 ? args[0] : null; + if (arg == null) statement = ToCast(quotedColName.ToString()); + else statement = $"DATE_FORMAT({quotedColName.ToString()},'{arg.ToString()}')"; + return new PartialSqlString(statement); + } + return base.VisitColumnAccessMethod(m); + } + + protected override string CreateInSubQuerySql(object quotedColName, string subSelect) + { + return $"{quotedColName} IN (SELECT * FROM ({subSelect}) SubQuery)"; + } } } diff --git a/src/ServiceStack.OrmLite.MySql/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.MySql/Properties/AssemblyInfo.cs index 85a5604a2..22ae012d6 100644 --- a/src/ServiceStack.OrmLite.MySql/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite.MySql/Properties/AssemblyInfo.cs @@ -1,25 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.MySql")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.MySql")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a47c24c1-27c2-443c-a1bf-b88d25aa3fc9")] - -[assembly: AssemblyVersion("4.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.Core.csproj b/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.Core.csproj new file mode 100644 index 000000000..244e15e7d --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.Core.csproj @@ -0,0 +1,22 @@ + + + + ServiceStack.OrmLite.MySql.Core + ServiceStack.OrmLite.MySql + ServiceStack.OrmLite.MySql + netstandard2.0;net6.0 + ServiceStack.OrmLite.MySql .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite.MySql + + MySQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.Source.csproj b/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.Source.csproj new file mode 100644 index 000000000..0142e6c85 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.Source.csproj @@ -0,0 +1,23 @@ + + + + ServiceStack.OrmLite.MySql + ServiceStack.OrmLite.MySql + netstandard2.0;net6.0 + OrmLite.MySql - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for MySQL. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in MySQL. + + MySQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + false + $(DefineConstants);ASYNC + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.csproj b/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.csproj index e023726da..ce17b5d78 100644 --- a/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.csproj +++ b/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySql.csproj @@ -1,96 +1,27 @@ - - + + - Debug - AnyCPU - 8.0.30703 - 2.0 - {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5} - Library - Properties - ServiceStack.OrmLite.MySql + ServiceStack.OrmLite.MySql ServiceStack.OrmLite.MySql - 512 - v4.0 - - ..\ - true + net472;netstandard2.0;net6.0 + OrmLite.MySql - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for MySQL. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in MySQL. + + MySQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - False - ..\packages\MySql.Data.6.9.5\lib\net40\MySql.Data.dll - - - False - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - + - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - + + + - - - + + + + - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file + + diff --git a/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySqlV45.csproj b/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySqlV45.csproj deleted file mode 100644 index 64fcd74c5..000000000 --- a/src/ServiceStack.OrmLite.MySql/ServiceStack.OrmLite.MySqlV45.csproj +++ /dev/null @@ -1,99 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {1BCE2206-A9F9-4381-B4F7-F617998447A1} - Library - Properties - ServiceStack.OrmLite.MySql - ServiceStack.OrmLite.MySql - 512 - v4.5 - - ..\ - true - - - true - full - false - bin\net45_Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\net45\ - TRACE;NET45 - prompt - 4 - false - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - - False - ..\packages\MySql.Data.6.9.3\lib\net45\MySql.Data.dll - - - False - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - - - - - - - - {fdc37335-9ecc-413b-bec5-16b466b0e689} - ServiceStack.OrmLiteV45 - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql/app.config b/src/ServiceStack.OrmLite.MySql/app.config index f9b2ac342..53058308e 100644 --- a/src/ServiceStack.OrmLite.MySql/app.config +++ b/src/ServiceStack.OrmLite.MySql/app.config @@ -4,6 +4,6 @@ - + diff --git a/src/ServiceStack.OrmLite.MySql/packages.config b/src/ServiceStack.OrmLite.MySql/packages.config deleted file mode 100644 index b89751538..000000000 --- a/src/ServiceStack.OrmLite.MySql/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySqlConnector/Converters/MySqlDateTimeConverter.cs b/src/ServiceStack.OrmLite.MySqlConnector/Converters/MySqlDateTimeConverter.cs new file mode 100644 index 000000000..1e46e80b6 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySqlConnector/Converters/MySqlDateTimeConverter.cs @@ -0,0 +1,6 @@ +namespace ServiceStack.OrmLite.MySql.Converters +{ + public class MySqlConnectorDateTimeConverter : MySqlDateTimeConverterBase + { + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySqlConnector/MySqlConnectorDialect.cs b/src/ServiceStack.OrmLite.MySqlConnector/MySqlConnectorDialect.cs new file mode 100644 index 000000000..169b4a874 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySqlConnector/MySqlConnectorDialect.cs @@ -0,0 +1,9 @@ +using ServiceStack.OrmLite.MySql; + +namespace ServiceStack.OrmLite +{ + public static class MySqlConnectorDialect + { + public static IOrmLiteDialectProvider Provider => MySqlConnectorDialectProvider.Instance; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySqlConnector/MySqlConnectorDialectProvider.cs b/src/ServiceStack.OrmLite.MySqlConnector/MySqlConnectorDialectProvider.cs new file mode 100644 index 000000000..0eeca2152 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySqlConnector/MySqlConnectorDialectProvider.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Data; +using MySqlConnector; +using ServiceStack.OrmLite.MySql.Converters; + +namespace ServiceStack.OrmLite.MySql +{ + public class MySqlConnectorDialectProvider : MySqlDialectProviderBase + { + public static MySqlConnectorDialectProvider Instance = new MySqlConnectorDialectProvider(); + + private const string TextColumnDefinition = "TEXT"; + + public MySqlConnectorDialectProvider() + { + base.RegisterConverter(new MySqlConnectorDateTimeConverter()); + } + + public override IDbConnection CreateConnection(string connectionString, Dictionary options) + { + return new MySqlConnection(connectionString); + } + + public override IDbDataParameter CreateParam() + { + return new MySqlParameter(); + } + + } +} diff --git a/src/ServiceStack.OrmLite.MySqlConnector/ServiceStack.OrmLite.MySqlConnector.Core.csproj b/src/ServiceStack.OrmLite.MySqlConnector/ServiceStack.OrmLite.MySqlConnector.Core.csproj new file mode 100644 index 000000000..327f4571e --- /dev/null +++ b/src/ServiceStack.OrmLite.MySqlConnector/ServiceStack.OrmLite.MySqlConnector.Core.csproj @@ -0,0 +1,35 @@ + + + ServiceStack.OrmLite.MySqlConnector.Core + ServiceStack.OrmLite.MySqlConnector + ServiceStack.OrmLite.MySqlConnector + netstandard2.0;net6.0 + ServiceStack.OrmLite.MySql + ServiceStack.OrmLite.MySqlConnector .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite.MySqlConnector + + MySqlConnector;MySQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySqlConnector/ServiceStack.OrmLite.MySqlConnector.csproj b/src/ServiceStack.OrmLite.MySqlConnector/ServiceStack.OrmLite.MySqlConnector.csproj new file mode 100644 index 000000000..7f90b9ca9 --- /dev/null +++ b/src/ServiceStack.OrmLite.MySqlConnector/ServiceStack.OrmLite.MySqlConnector.csproj @@ -0,0 +1,35 @@ + + + net472;netstandard2.0;net6.0 + ServiceStack.OrmLite.MySqlConnector + ServiceStack.OrmLite.MySqlConnector + ServiceStack.OrmLite.MySql + OrmLite.MySqlConnector - Fast, code-first, config-free POCO ORM + + MySQL Adapter for ServiceStack OrmLite using MySqlConnector ADO.NET Provider + + MySqlConnector;MySQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySqlV45/ServiceStack.OrmLite.MySqlV45.csproj b/src/ServiceStack.OrmLite.MySqlV45/ServiceStack.OrmLite.MySqlV45.csproj deleted file mode 100644 index e3f2fed87..000000000 --- a/src/ServiceStack.OrmLite.MySqlV45/ServiceStack.OrmLite.MySqlV45.csproj +++ /dev/null @@ -1,110 +0,0 @@ - - - - - Debug - AnyCPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6} - Library - Properties - ServiceStack.OrmLite.MySql - ServiceStack.OrmLite.MySql - v4.5 - 512 - ..\ - true - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET45 - prompt - 4 - - - bin\Signed\ - TRACE;NET45 - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - False - ..\packages\MySql.Data.6.9.5\lib\net45\MySql.Data.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - DataAnnotations\TextAttribute.cs - - - MySqlDialect.cs - - - MySqlDialectProvider.cs - - - MySqlExpression.cs - - - AssemblyInfo.cs - - - - - - - - - - - - {fdc37335-9ecc-413b-bec5-16b466b0e689} - ServiceStack.OrmLiteV45 - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySqlV45/app.config b/src/ServiceStack.OrmLite.MySqlV45/app.config deleted file mode 100644 index d8f423dab..000000000 --- a/src/ServiceStack.OrmLite.MySqlV45/app.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySqlV45/packages.config b/src/ServiceStack.OrmLite.MySqlV45/packages.config deleted file mode 100644 index 9ac31173e..000000000 --- a/src/ServiceStack.OrmLite.MySqlV45/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/ForeignKeyAttributeTests.cs b/src/ServiceStack.OrmLite.Oracle.Tests/ForeignKeyAttributeTests.cs deleted file mode 100644 index 061ed5cb9..000000000 --- a/src/ServiceStack.OrmLite.Oracle.Tests/ForeignKeyAttributeTests.cs +++ /dev/null @@ -1,300 +0,0 @@ -using System; -using System.Data; -using System.Linq; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class ForeignKeyAttributeTests : OrmLiteTestBase - { - [TestFixtureSetUp] - public void Setup() - { - using (var dbConn = OpenDbConnection()) - { - DropTables(dbConn); - - dbConn.DropAndCreateTable(); - } - } - - private void DropTables(IDbConnection dbConnection) - { - if (dbConnection.TableExists("TWODUC")) dbConnection.DropTable(); - if (dbConnection.TableExists("TWODSN")) dbConnection.DropTable(); - if (dbConnection.TableExists("TWODDF")) dbConnection.DropTable(); - if (dbConnection.TableExists("TWODNR")) dbConnection.DropTable(); - if (dbConnection.TableExists("TWODNA")) dbConnection.DropTable(); - if (dbConnection.TableExists("TWODC")) dbConnection.DropTable(); - if (dbConnection.TableExists("TWSKF")) dbConnection.DropTable(); - if (dbConnection.TableExists("TWONFKI")) dbConnection.DropTable(); - } - - [Test] - public void CanCreateSimpleForeignKey() - { - using (var dbConnection = OpenDbConnection()) - { - dbConnection.DropAndCreateTable(); - } - } - - [Test] - public void ForeignWithOnDeleteCascadeCreatesOk() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } - } - - [Test] - public void ForeignWithOnDeleteCascadeWorks() - { - using (var dbConnection = OpenDbConnection()) - { - dbConnection.DropAndCreateTable(); - - dbConnection.Save(new ReferencedType { Id = 1 }); - dbConnection.Save(new TypeWithOnDeleteCascade { RefId = 1 }); - - Assert.AreEqual(1, dbConnection.Select().Count); - Assert.AreEqual(1, dbConnection.Select().Count); - - dbConnection.Delete(r => r.Id == 1); - - Assert.AreEqual(0, dbConnection.Select().Count); - Assert.AreEqual(0, dbConnection.Select().Count); - } - } - - [Test] - public void ForeignWithOnDeleteCascadeAndOnUpdateCascadeCreatesOk() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } - } - - [Test] - public void ForeignWithOnDeleteNoActionCreatesOk() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } - } - - [Test] - public void ForeignWithOnDeleteNoActionThrowsException() - { - using (var dbConnection = OpenDbConnection()) - { - dbConnection.CreateTableIfNotExists(); - - dbConnection.Save(new ReferencedType { Id = 1 }); - dbConnection.Save(new TypeWithOnDeleteNoAction { RefId = 1 }); - - Assert.AreEqual(1, dbConnection.Select().Count); - Assert.AreEqual(1, dbConnection.Select().Count); - - // Do not want to require reference to dll with exception definition so use catch - Assert.Catch(() => dbConnection.Delete(r => r.Id == 1)); - } - } - - [Test] - public void ForeignWithOnDeleteRestrictCreatesOk() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } - } - - [Test] - public void ForeignWithOnDeleteRestrictThrowsException() - { - using (var dbConnection = OpenDbConnection()) - { - dbConnection.CreateTableIfNotExists(); - - dbConnection.Save(new ReferencedType { Id = 1 }); - dbConnection.Save(new TypeWithOnDeleteRestrict { RefId = 1 }); - - Assert.AreEqual(1, dbConnection.Select().Count); - Assert.AreEqual(1, dbConnection.Select().Count); - - // Do not want to require reference to dll with exception definition so use catch - Assert.Catch(() => dbConnection.Delete(r => r.Id == 1)); - } - } - - [Test] - public void ForeignWithOnDeleteSetDefaultCreatesOk() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } - } - - [Test] - public void ForeignWithOnDeleteSetDefaultThrowsException() - { - using (var dbConnection = OpenDbConnection()) - { - dbConnection.CreateTableIfNotExists(); - - dbConnection.Save(new ReferencedType { Id = 1 }); - dbConnection.Save(new TypeWithOnDeleteSetDefault { RefId = 1 }); - - Assert.AreEqual(1, dbConnection.Select().Count); - Assert.AreEqual(1, dbConnection.Select().Count); - - // Do not want to require reference to dll with exception definition so use catch - Assert.Catch(() => dbConnection.Delete(r => r.Id == 1)); - } - } - - [Test] - public void ForeignWithOnDeleteSetNullCreatesOk() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } - } - - [Test] - public void ForeignWithOnDeleteSetNullWorks() - { - using (var dbConnection = OpenDbConnection()) - { - DropTables(dbConnection); - - dbConnection.CreateTableIfNotExists(); - - dbConnection.Save(new ReferencedType { Id = 1 }); - dbConnection.Save(new TypeWithOnDeleteSetNull { RefId = 1 }); - - Assert.AreEqual(1, dbConnection.Select().Count); - Assert.AreEqual(1, dbConnection.Select().Count); - - dbConnection.Delete(r => r.Id == 1); - - Assert.AreEqual(0, dbConnection.Select().Count); - var row = dbConnection.Select().First(); - Assert.That(row.RefId, Is.Null); - } - } - - [Test, NUnit.Framework.Ignore("Base implementation does not allow provider override so cannot work in Oracle")] - public void CanDropForeignKey() - { - using (var dbConnection = OpenDbConnection()) - { - dbConnection.DropAndCreateTable(); - dbConnection.DropForeignKey("FK_DNA"); - } - } - - [Test] - public void CanAddForeignKey() - { - using (var dbConnection = OpenDbConnection()) - { - dbConnection.DropAndCreateTable(); - dbConnection.AddForeignKey( - t => t.RefId, tr => tr.Id, OnFkOption.NoAction, OnFkOption.Cascade, "FK_ADDED"); - } - } - } - - public class ReferencedType - { - public int Id { get; set; } - } - - [Alias("TWSKF")] - public class TypeWithSimpleForeignKey - { - [AutoIncrement] - public int Id { get; set; } - [References(typeof(ReferencedType))] - public int RefId { get; set; } - } - - [Alias("TWODC")] - public class TypeWithOnDeleteCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", ForeignKeyName="FK_DC")] - public int? RefId { get; set; } - } - - [Alias("TWODUC")] - public class TypeWithOnDeleteAndUpdateCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE", ForeignKeyName="FK_DC_UC")] - public int? RefId { get; set; } - } - - [Alias("TWODNA")] - public class TypeWithOnDeleteNoAction - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION", ForeignKeyName="FK_DNA")] - public int? RefId { get; set; } - } - - [Alias("TWODNR")] - public class TypeWithOnDeleteRestrict - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT", ForeignKeyName="FK_DR")] - public int? RefId { get; set; } - } - - [Alias("TWODDF")] - public class TypeWithOnDeleteSetDefault - { - [AutoIncrement] - public int Id { get; set; } - - [Default(typeof(int), "17")] - [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT", ForeignKeyName="FK_DDF")] - public int RefId { get; set; } - } - - [Alias("TWODSN")] - public class TypeWithOnDeleteSetNull - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL", ForeignKeyName="FK_SN")] - public int? RefId { get; set; } - } - - [Alias("TWONFKI")] - public class TypeWithNoForeignKeyInitially - { - [AutoIncrement] - public int Id { get; set; } - - public int? RefId { get; set; } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/OracleParamTests.cs b/src/ServiceStack.OrmLite.Oracle.Tests/OracleParamTests.cs deleted file mode 100644 index ffab86a81..000000000 --- a/src/ServiceStack.OrmLite.Oracle.Tests/OracleParamTests.cs +++ /dev/null @@ -1,596 +0,0 @@ -using System; -using System.Data; -using System.Linq; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class OracleParamTests : OrmLiteTestBase - { - private void DropAndCreateTables(IDbConnection db) - { - if (db.TableExists("ParamRelBO")) - db.DropTable(); - - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - } - - [Test] - public void ORA_ParamTestInsert() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - var dateTimeNow =new DateTime( DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); - - db.Insert(new ParamTestBo { Id = 1, Double = 0.001, Int = 100, Info = "One", NullableBool = null, DateTime = dateTimeNow }); - db.Insert(new ParamTestBo { Id = 2, Double = 0.002, Int = 200, Info = "Two", NullableBool = true, DateTime = dateTimeNow }); - db.Insert(new ParamTestBo { Id = 3, Double = 0.003, Int = 300, Info = "Three", NullableBool = false, DateTime = dateTimeNow.AddDays(23) }); - db.Insert(new ParamTestBo { Id = 4, Double = 0.004, Int = 400, Info = "Four", NullableBool = null }); - - var bo1 = db.Select(q => q.Id == 1).Single(); - var bo2 = db.Select(q => q.Id == 2).Single(); - var bo3 = db.Select(q => q.Id == 3).Single(); - var bo4 = db.Select(q => q.Id == 4).Single(); - - Assert.AreEqual(1, bo1.Id); - Assert.AreEqual(2, bo2.Id); - Assert.AreEqual(3, bo3.Id); - Assert.AreEqual(4, bo4.Id); - - Assert.AreEqual(0.001, bo1.Double); - Assert.AreEqual(0.002, bo2.Double); - Assert.AreEqual(0.003, bo3.Double); - Assert.AreEqual(0.004, bo4.Double); - - Assert.AreEqual(100, bo1.Int); - Assert.AreEqual(200, bo2.Int); - Assert.AreEqual(300, bo3.Int); - Assert.AreEqual(400, bo4.Int); - - Assert.AreEqual("One", bo1.Info); - Assert.AreEqual("Two", bo2.Info); - Assert.AreEqual("Three", bo3.Info); - Assert.AreEqual("Four", bo4.Info); - - Assert.AreEqual(null, bo1.NullableBool); - Assert.AreEqual(true, bo2.NullableBool); - Assert.AreEqual(false, bo3.NullableBool); - Assert.AreEqual(null, bo4.NullableBool); - - Assert.AreEqual(dateTimeNow, bo1.DateTime); - Assert.AreEqual(dateTimeNow, bo2.DateTime); - Assert.AreEqual(dateTimeNow.AddDays(23), bo3.DateTime); - Assert.AreEqual(null, bo4.DateTime); - } - } - - [Test] - public void ORA_ParamTestUpdate() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var bo1 = new ParamTestBo { Id = 1, Double = 0.001, Int = 100, Info = "One", NullableBool = true }; - var bo2 = new ParamTestBo { Id = 2, Double = 0.002, Int = 200, Info = "Two", NullableBool = true, DateTime = DateTime.Now }; - db.Insert(bo1); - db.Insert(bo2); - - bo1.Double = 0.01; - bo1.Int = 10000; - bo1.Info = "OneUpdated"; - bo1.NullableBool = null; - bo1.DateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); - - db.Update(bo1); - - var bo1Check = db.SingleById(1); - - Assert.AreEqual(bo1.Double, bo1Check.Double); - Assert.AreEqual(bo1.Int, bo1Check.Int); - Assert.AreEqual(bo1.Info, bo1Check.Info); - Assert.AreEqual(bo1.DateTime, bo1Check.DateTime); - - - Assert.GreaterOrEqual(DateTime.Now, bo2.DateTime); - - bo2.Info = "TwoUpdated"; - bo2.Int = 9923; - bo2.NullableBool = false; - bo2.DateTime = DateTime.Now.AddDays(10); - - db.Update(bo2); - - var bo2Check = db.SingleById(2); - - Assert.Less(DateTime.Now, bo2.DateTime); - Assert.AreEqual("TwoUpdated", bo2Check.Info); - Assert.AreEqual(9923, bo2Check.Int); - Assert.AreEqual(false, bo2Check.NullableBool); - } - } - - [Test] - public void ORA_ParamTestDelete() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - db.Insert(new ParamTestBo { Id = 1 }); - db.Insert(new ParamTestBo { Id = 2 }); - db.Insert(new ParamTestBo { Id = 3 }); - - Assert.IsNotNull(db.Select(q => q.Id == 1).FirstOrDefault()); - Assert.IsNotNull(db.Select(q => q.Id == 2).FirstOrDefault()); - Assert.IsNotNull(db.Select(q => q.Id == 3).FirstOrDefault()); - - db.DeleteById(1); - db.DeleteById(2); - db.DeleteById(3); - - Assert.IsNull(db.Select(q => q.Id == 1).FirstOrDefault()); - Assert.IsNull(db.Select(q => q.Id == 2).FirstOrDefault()); - Assert.IsNull(db.Select(q => q.Id == 3).FirstOrDefault()); - } - } - - [Test] - public void ORA_ParamTestGetById() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - db.Insert(new ParamTestBo { Id = 1, Info = "Item1" }); - db.Insert(new ParamTestBo { Id = 2, Info = "Item2" }); - db.Insert(new ParamTestBo { Id = 3, Info = "Item3" }); - - Assert.AreEqual("Item1", db.SingleById(1).Info); - Assert.AreEqual("Item2", db.SingleById(2).Info); - Assert.AreEqual("Item3", db.SingleById(3).Info); - } - } - - [Test] - public void ORA_ParamTestSelectLambda() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - LoadParamTestBo(db); - - //select multiple items - Assert.AreEqual(2, db.Select(q => q.NullableBool == null).Count); - Assert.AreEqual(2, db.Select(q => q.NullableBool == null).Count); - Assert.AreEqual(1, db.Select(q => q.NullableBool == true).Count); - Assert.AreEqual(1, db.Select(q => q.NullableBool == false).Count); - - Assert.AreEqual(1, db.Select(q => q.Info == "Two").Count); - Assert.AreEqual(1, db.Select(q => q.Int == 300).Count); - Assert.AreEqual(1, db.Select(q => q.Double == 0.003).Count); - } - } - - private void LoadParamTestBo(IDbConnection db) - { - db.Insert(new ParamTestBo { Id = 1, Double = 0.001, Int = 100, Info = "One", NullableBool = null }); - db.Insert(new ParamTestBo { Id = 2, Double = 0.002, Int = 200, Info = "Two", NullableBool = true }); - db.Insert(new ParamTestBo { Id = 3, Double = 0.003, Int = 300, Info = "Three", NullableBool = false }); - db.Insert(new ParamTestBo { Id = 4, Double = 0.004, Int = 400, Info = "Four", NullableBool = null }); - } - - [Test] - public void ORA_ParamTestSelectLambda2() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - LoadParamTestBo(db); - LoadParamRelBo(db); - - Assert.AreEqual(8, db.Select(q => q.Info == "T1").Count); - Assert.AreEqual(2, db.Select(q => q.Info == "T2").Count); - - Assert.AreEqual(3, db.Select(q => q.Info == "T1" && (q.PtId == 2 || q.PtId == 3) ).Count); - } - } - - private void LoadParamRelBo(IDbConnection db) - { - db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 2, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 2, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 3, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 4, Info = "T1" }); - db.Insert(new ParamRelBo { PtId = 3, Info = "T2" }); - db.Insert(new ParamRelBo { PtId = 4, Info = "T2" }); - } - - [Test] - public void ORA_ParamTestSelectLambdaComplex() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - LoadParamTestBo(db); - LoadParamRelBo(db); - - Assert.AreEqual(10, db.Select(q => Sql.In(q.Info, "T1", "T2")).Count); - Assert.AreEqual(10, db.Select(q => q.Info.StartsWith("T")).Count); - Assert.AreEqual(8, db.Select(q => q.Info.EndsWith("1")).Count); - Assert.AreEqual(10, db.Select(q => q.Info.Contains("T")).Count); - } - } - - [Test] - public void ORA_ParamByteTest() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - db.DeleteAll(); - var bo1 = new ParamByteBo { Id = 1, Data = new byte[] { 1, 25, 43, 3, 1, 66, 82, 23, 11, 44, 66, 22, 52, 62, 76, 19, 30, 91, 4 } }; - - db.Insert(bo1); - var bo1Check = db.Select(s => s.Id == bo1.Id).Single(); - - Assert.AreEqual(bo1.Id, bo1Check.Id); - Assert.AreEqual(bo1.Data, bo1Check.Data); - - db.DeleteAll(); - } - } - - [Test] - public void ORA_ReservedNameComment_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamComment { Comment = 1, Id = 2 }; - db.Insert(row); - - row.Comment = 454; - db.Update(row); - } - } - - - [Test] - public void ORA_ReservedNameLeft_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamLeft { Id = 2, Left = 3 }; - db.Insert(row); - - row.Left = 454; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameOrder_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamOrder { Id = 2, Order = 4 }; - db.Insert(row); - - row.Order = 67; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameUser_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamUser { Id = 2, User = 5 }; - db.Insert(row); - - row.User = 35; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNamePassword_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamPassword { Id = 2, Password = 6 }; - db.Insert(row); - - row.Password = 335; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameActive_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamActive { Id = 2, Active = 7 }; - db.Insert(row); - - row.Active = 454; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameDouble_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamDouble { Id = 2, Double = 8 }; - db.Insert(row); - - row.Double = 4876554; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameFloat_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamFloat { Id = 2, Float = 9 }; - db.Insert(row); - - row.Float = 798; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameDecimal_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamDecimal { Id = 2, Decimal = 10 }; - db.Insert(row); - - row.Decimal = 454; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameString_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamString { Id = 2, String = 11 }; - db.Insert(row); - - row.String = 234234; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameDate_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamDate { Id = 2, Date = 12 }; - db.Insert(row); - - row.Date = 826; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameDateTime_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamDateTime { Id = 2, DateTime = 13 }; - db.Insert(row); - - row.DateTime = 327895; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameType_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamType { Id = 2, Type = 5 }; - db.Insert(row); - - row.Type = 454; - db.Update(row); - } - } - - [Test] - public void ORA_ReservedNameTimestamp_Test() - { - using (var db = OpenDbConnection()) - { - DropAndCreateTables(db); - - var row = new ParamTimestamp { Id = 2, Timestamp = 27 }; - db.Insert(row); - - row.Timestamp = 28454; - db.Update(row); - } - } - - public class ParamTestBo - { - public int Id { get; set; } - public string Info { get; set; } - public int Int { get; set; } - public double Double { get; set; } - public bool? NullableBool { get; set; } - public DateTime? DateTime { get; set; } - } - - - public class ParamRelBo - { - [Sequence("SEQ_PARAMTESTREL_ID")] - [PrimaryKey] - [Alias("ParamRel_Id")] - public int Id { get; set; } - [ForeignKey(typeof(ParamTestBo))] - public int PtId { get; set; } - - [Alias("InfoStr")] - public string Info { get; set; } - } - - public class ParamByteBo - { - public int Id { get; set; } - public byte[] Data { get; set; } - } - - public class ParamComment - { - public int Id { get; set; } - public int Comment { get; set; } - } - - public class ParamOrder - { - public int Id { get; set; } - public int Order { get; set; } - } - - public class ParamLeft - { - public int Id { get; set; } - public int Left { get; set; } - } - - public class ParamUser - { - public int Id { get; set; } - public int User { get; set; } - } - - public class ParamPassword - { - public int Id { get; set; } - public int Password { get; set; } - } - - public class ParamActive - { - public int Id { get; set; } - public int Active { get; set; } - } - - public class ParamDouble - { - public int Id { get; set; } - public int Double { get; set; } - } - - public class ParamFloat - { - public int Id { get; set; } - public int Float { get; set; } - } - - public class ParamDecimal - { - public int Id { get; set; } - public int Decimal { get; set; } - } - - public class ParamString - { - public int Id { get; set; } - public int String { get; set; } - } - - public class ParamDate - { - public int Id { get; set; } - public int Date { get; set; } - } - - public class ParamDateTime - { - public int Id { get; set; } - public int DateTime { get; set; } - } - - public class ParamType - { - public int Id { get; set; } - public int Type { get; set; } - } - - public class ParamTimestamp - { - public int Id { get; set; } - public int Timestamp { get; set; } - } - } -} diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/OrmLiteTestBase.cs b/src/ServiceStack.OrmLite.Oracle.Tests/OrmLiteTestBase.cs deleted file mode 100644 index 32b221050..000000000 --- a/src/ServiceStack.OrmLite.Oracle.Tests/OrmLiteTestBase.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Configuration; -using System.Data; -using NUnit.Framework; -using ServiceStack.Logging; -using ServiceStack.OrmLite.Oracle; - -namespace ServiceStack.OrmLite.Tests -{ - public class Config - { - public static IDbConnection OpenDbConnection() - { - var testBase = new OrmLiteTestBase - { - DbFactory = new OrmLiteConnectionFactory( - ConfigurationManager.ConnectionStrings["testDb"].ConnectionString, - OracleDialect.Provider) - }; - return testBase.OpenDbConnection(); - } - } - - public class OrmLiteTestBase - { - protected virtual string ConnectionString { get; set; } - - protected virtual string GetFileConnectionString() - { - return ConfigurationManager.ConnectionStrings["testDb"].ConnectionString; - } - - protected void CreateNewDatabase() - { - ConnectionString = GetFileConnectionString(); - } - - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - LogManager.LogFactory = new ConsoleLogFactory(); - - OrmLiteConfig.DialectProvider = OracleDialect.Provider; - OrmLiteConfig.ClearCache(); - ConnectionString = GetFileConnectionString(); - DbFactory = new OrmLiteConnectionFactory(ConnectionString, OracleDialect.Provider); - } - - public void Log(string text) - { - Console.WriteLine(text); - } - - public Dialect Dialect = Dialect.Oracle; - public OrmLiteConnectionFactory DbFactory; - - public virtual IDbConnection OpenDbConnection() - { - return DbFactory.OpenDbConnection(); - } - - protected void SuppressIfOracle(string reason, params object[] args) - { - Assert.Ignore(reason, args); - } - } -} diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Oracle.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 353af5ae8..000000000 --- a/src/ServiceStack.OrmLite.Oracle.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.Oracle.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.Oracle.Tests")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("98a76291-26c2-4012-aeef-ab688752d30b")] - diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj b/src/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj deleted file mode 100644 index 66e3e61f2..000000000 --- a/src/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj +++ /dev/null @@ -1,431 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {DE5CA3EB-010D-492A-A0B7-501D7941FA51} - Library - Properties - ServiceStack.OrmLite.Oracle.Tests - ServiceStack.OrmLite.Oracle.Tests - v4.5 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AnyCPU - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - - ..\..\lib\tests\Northwind.Common.dll - - - ..\..\lib\tests\Northwind.Perf.dll - - - False - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\ServiceStack.dll - - - ..\..\lib\ServiceStack.Client.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - False - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - CaptureSqlFilterTests.cs - - - CompositeKeyTests.cs - - - CustomSqlTests.cs - - - DateTimeOffsetTests.cs - - - EnumTests.cs - - - ExpressionVisitorTests.cs - - - Expression\AdditiveExpressionsTest.cs - - - Expression\ComplexJoinTests.cs - - - Expression\ConditionalExpressionTest.cs - - - Expression\EqualityExpressionsTest.cs - - - Expression\ExpressionChainingUseCase.cs - - - Expression\ExpressionsTestBase.cs - - - Expression\ExpressionUsingCustomSerializedEnumTests.cs - - - Expression\FromExpressionTests.cs - - - Expression\GenericTableExpressions.cs - - - Expression\LogicalExpressionsTest.cs - - - Expression\MethodExpressionTests.cs - - - Expression\MultiplicativeExpressionsTest.cs - - - Expression\OrmLiteCountTests.cs - - - Expression\PrimaryExpressionsTest.cs - - - Expression\RelationalExpressionsTest.cs - - - Expression\SelectExpressionTests.cs - - - Expression\SqlExpressionTests.cs - - - Expression\StringFunctionTests.cs - - - Expression\TestType.cs - - - Expression\UnaryExpressionsTest.cs - - - Issues\ComplexJoinWithAlias.cs - - - Issues\MismatchSchemaTests.cs - - - Issues\MultiFieldReferenceTests.cs - - - Issues\MultithreadingIssueTests.cs - - - Issues\SchemaTests.cs - - - Issues\SelectDistinctTests.cs - - - Issues\SelectIntoTests.cs - - - JoinSqlBuilderTests.cs - - - LoadReferencesJoinTests.cs - - - LoadReferencesTests.cs - - - LocalizationTests.cs - - - MockAllApiTests.cs - - - MultipleConnectionIdTests.cs - - - OrmLiteBasicPersistenceProviderTests.cs - - - OrmLiteComplexTypesTests.cs - - - OrmLiteCreateTableTests.cs - - - OrmLiteCreateTableWithIndexesTests.cs - - - OrmLiteCreateTableWithNamingStrategyTest.cs - - - OrmLiteDeleteTests.cs - - - OrmLiteDropTableTests.cs - - - OrmLiteDropTableWithNamingStrategyTests.cs - - - OrmLiteExecFilterTests.cs - - - OrmLiteFiltersTests.cs - - - OrmLiteGetScalarTests.cs - - - OrmLiteInsertTests.cs - - - OrmLiteQueryTests.cs - - - OrmLiteSaveTests.cs - - - OrmLiteSelectTests.cs - - - OrmLiteUpdateTests.cs - - - OrmLiteUtilExtensionsTests.cs - - - PerfTests.cs - - - RowVersionTests.cs - - - Shared\ApiUtilExtensions.cs - - - Shared\BuiltInsFactory.cs - - - Shared\IModelFactory.cs - - - Shared\ModelFactoryBase.cs - - - Shared\ModelWithComplexTypes.cs - - - Shared\ModelWithComplexTypesFactory.cs - - - Shared\ModelWithCompositeIndexFields.cs - - - Shared\ModelWithFieldsOfDifferentAndNullableTypes.cs - - - Shared\ModelWithFieldsOfDifferentAndNullableTypesFactory.cs - - - Shared\ModelWithFieldsOfDifferentTypes.cs - - - Shared\ModelWithFieldsOfDifferentTypesFactory.cs - - - Shared\ModelWithFieldsOfNullableTypes.cs - - - Shared\ModelWithFieldsOfNullableTypesFactory.cs - - - Shared\ModelWithIdAndName.cs - - - Shared\ModelWithIdOnly.cs - - - Shared\ModelWithIndexFields.cs - - - Shared\ModelWithLongIdAndStringFields.cs - - - Shared\ModelWithMapAndList.cs - - - Shared\ModelWithNamedCompositeIndex.cs - - - Shared\ModelWithNumerics.cs - - - Shared\ModelWithOnlyStringFields.cs - - - Shared\Movie.cs - - - Shared\Person.cs - - - Shared\Poco.cs - - - Shared\SampleOrderLine.cs - - - Shared\Shipper.cs - - - Shared\ShipperFactory.cs - - - Shared\TaskQueue.cs - - - ShippersExample.cs - - - SqlBuilderTests.cs - - - SqlFormatTests.cs - - - StringSerializerTests.cs - - - TestHelpers.cs - - - TypeDescriptorMetadataTests.cs - - - TypeWithByteArrayFieldTests.cs - - - UntypedApiTests.cs - - - UseCase\AliasedFieldUseCase.cs - - - UseCase\CustomerOrdersUseCase.cs - - - UseCase\FieldFromInterfaceImplementationUseCase.cs - - - UseCase\ImageBlobDto.cs - - - UseCase\NestedComplexTypeUseCase.cs - - - UseCase\ServiceStack_OrmLite_UseCase.cs - - - UseCase\SimpleUseCase.cs - - - Properties\GlobalAssemblyInfo.cs - - - Component - - - - - Code - - - - - - - - - {517B64BA-D7A6-4A15-8719-821B38147C61} - ServiceStack.OrmLite.Oracle - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - Designer - - - - - UseCase\ImageBlobResource.resx - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/WrappedCommandTests.cs b/src/ServiceStack.OrmLite.Oracle.Tests/WrappedCommandTests.cs deleted file mode 100644 index b347c304f..000000000 --- a/src/ServiceStack.OrmLite.Oracle.Tests/WrappedCommandTests.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Data; -using System.Data.Common; -using NUnit.Framework; -using ServiceStack.MiniProfiler; -using ServiceStack.MiniProfiler.Data; -using ServiceStack.OrmLite.Oracle; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class WrappedCommandTests : OrmLiteTestBase - { - [Test] - public void WrappingWithMiniProfilerSucceeds() - { - var factory = new OrmLiteConnectionFactory(ConnectionString, OracleDialect.Provider) - { - ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current) - }; - - using (var db = factory.OpenDbConnection()) - { - DoInsertUpdate(db); - } - } - - private static void DoInsertUpdate(IDbConnection db) - { - db.CreateTable(true); - - var row = new ParamPassword { Id = 2, Password = 6 }; - db.Insert(row); - - row.Password = 335; - db.Update(row); - } - - [Test] - public void WrappingWithSpecializedMiniProfilerSucceeds() - { - var factory = new OrmLiteConnectionFactory(ConnectionString, OracleDialect.Provider) - { - ConnectionFilter = x => new SpecializedProfiledDbConnection(x, Profiler.Current) - }; - - using (var db = factory.OpenDbConnection()) - { - DoInsertUpdate(db); - } - } - } - - public class ParamPassword - { - public int Id { get; set; } - public int Password { get; set; } - } - - public class SpecializedProfiledDbConnection : ProfiledDbConnection - { - public SpecializedProfiledDbConnection(DbConnection connection, IDbProfiler profiler, bool autoDisposeConnection = true) - : base(connection, profiler, autoDisposeConnection) - { } - - public SpecializedProfiledDbConnection(IDbConnection connection, IDbProfiler profiler, bool autoDisposeConnection = true) - : base(connection, profiler, autoDisposeConnection) - { } - - protected override DbCommand CreateDbCommand() - { - return new SpecializedProfiledDbCommand(InnerConnection.CreateCommand(), InnerConnection, Profiler); - } - } - - public class SpecializedProfiledDbCommand : ProfiledDbCommand - { - public SpecializedProfiledDbCommand(DbCommand cmd, DbConnection conn, IDbProfiler profiler) - : base(cmd, conn, profiler) - { } - } -} diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/app.config b/src/ServiceStack.OrmLite.Oracle.Tests/app.config deleted file mode 100644 index 04047c406..000000000 --- a/src/ServiceStack.OrmLite.Oracle.Tests/app.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleBoolConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleBoolConverter.cs new file mode 100644 index 000000000..b2b59f4ea --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleBoolConverter.cs @@ -0,0 +1,18 @@ +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleBoolConverter : BoolAsIntConverter + { + public override string ColumnDefinition + { + get { return "NUMBER(1)"; } + } + + public override DbType DbType + { + get { return DbType.Int16; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleByteArrayConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleByteArrayConverter.cs new file mode 100644 index 000000000..b85fe1198 --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleByteArrayConverter.cs @@ -0,0 +1,13 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleByteArrayConverter : ByteArrayConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + return "hextoraw('" + BitConverter.ToString((byte[])value).Replace("-", "") + "')"; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleCharArrayConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleCharArrayConverter.cs new file mode 100644 index 000000000..423fa437c --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleCharArrayConverter.cs @@ -0,0 +1,27 @@ +using System; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleCharArrayConverter : OracleStringConverter + { + public OracleCharArrayConverter() : base(4000) {} + + public override object ToDbValue(Type fieldType, object value) + { + var chars = (char[])value; + return new string(chars); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is char[]) + return value; + + var strValue = value as string; + if (strValue != null) + return strValue.ToCharArray(); + + return (char[])value; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleDateTimeConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleDateTimeConverter.cs new file mode 100644 index 000000000..6b8ef447f --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleDateTimeConverter.cs @@ -0,0 +1,23 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleDateTimeConverter : DateTimeConverter + { + public override string ColumnDefinition + { + get { return "TIMESTAMP"; } + } + + public OracleOrmLiteDialectProvider OracleDialect + { + get { return (OracleOrmLiteDialectProvider)DialectProvider;} + } + + public override string ToQuotedString(Type fieldType, object value) + { + return OracleDialect.GetQuotedDateTimeValue((DateTime)value); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleDateTimeOffsetConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleDateTimeOffsetConverter.cs new file mode 100644 index 000000000..1d38c8647 --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleDateTimeOffsetConverter.cs @@ -0,0 +1,48 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + //TODO: Custom DateTimeOffset logic from DialectProvider should be moved here + public class OracleDateTimeOffsetConverter : DateTimeOffsetConverter + { + private OracleTimestampConverter _timestampConverter; + + public OracleDateTimeOffsetConverter(OracleTimestampConverter timestampConverter) + { + _timestampConverter = timestampConverter; + } + + public override string ColumnDefinition + { + get { return "TIMESTAMP WITH TIME ZONE"; } + } + + public OracleOrmLiteDialectProvider OracleDialect + { + get { return (OracleOrmLiteDialectProvider)DialectProvider; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + return OracleDialect.GetQuotedDateTimeOffsetValue((DateTimeOffset)value); + } + + public override object ToDbValue(Type fieldType, object value) + { + var timestamp = (DateTimeOffset)value; + return _timestampConverter.ConvertToOracleTimeStampTz(timestamp); + } + + public override object FromDbValue(Type fieldType, object value) + { + return Convert.ChangeType(value, typeof(DateTimeOffset)); + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + _timestampConverter.SetParameterTimeStampTzType(p); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleEnumConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleEnumConverter.cs new file mode 100644 index 000000000..eb8d20613 --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleEnumConverter.cs @@ -0,0 +1,75 @@ +using System; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleEnumConverter : EnumConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + if (fieldType.HasAttributeCached()) + { + return this.ConvertNumber(fieldType.GetEnumUnderlyingType(), value).ToString(); + } + + if (value is int && !fieldType.IsEnumFlags()) + { + value = fieldType.GetEnumName(value); + } + + if (fieldType.IsEnum) + { + var enumValue = DialectProvider.StringSerializer.SerializeToString(value); + // Oracle stores empty strings in varchar columns as null so match that behavior here + if (enumValue == null) + return null; + enumValue = DialectProvider.GetQuotedValue(enumValue.Trim('"')); + return enumValue == "''" + ? "null" + : enumValue; + } + return base.ToQuotedString(fieldType, value); + } + + public override object ToDbValue(Type fieldType, object value) + { + if (value is int && !fieldType.IsEnumFlags()) + { + value = fieldType.GetEnumName(value); + } + + if (fieldType.HasAttributeCached()) + { + if (value is string) + { + value = Enum.Parse(fieldType, value.ToString()); + } + return (int) value; + } + + var enumValue = DialectProvider.StringSerializer.SerializeToString(value); + // Oracle stores empty strings in varchar columns as null so match that behavior here + if (enumValue == null) + return null; + enumValue = enumValue.Trim('"'); + return enumValue == "" + ? null + : enumValue; + } + + public override object FromDbValue(Type fieldType, object value) + { + return base.FromDbValue(fieldType, GetDbValue(fieldType, value)); + } + + private static object GetDbValue(Type fieldType, object value) + { + if (!fieldType.IsEnum) return value; + + var oracleValue = value as OracleValue; + + return oracleValue == null ? value : Convert.ToInt32(value); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleFloatConverters.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleFloatConverters.cs new file mode 100644 index 000000000..5c6c9312c --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleFloatConverters.cs @@ -0,0 +1,48 @@ +using System; +using System.Globalization; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleFloatConverter : FloatConverter + { + public override string ColumnDefinition + { + get { return "FLOAT"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var s = ((float)value).ToString(CultureInfo.InvariantCulture); + if (s.Length > 20) s = s.Substring(0, 20); + return "'" + s + "'"; // when quoted exception is more clear! + } + } + + public class OracleDoubleConverter : DoubleConverter + { + public override string ColumnDefinition + { + get { return "FLOAT"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var s = ((double)value).ToString(CultureInfo.InvariantCulture); + if (s.Length > 20) s = s.Substring(0, 20); + return "'" + s + "'"; // when quoted exception is more clear! + } + } + + public class OracleDecimalConverter : DecimalConverter + { + public OracleDecimalConverter() : base(18, 12) {} + + public override string ToQuotedString(Type fieldType, object value) + { + var s = ((decimal)value).ToString(CultureInfo.InvariantCulture); + if (s.Length > 20) s = s.Substring(0, 20); + return "'" + s + "'"; // when quoted exception is more clear! + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleGuidConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleGuidConverter.cs new file mode 100644 index 000000000..26d9e97e7 --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleGuidConverter.cs @@ -0,0 +1,65 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleGuidConverter : GuidConverter + { + public override string ColumnDefinition + { + get { return "VARCHAR2(37)"; } + } + + public override DbType DbType + { + get { return DbType.String; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var guid = (Guid)value; + return string.Format("CAST('{0}' AS {1})", guid, ColumnDefinition); + } + + public override object ToDbValue(Type fieldType, object value) + { + return ((Guid)value).ToString(); + } + + public override object FromDbValue(Type fieldType, object value) + { + return new Guid(value.ToString()); + } + } + + public class OracleCompactGuidConverter : GuidConverter + { + public override string ColumnDefinition + { + get { return "RAW(16)"; } + } + + public override DbType DbType + { + get { return DbType.Binary; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var guid = (Guid)value; + return string.Format("CAST('{0}' AS {1})", BitConverter.ToString(guid.ToByteArray()).Replace("-", ""), ColumnDefinition); + } + + public override object ToDbValue(Type fieldType, object value) + { + return ((Guid)value).ToByteArray(); + } + + public override object FromDbValue(Type fieldType, object value) + { + var raw = (byte[])value; + return new Guid(raw); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleIntegerConverters.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleIntegerConverters.cs new file mode 100644 index 000000000..058faf63d --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleIntegerConverters.cs @@ -0,0 +1,55 @@ +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleInt64Converter : Int64Converter + { + public override string ColumnDefinition + { + get { return "NUMERIC(18)"; } + } + } + + public class OracleSByteConverter : SByteConverter + { + public override DbType DbType + { + get { return DbType.Byte; } + } + } + + public class OracleUInt16Converter : UInt16Converter + { + public override DbType DbType + { + get { return DbType.Decimal; } + } + } + + public class OracleUInt32Converter : UInt32Converter + { + public override DbType DbType + { + get { return DbType.Decimal; } + } + + public override string ColumnDefinition + { + get { return "NUMERIC(18)"; } + } + } + + public class OracleUInt64Converter : UInt64Converter + { + public override DbType DbType + { + get { return DbType.Decimal; } + } + + public override string ColumnDefinition + { + get { return "NUMERIC(18)"; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleStringConverters.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleStringConverters.cs new file mode 100644 index 000000000..9d16a07b7 --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleStringConverters.cs @@ -0,0 +1,55 @@ +using System; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleStringConverter : StringConverter + { + public OracleStringConverter() : base(4000) {} + + protected OracleStringConverter(int stringLength) : base(stringLength) + { + } + + public override string MaxColumnDefinition => UseUnicode ? "NVARCHAR2(2000)" : "NVARCHAR2(4000)"; + + public override int MaxVarCharLength => UseUnicode ? 2000 : 4000; + + public override string GetColumnDefinition(int? stringLength) + { + if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText) + return MaxColumnDefinition; + + var safeLength = Math.Min(stringLength.GetValueOrDefault(StringLength), UseUnicode ? 2000 : 4000); + + return UseUnicode + ? $"NVARCHAR({safeLength})" + : $"VARCHAR({safeLength})"; + } + } + + /// + /// + /// + public class Oracle12StringConverter : StringConverter + { + public Oracle12StringConverter() : base(32767) {} + + public override string MaxColumnDefinition => UseUnicode ? "NVARCHAR2(16383)" : "NVARCHAR2(32767)"; + + public override int MaxVarCharLength => UseUnicode ? 16383 : 32767; + + public override string GetColumnDefinition(int? stringLength) + { + if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText) + return MaxColumnDefinition; + + var safeLength = Math.Min(stringLength.GetValueOrDefault(StringLength), UseUnicode ? 16383 : 32767); + + return UseUnicode + ? $"NVARCHAR({safeLength})" + : $"VARCHAR({safeLength})"; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Converters/OracleTimeSpanAsIntConverter.cs b/src/ServiceStack.OrmLite.Oracle/Converters/OracleTimeSpanAsIntConverter.cs new file mode 100644 index 000000000..129776ccc --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Converters/OracleTimeSpanAsIntConverter.cs @@ -0,0 +1,12 @@ +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Oracle.Converters +{ + public class OracleTimeSpanAsIntConverter : TimeSpanAsIntConverter + { + public override string ColumnDefinition + { + get { return "NUMERIC(18)"; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/OraSchema/Schema.cs b/src/ServiceStack.OrmLite.Oracle/OraSchema/Schema.cs index f3770431a..771632313 100644 --- a/src/ServiceStack.OrmLite.Oracle/OraSchema/Schema.cs +++ b/src/ServiceStack.OrmLite.Oracle/OraSchema/Schema.cs @@ -4,6 +4,7 @@ using System.Text; using System.Data; using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Legacy; using ServiceStack.OrmLite.Oracle.DbSchema; namespace ServiceStack.OrmLite.Oracle diff --git a/src/ServiceStack.OrmLite.Oracle/Oracle10OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Oracle/Oracle10OrmLiteDialectProvider.cs new file mode 100644 index 000000000..580ee2afe --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Oracle10OrmLiteDialectProvider.cs @@ -0,0 +1,50 @@ +namespace ServiceStack.OrmLite.Oracle +{ + using System; + using ServiceStack.DataAnnotations; + using ServiceStack.Model; + using ServiceStack.OrmLite.Dapper; + using ServiceStack.OrmLite.Oracle.Converters; + + /// + /// Oracle v11 specific provider + /// + public class Oracle11OrmLiteDialectProvider : OracleOrmLiteDialectProvider + { + public new static Oracle11OrmLiteDialectProvider Instance = new Oracle11OrmLiteDialectProvider(); + + protected new const int MaxNameLength = 128; + + public Oracle11OrmLiteDialectProvider() + { + NamingStrategy = new OracleNamingStrategy(MaxNameLength); + + RegisterConverter(new Oracle12StringConverter()); + } + + + // Column level collation (case-insensitive) + // Case insensitive db (collation) + // AL32UTF8 default char set + + // Change to VARCHAR2, NVARCHAR2, and RAW Datatypes to max string size 32767 + // Json support + // GeoJson - https://docs.oracle.com/en/database/oracle/oracle-database/12.2/spatl/spatial-concepts.html#GUID-D703DF4D-57D1-4990-8F53-CAAA9C8FCB2F + + // CAST returns user-specified value if conversion error https://docs.oracle.com/en/database/oracle/oracle-database/12.2/newft/new-features.html#GUID-03517A06-2AA8-4EE5-9A20-B76E519EB69C + // VALIDATE_CONVERSION function + // LISTAGG overflow facility + // Identifiers (table/field names) increase from 30 bytes to 128 bytes + + // IDENTITY cols in table definition (ints only) + // CREATE TABLE SEQ_TABLE2 (NO NUMBER GENERATED AS IDENTITY (START WITH 10 INCREMENT BY 5), NAME VARCHAR2(100)); + // + + // Change to paging + // SELECT ENAME, SAL + // FROM EMP + // ORDER BY SAL DESC + // OFFSET 2 ROWS + // FETCH FIRST 5 ROWS ONLY; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/Oracle18OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Oracle/Oracle18OrmLiteDialectProvider.cs new file mode 100644 index 000000000..3e2c90cbb --- /dev/null +++ b/src/ServiceStack.OrmLite.Oracle/Oracle18OrmLiteDialectProvider.cs @@ -0,0 +1,13 @@ +namespace ServiceStack.OrmLite.Oracle +{ + /// + /// Oracle 18 specific provider + /// + public class Oracle18OrmLiteDialectProvider : Oracle11OrmLiteDialectProvider + { + public new static Oracle18OrmLiteDialectProvider Instance = new Oracle18OrmLiteDialectProvider(); + + // JSON enhancements - https://docs.oracle.com/en/database/oracle/oracle-database/18/newft/new-features.html#GUID-82224A33-A394-4C21-ADB1-712092A15F62 + // GEO SPACIAL enhancements - + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/OracleDialect.cs b/src/ServiceStack.OrmLite.Oracle/OracleDialect.cs index 127f2f2b6..6bc5f582a 100644 --- a/src/ServiceStack.OrmLite.Oracle/OracleDialect.cs +++ b/src/ServiceStack.OrmLite.Oracle/OracleDialect.cs @@ -1,7 +1,10 @@ -namespace ServiceStack.OrmLite.Oracle +using ServiceStack.OrmLite.Oracle; + +namespace ServiceStack.OrmLite { public class OracleDialect { - public static IOrmLiteDialectProvider Provider { get { return OracleOrmLiteDialectProvider.Instance; } } + public static IOrmLiteDialectProvider Provider => OracleOrmLiteDialectProvider.Instance; + public static OracleOrmLiteDialectProvider Instance => OracleOrmLiteDialectProvider.Instance; } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/OracleNamingStrategy.cs b/src/ServiceStack.OrmLite.Oracle/OracleNamingStrategy.cs index 7ccd5a45f..519ca2529 100644 --- a/src/ServiceStack.OrmLite.Oracle/OracleNamingStrategy.cs +++ b/src/ServiceStack.OrmLite.Oracle/OracleNamingStrategy.cs @@ -41,8 +41,8 @@ public override string ApplyNameRestrictions(string name) public override string GetTableName(ModelDefinition modelDef) { return modelDef.IsInSchema - ? ApplyNameRestrictions(modelDef.Schema - + "_" + GetTableName(modelDef.ModelName)) + ? ApplyNameRestrictions(modelDef.Schema) + + "." + ApplyNameRestrictions(GetTableName(modelDef.ModelName)) : GetTableName(modelDef.ModelName); } diff --git a/src/ServiceStack.OrmLite.Oracle/OracleOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Oracle/OracleOrmLiteDialectProvider.cs index 0da6dd104..839ebfc1b 100644 --- a/src/ServiceStack.OrmLite.Oracle/OracleOrmLiteDialectProvider.cs +++ b/src/ServiceStack.OrmLite.Oracle/OracleOrmLiteDialectProvider.cs @@ -7,40 +7,56 @@ using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using Oracle.ManagedDataAccess.Client; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; +using ServiceStack.OrmLite.Oracle.Converters; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Oracle { public class OracleOrmLiteDialectProvider : OrmLiteDialectProviderBase { - public const string OdpProvider = "Oracle.DataAccess.Client"; - public const string MicrosoftProvider = "System.Data.OracleClient"; + public const string ManagedProvider = "Oracle.ManagedDataAccess.Client"; + public string AutoIdGuidFunction { get; set; } = "SYS_GUID()"; + public bool UseReturningForLastInsertId { get; set; } = true; + + public static readonly OracleOrmLiteDialectProvider Instance = new OracleOrmLiteDialectProvider(); + public static string RowVersionTriggerFormat = "{0}RowVersionUpdateTrigger"; + // TODO refactor to hashset (case insensitive protected readonly List ReservedNames = new List { - "USER", "ORDER", "PASSWORD", "ACTIVE", "LEFT", "DOUBLE", "FLOAT", "DECIMAL", "STRING", "DATE", - "DATETIME", "TYPE","TIMESTAMP", "COMMENT", "LONG", "INDEX" - }; + "ACCESS", "DEFAULT", "INTEGER", "ONLINE", "START", "ADD", "DELETE", "INTERSECT", "OPTION", "SUCCESSFUL", "ALL", "DESC", + "INTO", "OR", "SYNONYM", "ALTER", "DISTINCT", "IS", "ORDER", "SYSDATE", "AND", "DROP", "LEVEL", "PCTFREE", "TABLE", "ANY", + "ELSE", "LIKE", "PRIOR", "THEN", "AS", "EXCLUSIVE", "LOCK", "PRIVILEGES", "TO", "ASC", "EXISTS", "LONG", "PUBLIC", "TRIGGER", + "AUDIT", "FILE", "MAXEXTENTS", "RAW", "UID", "BETWEEN", "FLOAT", "MINUS", "RENAME", "UNION", "BY", "FOR", "MLSLABEL", "RESOURCE", + "UNIQUE", "CHAR", "FROM", "MODE", "REVOKE", "UPDATE", "CHECK", "GRANT", "MODIFY", "ROW", "USER", "CLUSTER", "GROUP", "NOAUDIT", + "ROWID", "VALIDATE", "COLUMN", "HAVING", "NOCOMPRESS", "ROWNUM", "VALUES", "COMMENT", "IDENTIFIED", "NOT", "ROWS", "VARCHAR", + "COMPRESS", "IMMEDIATE", "NOWAIT", "SELECT", "VARCHAR2", "CONNECT", "IN", "NULL", "SESSION", "VIEW", "CREATE", "INCREMENT", + "NUMBER", "SET", "WHENEVER", "CURRENT", "INDEX", "OF", "SHARE", "WHERE", "DATE", "INITIAL", "OFFLINE", "SIZE", "WITH", "DECIMAL", + "INSERT", "ON", "SMALLINT", "PASSWORD", "ACTIVE", "LEFT", "DOUBLE", "STRING", "DATETIME", "TYPE", "TIMESTAMP", + "BYTE", "SHORT", "INT", "SUBTYPE" + }; + // TODO refactor to hashset (case insensitive protected readonly List ReservedParameterNames = new List { - "COMMENT", "DATE", "DECIMAL", "FLOAT", "ORDER", "USER", "LONG", "INDEX" + "ACCESS", "DEFAULT", "INTEGER", "ONLINE", "START", "ADD", "DELETE", "INTERSECT", "OPTION", "SUCCESSFUL", "ALL", "DESC", + "INTO", "OR", "SYNONYM", "ALTER", "DISTINCT", "IS", "ORDER", "SYSDATE", "AND", "DROP", "LEVEL", "PCTFREE", "TABLE", "ANY", + "ELSE", "LIKE", "PRIOR", "THEN", "AS", "EXCLUSIVE", "LOCK", "PRIVILEGES", "TO", "ASC", "EXISTS", "LONG", "PUBLIC", "TRIGGER", + "AUDIT", "FILE", "MAXEXTENTS", "RAW", "UID", "BETWEEN", "FLOAT", "MINUS", "RENAME", "UNION", "BY", "FOR", "MLSLABEL", "RESOURCE", + "UNIQUE", "CHAR", "FROM", "MODE", "REVOKE", "UPDATE", "CHECK", "GRANT", "MODIFY", "ROW", "USER", "CLUSTER", "GROUP", "NOAUDIT", + "ROWID", "VALIDATE", "COLUMN", "HAVING", "NOCOMPRESS", "ROWNUM", "VALUES", "COMMENT", "IDENTIFIED", "NOT", "ROWS", "VARCHAR", + "COMPRESS", "IMMEDIATE", "NOWAIT", "SELECT", "VARCHAR2", "CONNECT", "IN", "NULL", "SESSION", "VIEW", "CREATE", "INCREMENT", + "NUMBER", "SET", "WHENEVER", "CURRENT", "INDEX", "OF", "SHARE", "WHERE", "DATE", "INITIAL", "OFFLINE", "SIZE", "WITH", "DECIMAL", + "INSERT", "ON", "SMALLINT", + "BYTE", "SHORT", "INT", "SUBTYPE" }; + internal long LastInsertId { get; set; } protected const int MaxNameLength = 30; protected const int MaxStringColumnLength = 4000; - - private static OracleOrmLiteDialectProvider _instance; - public static OracleOrmLiteDialectProvider Instance - { - // Constructing extras if we happen to hit this concurrently on separate threads is harmless enough - get { return _instance ?? (_instance = new OracleOrmLiteDialectProvider()); } - } - - protected bool CompactGuid; - - internal const string StringGuidDefinition = "VARCHAR2(37)"; - internal const string CompactGuidDefinition = "RAW(16)"; - private readonly DbProviderFactory _factory; private readonly OracleTimestampConverter _timestampConverter; @@ -49,80 +65,89 @@ public OracleOrmLiteDialectProvider() { } - public OracleOrmLiteDialectProvider(bool compactGuid, bool quoteNames, string clientProvider = OdpProvider) + public OracleOrmLiteDialectProvider(bool compactGuid, bool quoteNames, string clientProvider = ManagedProvider) { - ClientProvider = clientProvider; - CompactGuid = compactGuid; + // Make managed provider work with CaptureSqlFilter, safe since Oracle providers don't support async + OrmLiteContext.UseThreadStatic = true; + // Not nice to slow down, but need to read some types via Oracle-specific read methods so can't read all fields in single call + OrmLiteConfig.DeoptimizeReader = true; + QuoteNames = quoteNames; - BoolColumnDefinition = "NUMBER(1)"; - GuidColumnDefinition = CompactGuid ? CompactGuidDefinition : StringGuidDefinition; - LongColumnDefinition = "NUMERIC(18)"; AutoIncrementDefinition = string.Empty; - DateTimeColumnDefinition = "TIMESTAMP"; - DateTimeOffsetColumnDefinition = "TIMESTAMP WITH TIME ZONE"; - TimeColumnDefinition = LongColumnDefinition; - RealColumnDefinition = "FLOAT"; - // Order-dependency here: must set following values before setting DefaultStringLength - StringLengthNonUnicodeColumnDefinitionFormat = "VARCHAR2({0})"; - StringLengthUnicodeColumnDefinitionFormat = "NVARCHAR2({0})"; - MaxStringColumnDefinition = StringLengthNonUnicodeColumnDefinitionFormat.Fmt(MaxStringColumnLength); - DefaultStringLength = 128; - InitColumnTypeMap(); ParamString = ":"; - + NamingStrategy = new OracleNamingStrategy(MaxNameLength); ExecFilter = new OracleExecFilter(); - _factory = DbProviderFactories.GetFactory(ClientProvider); - _timestampConverter = new OracleTimestampConverter(_factory.GetType()); - } - - public override void OnAfterInitColumnTypeMap() - { - base.OnAfterInitColumnTypeMap(); + _factory = OracleClientFactory.Instance; +#if !NETFRAMEWORK + // TODO tune settings + //OracleConfiguration.FetchSize = 1024 * 1024; + //OracleConfiguration.SelfTuning = false; + OracleConfiguration.BindByName = true; + OracleConfiguration.CommandTimeout = OrmLiteConfig.CommandTimeout; + //OracleConfiguration.StatementCacheSize = -1; + //OracleConfiguration.SendBufferSize = 8192; + //OracleConfiguration.ReceiveBufferSize = 8192; + //OracleConfiguration.DisableOOB = true; + //OracleConfiguration.OnsMode = OnsConfigMode.Unspecified; + OracleConfiguration.TraceOption = 1; + //OracleConfiguration.TraceLevel = 7; + //OracleConfiguration.TcpNoDelay = true; + OracleConfiguration.TraceFileLocation = "c:\\temp\\ora"; +#endif + + _timestampConverter = new OracleTimestampConverter(_factory.GetType(), clientProvider); - DbTypeMap.Set(DbType.Int16, BoolColumnDefinition); - DbTypeMap.Set(DbType.Int16, BoolColumnDefinition); + InitColumnTypeMap(); - DbTypeMap.Set(DbType.Int16, IntColumnDefinition); - DbTypeMap.Set(DbType.Int16, IntColumnDefinition); - DbTypeMap.Set(DbType.Int32, IntColumnDefinition); - DbTypeMap.Set(DbType.Int32, IntColumnDefinition); - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); + //Special Converters if you need to override default behavior + base.EnumConverter = new OracleEnumConverter(); - if (CompactGuid) - { - DbTypeMap.Set(DbType.Binary, GuidColumnDefinition); - DbTypeMap.Set(DbType.Binary, GuidColumnDefinition); - } + if (compactGuid) + RegisterConverter(new OracleCompactGuidConverter()); else - { - DbTypeMap.Set(DbType.String, GuidColumnDefinition); - DbTypeMap.Set(DbType.String, GuidColumnDefinition); - } + RegisterConverter(new OracleGuidConverter()); - DbTypeMap.Set(DbType.String, DateTimeOffsetColumnDefinition); - DbTypeMap.Set(DbType.String, DateTimeOffsetColumnDefinition); - } + RegisterConverter(new OracleTimeSpanAsIntConverter()); + RegisterConverter(new OracleStringConverter()); + RegisterConverter(new OracleCharArrayConverter()); + RegisterConverter(new OracleByteArrayConverter()); - protected string ClientProvider = OdpProvider; - public static string RowVersionTriggerFormat = "{0}RowVersionUpdateTrigger"; + RegisterConverter(new OracleInt64Converter()); + RegisterConverter(new OracleSByteConverter()); + RegisterConverter(new OracleUInt16Converter()); + RegisterConverter(new OracleUInt32Converter()); + RegisterConverter(new OracleUInt64Converter()); + + RegisterConverter(new OracleFloatConverter()); + RegisterConverter(new OracleDoubleConverter()); + RegisterConverter(new OracleDecimalConverter()); + + RegisterConverter(new OracleDateTimeConverter()); + RegisterConverter(new OracleDateTimeOffsetConverter(_timestampConverter)); + RegisterConverter(new OracleBoolConverter()); + + this.Variables = new Dictionary + { + { OrmLiteVariables.SystemUtc, "sys_extract_utc(systimestamp)" }, + { OrmLiteVariables.MaxText, $"VARCHAR2({MaxStringColumnLength})" }, + { OrmLiteVariables.MaxTextUnicode, $"NVARCHAR2({MaxStringColumnLength / 2})" }, + { OrmLiteVariables.True, SqlBool(true) }, + { OrmLiteVariables.False, SqlBool(false) }, + }; + } public override string ToPostCreateTableStatement(ModelDefinition modelDef) { if (modelDef.RowVersion != null) { - var triggerName = NamingStrategy.ApplyNameRestrictions( - RowVersionTriggerFormat.Fmt(modelDef.ModelName)); - var triggerBody = ":NEW.{0} := :OLD.{0}+1;".Fmt( - modelDef.RowVersion.FieldName.SqlColumn(this)); + var triggerName = NamingStrategy.ApplyNameRestrictions(RowVersionTriggerFormat.Fmt(modelDef.ModelName)); + var sqlColumn = modelDef.RowVersion.FieldName.SqlColumn(this); + var triggerBody = $":NEW.{sqlColumn} := :OLD.{sqlColumn}+1;"; - var sql = "CREATE TRIGGER {0} BEFORE UPDATE ON {1} FOR EACH ROW BEGIN {2} END;".Fmt( - Quote(triggerName), NamingStrategy.GetTableName(modelDef), triggerBody); + var sql = $"CREATE TRIGGER {Quote(triggerName)} BEFORE UPDATE ON {NamingStrategy.GetTableName(modelDef)} FOR EACH ROW BEGIN {triggerBody} END;"; return sql; } @@ -135,7 +160,7 @@ public override IDbConnection CreateConnection(string connectionString, Dictiona { if (options != null) { - connectionString = options.Aggregate(connectionString, (current, option) => current + (option.Key + "=" + option.Value + ";")); + connectionString = options.Aggregate(connectionString, (current, option) => $"{current}{option.Key}={option.Value};"); } var connection = _factory.CreateConnection(); @@ -145,161 +170,102 @@ public override IDbConnection CreateConnection(string connectionString, Dictiona public override long GetLastInsertId(IDbCommand dbCmd) { - throw new NotSupportedException(); + return LastInsertId; } - public override long InsertAndGetLastInsertId(IDbCommand dbCmd) + public override object ToDbValue(object value, Type type) { - dbCmd.ExecuteScalar(); - - var modelDef = GetModel(typeof(T)); - - var primaryKey = modelDef.PrimaryKey; - if (primaryKey == null) - return 0; - - var identityParameter = (DbParameter)dbCmd.Parameters[this.GetParam(SanitizeFieldNameForParamName(primaryKey.FieldName))]; - if (identityParameter == null) - return 0; - - return Convert.ToInt64(identityParameter.Value); - } + if (value == null || value is DBNull) + return null; - public override void SetDbValue(FieldDefinition fieldDef, IDataReader reader, int colIndex, object instance) - { - if (OrmLiteUtils.HandledDbNullValue(fieldDef, reader, colIndex, instance)) return; + if (type.IsEnum && !type.HasAttributeCached()) + return EnumConverter.ToDbValue(type, value); - var value = reader.GetValue(colIndex); - var convertedValue = ConvertDbValue(value, fieldDef.FieldType); + if (type.IsRefType()) + return ReferenceTypeConverter.ToDbValue(type, value); + IOrmLiteConverter converter = null; try { - fieldDef.SetValueFn(instance, convertedValue); - } - catch (NullReferenceException ex) - { - Log.Warn("Unexpected NullReferenceException", ex); - } - } - - public override object ConvertDbValue(object value, Type type) - { - if (value == null || value is DBNull) return null; - - if (type == typeof (DateTimeOffset)) - { - return Convert.ChangeType(value, type); - } - - if (type == typeof(bool)) - return Convert.ToBoolean(value); - - if (type == typeof(Guid)) - { - if (CompactGuid) + if (Converters.TryGetValue(type, out converter)) { - var raw = (byte[])value; - return new Guid(raw); + if (type == typeof(DateTimeOffset)) + { + return converter.ToQuotedString(type, value); + } + + return converter.ToDbValue(type, value); } - return new Guid(value.ToString()); } - - if (type == typeof(byte[])) - return value; - - if (type == typeof(TimeSpan)) + catch (Exception ex) { - var ticks = long.Parse(value.ToString()); - return TimeSpan.FromTicks(ticks); + Log.Error($"Error in {converter?.GetType().Name}.ToDbValue() value '{value.GetType().Name}' and Type '{type.Name}'", ex); + throw; } - return base.ConvertDbValue(value, type); + return base.ToDbValue(value, type); } - public override string GetQuotedValue(object value, Type fieldType) - { - if (value == null) return "NULL"; + const string IsoDateFormat = "yyyy-MM-dd"; + const string IsoTimeFormat = "HH:mm:ss"; + const string IsoMillisecondFormat = "fffffff"; + const string IsoTimeZoneFormat = "zzz"; + const string OracleDateFormat = "YYYY-MM-DD"; + const string OracleTimeFormat = "HH24:MI:SS"; + const string OracleMillisecondFormat = "FF9"; + const string OracleTimeZoneFormat = "TZH:TZM"; - if (fieldType == typeof(Guid)) - { - var guid = (Guid)value; - return CompactGuid ? "'" + BitConverter.ToString(guid.ToByteArray()).Replace("-", "") + "'" - : string.Format("CAST('{0}' AS {1})", guid, StringGuidDefinition); - } - - if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?)) - { - var dateValue = (DateTime)value; - string iso8601Format = "yyyy-MM-dd"; - string oracleFormat = "YYYY-MM-DD"; - if (dateValue.ToString("yyyy-MM-dd HH:mm:ss.fff").EndsWith("00:00:00.000") == false) - { - iso8601Format = "yyyy-MM-dd HH:mm:ss.fff"; - oracleFormat = "YYYY-MM-DD HH24:MI:SS.FF3"; - } - return "TO_TIMESTAMP(" + base.GetQuotedValue(dateValue.ToString(iso8601Format), typeof(string)) + ", " + base.GetQuotedValue(oracleFormat, typeof(string)) + ")"; - } - - if ((value is TimeSpan) && (fieldType == typeof(Int64) || fieldType == typeof(Int64?))) - { - var longValue = ((TimeSpan)value).Ticks; - return base.GetQuotedValue(longValue, fieldType); - } - - if (fieldType == typeof(bool?) || fieldType == typeof(bool)) - { - var boolValue = (bool)value; - return base.GetQuotedValue(boolValue ? "1" : "0", typeof(string)); - } - - if (fieldType == typeof(decimal?) || fieldType == typeof(decimal) || - fieldType == typeof(double?) || fieldType == typeof(double) || - fieldType == typeof(float?) || fieldType == typeof(float)) - { - var s = base.GetQuotedValue(value, fieldType); - if (s.Length > 20) s = s.Substring(0, 20); - return "'" + s + "'"; // when quoted exception is more clear! - } + internal string GetQuotedDateTimeOffsetValue(DateTimeOffset dateValue) + { + var iso8601Format = $"{GetIsoDateTimeFormat(dateValue.TimeOfDay)} {IsoTimeZoneFormat}"; + var oracleFormat = $"{GetOracleDateTimeFormat(dateValue.TimeOfDay)} {OracleTimeZoneFormat}"; + return string.Format("TO_TIMESTAMP_TZ({0}, {1})", base.GetQuotedValue(dateValue.ToString(iso8601Format), typeof(string)), base.GetQuotedValue(oracleFormat, typeof(string))); + } - if (fieldType.IsEnum) - { - if (value is int && !fieldType.IsEnumFlags()) - { - value = fieldType.GetEnumName(value); - } + internal string GetQuotedDateTimeValue(DateTime dateValue) + { + var iso8601Format = GetIsoDateTimeFormat(dateValue.TimeOfDay); + var oracleFormat = GetOracleDateTimeFormat(dateValue.TimeOfDay); + return string.Format("TO_TIMESTAMP({0}, {1})", base.GetQuotedValue(dateValue.ToString(iso8601Format), typeof(string)), base.GetQuotedValue(oracleFormat, typeof(string))); + } - var enumValue = StringSerializer.SerializeToString(value); - // Oracle stores empty strings in varchar columns as null so match that behavior here - if (enumValue == null) - return null; - enumValue = GetQuotedValue(enumValue.Trim('"')); - return enumValue == "''" - ? "null" - : enumValue; - } + private string GetIsoDateTimeFormat(TimeSpan timeOfDay) + { + return GetTimeFormat(timeOfDay, IsoDateFormat, IsoTimeFormat, IsoMillisecondFormat); + } - if (fieldType == typeof(byte[])) - { - return "hextoraw('" + BitConverter.ToString((byte[])value).Replace("-", "") + "')"; - } + private string GetOracleDateTimeFormat(TimeSpan timeOfDay) + { + return GetTimeFormat(timeOfDay, OracleDateFormat, OracleTimeFormat, OracleMillisecondFormat); + } - return base.GetQuotedValue(value, fieldType); + private string GetTimeFormat(TimeSpan timeOfDay, string dateFormat, string timeFormat, string millisecondFormat) + { + var isStartOfDay = timeOfDay.Ticks == 0; + if (isStartOfDay) return dateFormat; + var hasFractionalSeconds = (timeOfDay.Milliseconds != 0) || ((timeOfDay.Ticks % TimeSpan.TicksPerMillisecond) != 0); + return hasFractionalSeconds + ? $"{dateFormat} {timeFormat}.{millisecondFormat}" + : $"{dateFormat} {timeFormat}"; } - public override string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams) + public override bool IsFullSelectStatement(string sqlFilter) { - var sql = new StringBuilder(); const string selectStatement = "SELECT "; - var modelDef = GetModel(tableType); - var isFullSelectStatement = false; if (!string.IsNullOrEmpty(sqlFilter)) { var cleanFilter = sqlFilter.Trim().Replace('\r', ' ').Replace('\n', ' ').ToUpperInvariant(); - isFullSelectStatement = cleanFilter.Length > selectStatement.Length - && cleanFilter.Substring(0, selectStatement.Length).Equals(selectStatement); + return cleanFilter.Length > selectStatement.Length && cleanFilter.Substring(0, selectStatement.Length).Equals(selectStatement); } + return false; + } - if (isFullSelectStatement) + public override string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams) + { + var sql = StringBuilderCache.Allocate(); + var modelDef = GetModel(tableType); + + if (IsFullSelectStatement(sqlFilter)) { if (Regex.Matches(sqlFilter.Trim().ToUpperInvariant(), @"(\b|\n)FROM(\b|\n)").Count < 1) sqlFilter += " FROM DUAL"; @@ -319,26 +285,25 @@ public override string ToSelectStatement(Type tableType, string sqlFilter, param } sql.Append(sqlFilter); } - return sql.ToString(); + return StringBuilderCache.ReturnAndFree(sql); } - public override void PrepareParameterizedInsertStatement(IDbCommand dbCommand, ICollection insertFields = null) + public override void PrepareParameterizedInsertStatement(IDbCommand dbCommand, ICollection insertFields = null, + Func shouldInclude=null) { - if (insertFields == null) - insertFields = new List(); - - var sbColumnNames = new StringBuilder(); - var sbColumnValues = new StringBuilder(); + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); var modelDef = GetModel(typeof(T)); dbCommand.Parameters.Clear(); dbCommand.CommandTimeout = OrmLiteConfig.CommandTimeout; - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.IsComputed || fieldDef.IsRowVersion) continue; - //insertFields contains Property "Name" of fields to insert (that's how expressions work) - if (insertFields.Count > 0 && !insertFields.Contains(fieldDef.Name)) continue; + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) + { + if (((fieldDef.IsComputed && !fieldDef.IsPersisted) || fieldDef.IsRowVersion) + && shouldInclude?.Invoke(fieldDef) != true) + continue; if (sbColumnNames.Length > 0) sbColumnNames.Append(","); if (sbColumnValues.Length > 0) sbColumnValues.Append(","); @@ -346,7 +311,7 @@ public override void PrepareParameterizedInsertStatement(IDbCommand dbCommand try { sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); - sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName),fieldDef.CustomInsert)); AddParameter(dbCommand, fieldDef); } @@ -358,7 +323,9 @@ public override void PrepareParameterizedInsertStatement(IDbCommand dbCommand } dbCommand.CommandText = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", - GetQuotedTableName(modelDef), sbColumnNames, sbColumnValues); + GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sbColumnNames), + StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)); } public override void SetParameterValues(IDbCommand dbCmd, object obj) @@ -368,9 +335,8 @@ public override void SetParameterValues(IDbCommand dbCmd, object obj) foreach (IDataParameter p in dbCmd.Parameters) { - FieldDefinition fieldDef; var fieldName = this.ToFieldName(p.ParameterName); - fieldMap.TryGetValue(fieldName, out fieldDef); + fieldMap.TryGetValue(fieldName, out var fieldDef); if (fieldDef == null) throw new ArgumentException("Field Definition '{0}' was not found".Fmt(fieldName)); @@ -391,8 +357,7 @@ public override void SetParameterValues(IDbCommand dbCmd, object obj) var sql = dbCmd.CommandText.TrimStart().ToUpperInvariant(); bool isInsert = sql.StartsWith("INSERT", StringComparison.InvariantCulture); - var result = GetNextValue(dbCmd.Connection, dbCmd.Transaction, fieldDef.Sequence, - pi.GetValue(obj, new object[] { }), isInsert); + var result = GetNextValue(dbCmd, fieldDef.Sequence, pi.GetValue(obj, new object[] { })); if (pi.PropertyType == typeof(String)) pi.SetProperty(obj, result.ToString()); else if (pi.PropertyType == typeof(Int16) || pi.PropertyType == typeof(Int16?)) @@ -405,52 +370,24 @@ public override void SetParameterValues(IDbCommand dbCmd, object obj) pi.SetProperty(obj, Convert.ToInt64(result)); } - SetParameterValue(fieldDef, p, obj); - } - } - - public override void SetParameterValue(FieldDefinition fieldDef, IDataParameter p, object obj) - { - p.Value = GetValueOrDbNull(fieldDef, obj); - } - - protected override object GetValue(FieldDefinition fieldDef, object obj) - { - var value = base.GetValue(fieldDef, obj); - - if (value != null) - { - if (fieldDef.FieldType == typeof(Guid)) - { - var guid = (Guid)value; - if (CompactGuid) return guid.ToByteArray(); - return guid.ToString(); - } - - if (fieldDef.FieldType == typeof(DateTimeOffset)) - { - var timestamp = (DateTimeOffset)value; - return _timestampConverter.ConvertToOracleTimeStampTz(timestamp); - } + SetParameterValue(fieldDef, p, obj); } - return value; } + //TODO: Change to parameterized query to match all other ToInsertRowStatement() impls public override string ToInsertRowStatement(IDbCommand dbCommand, object objWithProperties, ICollection insertFields = null) { - if (insertFields == null) - insertFields = new List(); - - var sbColumnNames = new StringBuilder(); - var sbColumnValues = new StringBuilder(); + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); var tableType = objWithProperties.GetType(); var modelDef = GetModel(tableType); - foreach (var fieldDef in modelDef.FieldDefinitions) + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) { - if (fieldDef.IsComputed) continue; - if (insertFields.Count > 0 && !insertFields.Contains(fieldDef.Name)) continue; + if ((fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; if ((fieldDef.AutoIncrement || !string.IsNullOrEmpty(fieldDef.Sequence)) && dbCommand != null) @@ -463,8 +400,7 @@ public override string ToInsertRowStatement(IDbCommand dbCommand, object objWith var pi = tableType.GetProperty(fieldDef.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); - var result = GetNextValue(dbCommand.Connection, dbCommand.Transaction, fieldDef.Sequence, - pi.GetValue(objWithProperties, new object[] { }), isInsert: true); + var result = GetNextValue(dbCommand, fieldDef.Sequence, pi.GetValue(objWithProperties, new object[] { })); if (pi.PropertyType == typeof(String)) pi.SetProperty(objWithProperties, result.ToString()); else if (pi.PropertyType == typeof(Int16)) @@ -482,9 +418,9 @@ public override string ToInsertRowStatement(IDbCommand dbCommand, object objWith try { - sbColumnNames.Append(string.Format("{0}", GetQuotedColumnName(fieldDef.FieldName))); + sbColumnNames.Append($"{GetQuotedColumnName(fieldDef.FieldName)}"); if (!string.IsNullOrEmpty(fieldDef.Sequence) && dbCommand == null) - sbColumnValues.Append(string.Format(":{0}", fieldDef.Name)); + sbColumnValues.Append($":{fieldDef.Name}"); else sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties)); } @@ -496,80 +432,72 @@ public override string ToInsertRowStatement(IDbCommand dbCommand, object objWith } var sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2}) ", - GetQuotedTableName(modelDef), sbColumnNames, sbColumnValues); + GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sbColumnNames), + StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)); return sql; } - public override string ToUpdateRowStatement(object objWithProperties, ICollection updateFields = null) + public override void PrepareUpdateRowStatement(IDbCommand dbCmd, object objWithProperties, ICollection updateFields = null) { - var sqlFilter = new StringBuilder(); - var sql = new StringBuilder(); + var sql = StringBuilderCache.Allocate(); + var sqlFilter = StringBuilderCacheAlt.Allocate(); var tableType = objWithProperties.GetType(); var modelDef = GetModel(tableType); foreach (var fieldDef in modelDef.FieldDefinitions) { - if (fieldDef.IsComputed) continue; + if ((fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; var updateFieldsEmptyOrNull = updateFields == null || updateFields.Count == 0; if ((fieldDef.IsPrimaryKey || fieldDef.Name == OrmLiteConfig.IdField) && updateFieldsEmptyOrNull) { - if (sqlFilter.Length > 0) sqlFilter.Append(" AND "); + if (sqlFilter.Length > 0) + sqlFilter.Append(" AND "); - sqlFilter.AppendFormat("{0} = {1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties)); + sqlFilter + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.AddQueryParam(dbCmd, fieldDef.GetValue(objWithProperties), fieldDef).ParameterName); continue; } - if (!updateFieldsEmptyOrNull && !updateFields.Contains(fieldDef.Name)) continue; - if (sql.Length > 0) sql.Append(","); - sql.AppendFormat("{0}={1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties)); - } - - var updateSql = string.Format("UPDATE {0} \nSET {1} {2}", - GetQuotedTableName(modelDef), sql, (sqlFilter.Length > 0 ? "\nWHERE " + sqlFilter : "")); - - return updateSql; - } - public override string ToDeleteRowStatement(object objWithProperties) - { - var tableType = objWithProperties.GetType(); - var modelDef = GetModel(tableType); + if (!updateFieldsEmptyOrNull && !updateFields.Contains(fieldDef.Name, StringComparer.OrdinalIgnoreCase)) + continue; - var sqlFilter = new StringBuilder(); + if (sql.Length > 0) + sql.Append(","); - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.IsPrimaryKey || fieldDef.Name == OrmLiteConfig.IdField) - { - if (sqlFilter.Length > 0) sqlFilter.Append(" AND "); - sqlFilter.AppendFormat("{0} = {1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties)); - } + sql + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.GetUpdateParam(dbCmd, fieldDef.GetValue(objWithProperties), fieldDef)); } - var deleteSql = string.Format("DELETE FROM {0} WHERE {1}", - GetQuotedTableName(modelDef), sqlFilter); - - return deleteSql; + var strFilter = StringBuilderCacheAlt.ReturnAndFree(sqlFilter); + dbCmd.CommandText = string.Format("UPDATE {0} \nSET {1} {2}", + GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sql), + strFilter.Length > 0 ? "\nWHERE " + strFilter : ""); } public override string ToCreateTableStatement(Type tableType) { - var sbColumns = new StringBuilder(); - var sbConstraints = new StringBuilder(); + var sbColumns = StringBuilderCache.Allocate(); + var sbConstraints = StringBuilderCacheAlt.Allocate(); + var sbPk = new StringBuilder(); var modelDef = GetModel(tableType); - foreach (var fieldDef in modelDef.FieldDefinitions) + foreach (var fieldDef in CreateTableFieldsStrategy(modelDef)) { + if (fieldDef.CustomSelect != null || (fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; + if (fieldDef.IsPrimaryKey) { sbPk.AppendFormat(sbPk.Length != 0 ? ",{0}" : "{0}", GetQuotedColumnName(fieldDef.FieldName)); @@ -577,21 +505,11 @@ public override string ToCreateTableStatement(Type tableType) if (sbColumns.Length != 0) sbColumns.Append(", \n "); - var columnDefinition = GetColumnDefinition( - fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - + var columnDefinition = GetColumnDefinition(fieldDef); sbColumns.Append(columnDefinition); - if (fieldDef.ForeignKey == null) continue; + if (fieldDef.ForeignKey == null || OrmLiteConfig.SkipForeignKeys) + continue; var refModelDef = GetModel(fieldDef.ForeignKey.ReferenceType); sbConstraints.AppendFormat( @@ -604,12 +522,21 @@ public override string ToCreateTableStatement(Type tableType) sbConstraints.Append(GetForeignKeyOnDeleteClause(fieldDef.ForeignKey)); } - if (sbPk.Length != 0) sbColumns.AppendFormat(", \n PRIMARY KEY({0})", sbPk); + if (sbPk.Length != 0) + sbColumns.AppendFormat(", \n PRIMARY KEY({0})", sbPk); + + var uniqueConstraints = GetUniqueConstraints(modelDef); + if (uniqueConstraints != null) + { + sbConstraints.Append(",\n" + uniqueConstraints); + } - var sql = new StringBuilder(string.Format( - "CREATE TABLE {0} \n(\n {1}{2} \n) \n", GetQuotedTableName(modelDef), sbColumns, sbConstraints)); + var sql = string.Format( + "CREATE TABLE {0} \n(\n {1}{2} \n) \n", GetQuotedTableName(modelDef), + StringBuilderCache.ReturnAndFree(sbColumns), + StringBuilderCacheAlt.ReturnAndFree(sbConstraints)); - return sql.ToString(); + return sql; } public override string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignKey) @@ -619,10 +546,11 @@ public override string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignK return (onDelete == "SET NULL" || onDelete == "CASCADE") ? " ON DELETE " + onDelete : string.Empty; } - public override string GetLoadChildrenSubSelect(ModelDefinition modelDef, SqlExpression expr) + public override string GetLoadChildrenSubSelect(SqlExpression expr) { if (!expr.OrderByExpression.IsNullOrEmpty() && expr.Rows == null) { + var modelDef = expr.ModelDef; expr.Select(this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey)) .ClearLimits() .OrderBy(""); //Invalid in Sub Selects @@ -632,7 +560,7 @@ public override string GetLoadChildrenSubSelect(ModelDefinition modelDef, return subSql; } - return base.GetLoadChildrenSubSelect(modelDef, expr); + return base.GetLoadChildrenSubSelect(expr); } public override string ToCreateSequenceStatement(Type tableType, string sequenceName) @@ -678,37 +606,16 @@ public override List SequenceList(Type tableType) return gens; } - public override string GetColumnDefinition(string fieldName, Type fieldType, - bool isPrimaryKey, bool autoIncrement, bool isNullable, bool isRowVersion, - int? fieldLength, int? scale, string defaultValue, string customFieldDefinition) + public override string GetColumnDefinition(FieldDefinition fieldDef) { - string fieldDefinition; - - if (customFieldDefinition != null) - { - fieldDefinition = customFieldDefinition; - } - else if (fieldType == typeof(string)) - { - var length = fieldLength.GetValueOrDefault(DefaultStringLength); - length = Math.Min(length, MaxStringColumnLength); - fieldDefinition = string.Format(StringLengthColumnDefinitionFormat, length); - } - else if (fieldType == typeof(Decimal)) - { - fieldDefinition = string.Format("{0} ({1},{2})", DecimalColumnDefinition, - fieldLength.GetValueOrDefault(DefaultDecimalPrecision), - scale.GetValueOrDefault(DefaultDecimalScale)); - } - else - { - fieldDefinition = GetColumnTypeDefinition(fieldType); - } + var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) + ?? GetColumnTypeDefinition(fieldDef.FieldType, fieldDef.FieldLength, fieldDef.Scale); - var sql = new StringBuilder(); - sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldName), fieldDefinition); + var sql = StringBuilderCache.Allocate(); + sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldDef.FieldName), fieldDefinition); - if (isRowVersion) + var defaultValue = GetDefaultValue(fieldDef); + if (fieldDef.IsRowVersion) { sql.AppendFormat(DefaultValueFormat, 1L); } @@ -717,11 +624,23 @@ public override string GetColumnDefinition(string fieldName, Type fieldType, sql.AppendFormat(DefaultValueFormat, defaultValue); } - sql.Append(isNullable ? " NULL" : " NOT NULL"); + sql.Append(fieldDef.IsNullable ? " NULL" : " NOT NULL"); - return sql.ToString(); + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } + + var definition = StringBuilderCache.ReturnAndFree(sql); + return definition; } + public override string GetAutoIdDefaultValue(FieldDefinition fieldDef) + { + return fieldDef.FieldType == typeof(Guid) + ? AutoIdGuidFunction + : null; + } public override List ToCreateIndexStatements(Type tableType) { @@ -732,8 +651,8 @@ public override List ToCreateIndexStatements(Type tableType) { if (!fieldDef.IsIndexed) continue; - var indexName = GetIndexName( - fieldDef.IsUnique, + var indexName = fieldDef.IndexName ?? GetIndexName( + fieldDef.IsUniqueIndex, (modelDef.IsInSchema ? modelDef.Schema + "_" + modelDef.ModelName : modelDef.ModelName).SafeVarName(), @@ -741,7 +660,7 @@ public override List ToCreateIndexStatements(Type tableType) indexName = NamingStrategy.ApplyNameRestrictions(indexName); sqlIndexes.Add( - ToCreateIndexStatement(fieldDef.IsUnique, indexName, modelDef, fieldDef.FieldName)); + ToCreateIndexStatement(fieldDef.IsUniqueIndex, indexName, modelDef, fieldDef.FieldName)); } foreach (var compositeIndex in modelDef.CompositeIndexes) @@ -751,7 +670,7 @@ public override List ToCreateIndexStatements(Type tableType) var indexNames = string.Join(",", compositeIndex.FieldNames.ToArray()); sqlIndexes.Add( - ToCreateIndexStatement(compositeIndex.Unique, indexName, modelDef, indexNames)); + ToCreateIndexStatement(compositeIndex.Unique, indexName, modelDef, indexNames, isCombined:true)); } return sqlIndexes; @@ -760,25 +679,22 @@ public override List ToCreateIndexStatements(Type tableType) protected override string ToCreateIndexStatement(bool isUnique, string indexName, ModelDefinition modelDef, string fieldName, bool isCombined = false, FieldDefinition fieldDef = null) { - return string.Format("CREATE {0} INDEX {1} ON {2} ({3} ) \n", - isUnique ? "UNIQUE" : "", - indexName, - GetQuotedTableName(modelDef), - GetQuotedColumnName(fieldName)); + var unique = isUnique ? "UNIQUE" : ""; + var field = isCombined ? fieldName : GetQuotedColumnName(fieldName); + return $"CREATE {unique} INDEX {indexName} ON {GetQuotedTableName(modelDef)} ({field}) \n"; } - public override string ToExistStatement(Type fromTableType, object objWithProperties, string sqlFilter, params object[] filterParams) { - var fromModelDef = GetModel(fromTableType); - var sql = new StringBuilder(); + var sql = StringBuilderCache.Allocate(); sql.AppendFormat("SELECT 1 FROM {0}", GetQuotedTableName(fromModelDef)); - var filter = new StringBuilder(); + var filter = StringBuilderCacheAlt.Allocate(); + var hasFilter = false; if (objWithProperties != null) { @@ -793,7 +709,9 @@ public override string ToExistStatement(Type fromTableType, foreach (var fieldDef in fromModelDef.FieldDefinitions) { - if (fieldDef.IsComputed) continue; + if (fieldDef.IsComputed) + continue; + if (fieldDef.ForeignKey != null && GetModel(fieldDef.ForeignKey.ReferenceType).ModelName == modelDef.ModelName) { @@ -809,7 +727,9 @@ public override string ToExistStatement(Type fromTableType, var modelDef = GetModel(tableType); foreach (var fieldDef in modelDef.FieldDefinitions) { - if (fieldDef.IsComputed) continue; + if (fieldDef.IsComputed) + continue; + if (fieldDef.IsPrimaryKey) { if (filter.Length > 0) filter.Append(" AND "); @@ -820,7 +740,9 @@ public override string ToExistStatement(Type fromTableType, } } - if (filter.Length > 0) sql.AppendFormat("\nWHERE {0} ", filter); + hasFilter = filter.Length > 0; + if (hasFilter) + sql.AppendFormat("\nWHERE {0} ", StringBuilderCacheAlt.ReturnAndFree(filter)); } if (!string.IsNullOrEmpty(sqlFilter)) @@ -829,14 +751,15 @@ public override string ToExistStatement(Type fromTableType, if (!sqlFilter.StartsWith("\nORDER ", StringComparison.OrdinalIgnoreCase) && !sqlFilter.StartsWith("\nROWS ", StringComparison.OrdinalIgnoreCase)) // ROWS [TO ]) { - sql.Append(filter.Length > 0 ? " AND " : "\nWHERE "); + sql.Append(hasFilter ? " AND " : "\nWHERE "); } sql.Append(sqlFilter); } - var sb = new StringBuilder("select 1 from dual where"); - sb.AppendFormat(" exists ({0})", sql); - return sb.ToString(); + var sb = StringBuilderCacheAlt.Allocate() + .Append("select 1 from dual where") + .AppendFormat(" exists ({0})", StringBuilderCache.ReturnAndFree(sql)); + return StringBuilderCacheAlt.ReturnAndFree(sb); } public override string ToSelectFromProcedureStatement( @@ -846,7 +769,7 @@ public override string ToSelectFromProcedureStatement( params object[] filterParams) { - var sbColumnValues = new StringBuilder(); + var sbColumnValues = StringBuilderCache.Allocate(); Type fromTableType = fromObjWithProperties.GetType(); @@ -859,13 +782,14 @@ public override string ToSelectFromProcedureStatement( sbColumnValues.Append(fieldDef.GetQuotedValue(fromObjWithProperties)); } - var sql = new StringBuilder(); + var columnValues = StringBuilderCache.ReturnAndFree(sbColumnValues); + var sql = StringBuilderCache.Allocate(); sql.AppendFormat("SELECT {0} FROM {1} {2}{3}{4} \n", GetColumnNames(GetModel(outputModelType)), GetQuotedTableName(modelDef), - sbColumnValues.Length > 0 ? "(" : "", - sbColumnValues, - sbColumnValues.Length > 0 ? ")" : ""); + columnValues.Length > 0 ? "(" : "", + columnValues, + columnValues.Length > 0 ? ")" : ""); if (!string.IsNullOrEmpty(sqlFilter)) { @@ -878,12 +802,12 @@ public override string ToSelectFromProcedureStatement( sql.Append(sqlFilter); } - return sql.ToString(); + return StringBuilderCache.ReturnAndFree(sql); } public override string ToExecuteProcedureStatement(object objWithProperties) { - var sbColumnValues = new StringBuilder(); + var sbColumnValues = StringBuilderCache.Allocate(); var tableType = objWithProperties.GetType(); var modelDef = GetModel(tableType); @@ -894,32 +818,56 @@ public override string ToExecuteProcedureStatement(object objWithProperties) sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties)); } + var columnValues = StringBuilderCache.ReturnAndFree(sbColumnValues); var sql = string.Format("EXECUTE PROCEDURE {0} {1}{2}{3};", GetQuotedTableName(modelDef), - sbColumnValues.Length > 0 ? "(" : "", - sbColumnValues, - sbColumnValues.Length > 0 ? ")" : ""); + columnValues.Length > 0 ? "(" : "", + columnValues, + columnValues.Length > 0 ? ")" : ""); return sql; } - private object GetNextValue(IDbConnection connection, IDbTransaction transaction, string sequence, object value, bool isInsert) + public override string GetLastInsertIdSqlSuffix() { - if (!isInsert) + if (SelectIdentitySql == null) + throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider."); + + if (UseReturningForLastInsertId) { - long nv; - return long.TryParse(value.ToString(), out nv) - ? nv - : 0; + var modelDef = GetModel(typeof(T)); + var pkName = NamingStrategy.GetColumnName(modelDef.PrimaryKey.FieldName); + return $" RETURNING {pkName} into " + pkName; } - using (var dbCmd = connection.CreateCommand()) + return "; " + SelectIdentitySql; + } + + private object GetNextValue(IDbCommand dbCmd, string sequence, object value) + { + if (value.ToString() != "0") { - dbCmd.Transaction = transaction; - dbCmd.CommandText = string.Format("SELECT {0}.NEXTVAL FROM dual", Quote(sequence)); - var result = dbCmd.LongScalar(); - return result; + object retObj; + if (long.TryParse(value.ToString(), out var nv)) + { + LastInsertId = nv; + retObj = LastInsertId; + } + else + { + LastInsertId = 0; + retObj = value; + } + return retObj; } + //Get current CommandText + var lastSql = dbCmd.CommandText; + dbCmd.CommandText = $"SELECT {Quote(sequence)}.NEXTVAL FROM dual"; + long result = (long)dbCmd.LongScalar(); + LastInsertId = result; + //Set CommandText back + dbCmd.CommandText = lastSql; + return result; } public bool QuoteNames { get; set; } @@ -935,9 +883,9 @@ private string Quote(string name) return WillQuote(name) ? string.Format("\"{0}\"", name) : name; } - public override string GetQuotedName(string fieldName) + public override string GetQuotedName(string name) { - return Quote(fieldName); + return Quote(name); } public override string GetQuotedTableName(ModelDefinition modelDef) @@ -986,10 +934,54 @@ public override SqlExpression SqlExpression() return new OracleSqlExpression(this); } + public override IDbDataParameter CreateParam() + { + return _factory.CreateParameter(); + } + + public override bool DoesSchemaExist(IDbCommand dbCmd, string schemaName) + { + dbCmd.CommandText = $"SELECT 1 FROM sys.schemas WHERE name = {schemaName.Quoted()}"; + var query = dbCmd.ExecuteNonQuery(); + return query == 1; + } + + public override string ToCreateSchemaStatement(string schemaName) + { + var sql = $"CREATE SCHEMA {GetSchemaName(schemaName)}"; + return sql; + } + + public override string ToAddColumnStatement(Type modelType, FieldDefinition fieldDef) + { + var command = base.ToAddColumnStatement(modelType, fieldDef); + + command = RemoveTerminatingSemicolon(command); + + return command.Replace("ADD COLUMN", "ADD"); + } + + private static string RemoveTerminatingSemicolon(string command) + { + command = command.Trim(); + + if (command[command.Length - 1] == ';') command = command.Substring(0, command.Length - 1); + + return command; + } + + protected override string ToDropColumnStatement(Type modelType, string columnName, IOrmLiteDialectProvider provider) + { + var command = base.ToDropColumnStatement(modelType, columnName, provider); + + return RemoveTerminatingSemicolon(command); + } + public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema=null) { if (!WillQuote(tableName)) tableName = tableName.ToUpper(); + tableName = RemoveSchemaName(tableName); var sql = "SELECT count(*) FROM USER_TABLES WHERE TABLE_NAME = {0}".SqlFmt(tableName); if (schema != null) @@ -1001,6 +993,31 @@ public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string s return result > 0; } + private static string RemoveSchemaName(string tableName) + { + var indexOfPeriod = tableName.IndexOf(".", StringComparison.Ordinal); + return indexOfPeriod < 0 ? tableName : tableName.Substring(indexOfPeriod + 1); + } + + public override bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null) + { + if (!WillQuote(tableName)) + tableName = tableName.ToUpper(); + + columnName = columnName.ToUpper(); + tableName = RemoveSchemaName(tableName); + var sql = "SELECT count(*) from all_tab_cols" + + " WHERE table_name = :tableName" + + " AND upper(column_name) = :columnName"; + + if (schema != null) + sql += " AND OWNER = :schema"; + + var result = db.SqlScalar(sql, new { tableName, columnName, schema }); + + return result > 0; + } + public override bool DoesSequenceExist(IDbCommand dbCmd, string sequenceName) { if (!WillQuote(sequenceName)) sequenceName = sequenceName.ToUpper(); @@ -1008,7 +1025,7 @@ public override bool DoesSequenceExist(IDbCommand dbCmd, string sequenceName) var sql = "SELECT count(*) FROM USER_SEQUENCES WHERE SEQUENCE_NAME = {0}".SqlFmt(sequenceName); dbCmd.CommandText = sql; var result = dbCmd.LongScalar(); - return result > 0; + return result == 1; } public override string ToAddForeignKeyStatement(Expression> field, @@ -1038,24 +1055,23 @@ public override string ToAddForeignKeyStatement(Expression tags=null) { - var sbInner = new StringBuilder(selectExpression); + var sbInner = StringBuilderCache.Allocate(); + ApplyTags(sbInner, tags); + + sbInner.Append(selectExpression); if (!bodyExpression.StartsWith(" ") && !bodyExpression.StartsWith("\n") && !selectExpression.EndsWith(" ") && !selectExpression.EndsWith("\n")) { @@ -1064,12 +1080,12 @@ public override string ToSelectStatement(ModelDefinition modelDef, sbInner.Append(bodyExpression); if (!rows.HasValue && !offset.HasValue) - return sbInner + " " + orderByExpression; + return StringBuilderCache.ReturnAndFree(sbInner) + " " + orderByExpression; if (!offset.HasValue) offset = 0; - if (string.IsNullOrEmpty(orderByExpression) && rows.HasValue) + if (queryType == QueryType.Select && (offset.GetValueOrDefault() > 0 || rows.GetValueOrDefault() > 1) && orderByExpression.IsEmpty()) { var primaryKey = modelDef.FieldDefinitions.FirstOrDefault(x => x.IsPrimaryKey); if (primaryKey == null) @@ -1077,7 +1093,7 @@ public override string ToSelectStatement(ModelDefinition modelDef, if (rows.Value == 1 && offset.Value == 0) { // Probably used Single<> extension method on a table with a composite key so let it through. - // Lack of an orderby expression will mean it returns a random matching row, but that is OK. + // Lack of an order by expression will mean it returns a random matching row, but that is OK. orderByExpression = ""; } else @@ -1085,16 +1101,15 @@ public override string ToSelectStatement(ModelDefinition modelDef, } else { - orderByExpression = string.Format("ORDER BY {0}", - this.GetQuotedColumnName(modelDef, primaryKey.FieldName)); + orderByExpression = $"ORDER BY {this.GetQuotedColumnName(modelDef, primaryKey.FieldName)}"; } } sbInner.Append(" " + orderByExpression); - var sql = sbInner.ToString(); + var sql = StringBuilderCache.ReturnAndFree(sbInner); //TODO paging doesn't work with ORACLE because we are returning RNUM so we need to figure out a way to return just the desired columns - var sb = new StringBuilder(); + var sb = StringBuilderCache.Allocate(); sb.AppendLine("SELECT * FROM ("); sb.AppendLine("SELECT \"_ss_ormlite_1_\".*, ROWNUM RNUM FROM ("); sb.Append(sql); @@ -1105,12 +1120,31 @@ public override string ToSelectStatement(ModelDefinition modelDef, sb.Append(") \"_ss_ormlite_2_\" "); sb.AppendFormat("WHERE \"_ss_ormlite_2_\".RNUM > {0}", offset.Value); - return sb.ToString(); + return StringBuilderCache.ReturnAndFree(sb); } public override string ToRowCountStatement(string innerSql) { return "SELECT COUNT(*) FROM ({0})".Fmt(innerSql); } + + public override string SqlConcat(IEnumerable args) => string.Join(" || ", args); + + public override string SqlRandom => "dbms_random.value"; + + protected OracleConnection Unwrap(IDbConnection db) + { + return (OracleConnection)db.ToDbConnection(); + } + + protected OracleCommand Unwrap(IDbCommand cmd) + { + return (OracleCommand)cmd.ToDbCommand(); + } + + protected OracleDataReader Unwrap(IDataReader reader) + { + return (OracleDataReader)reader; + } } } diff --git a/src/ServiceStack.OrmLite.Oracle/OracleSqlExpression.cs b/src/ServiceStack.OrmLite.Oracle/OracleSqlExpression.cs index b04647d9f..02f66cf30 100644 --- a/src/ServiceStack.OrmLite.Oracle/OracleSqlExpression.cs +++ b/src/ServiceStack.OrmLite.Oracle/OracleSqlExpression.cs @@ -19,18 +19,39 @@ protected override object VisitColumnAccessMethod(MethodCallExpression m) if (args.Count == 2) { var length = Int32.Parse(args[1].ToString()); - return new PartialSqlString(string.Format("subStr({0},{1},{2})", - quotedColName, - startIndex, - length)); + return new PartialSqlString(string.Format( + "subStr({0},{1},{2})", quotedColName, startIndex, length)); } - return new PartialSqlString(string.Format("subStr({0},{1})", - quotedColName, - startIndex)); + return new PartialSqlString(string.Format( + "subStr({0},{1})", quotedColName, startIndex)); } return base.VisitColumnAccessMethod(m); } + + protected override void VisitFilter(string operand, object originalLeft, object originalRight, ref object left, ref object right) + { + if (originalRight is DateTimeOffset) + return; + + base.VisitFilter(operand, originalLeft, originalRight, ref left, ref right); + } + + protected override void ConvertToPlaceholderAndParameter(ref object right) + { + var paramName = Params.Count.ToString(); + var paramValue = right; + + var parameter = CreateParam(paramName, paramValue); + Params.Add(parameter); + + right = parameter.ParameterName; + } + + protected override PartialSqlString ToLengthPartialString(object arg) + { + return new PartialSqlString($"LENGTH({arg})"); + } } } diff --git a/src/ServiceStack.OrmLite.Oracle/OracleTimestampConverter.cs b/src/ServiceStack.OrmLite.Oracle/OracleTimestampConverter.cs index 9126df85f..015c596a7 100644 --- a/src/ServiceStack.OrmLite.Oracle/OracleTimestampConverter.cs +++ b/src/ServiceStack.OrmLite.Oracle/OracleTimestampConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Data; using System.Reflection; namespace ServiceStack.OrmLite.Oracle @@ -8,21 +9,24 @@ public class OracleTimestampConverter private readonly Lazy _oracleTimeStampTzConstructor; private readonly Type _factoryType; + private readonly string _clientProviderName; + private MethodInfo _oracleTypeParameterSetMethod; + private object _oracleDbTypeTimeStampTzValue; - public OracleTimestampConverter(Type factoryType) + public OracleTimestampConverter(Type factoryType, string clientProviderName) { _factoryType = factoryType; + _clientProviderName = clientProviderName; _oracleTimeStampTzConstructor = new Lazy(() => InitConstructor(_factoryType)); + InitSetDbType(_factoryType); } - private static ConstructorInfo InitConstructor(Type factoryType) + private ConstructorInfo InitConstructor(Type factoryType) { var oracleAssembly = factoryType.Assembly; - var globalizationType = oracleAssembly.GetType("Oracle.DataAccess.Client.OracleGlobalization"); - if (globalizationType == null) return null; - - var oracleTimeStampTzType = oracleAssembly.GetType("Oracle.DataAccess.Types.OracleTimeStampTZ"); + var clientProviderNamePrefix = _clientProviderName.Substring(0, _clientProviderName.LastIndexOf('.')); + var oracleTimeStampTzType = oracleAssembly.GetType(clientProviderNamePrefix + ".Types.OracleTimeStampTZ"); if (oracleTimeStampTzType == null) return null; return oracleTimeStampTzType.GetConstructor(new[] { typeof(DateTime), typeof(string) }); @@ -48,5 +52,26 @@ public object ConvertToOracleTimeStampTz(DateTimeOffset timestamp) return timestamp; } + + private void InitSetDbType(Type factoryType) + { + var oracleAssembly = factoryType.Assembly; + + var oracleParameterType = oracleAssembly.GetType(_clientProviderName + ".OracleParameter"); + if (oracleParameterType == null) return; + var oracleTypeParameter = oracleParameterType.GetProperty("OracleDbType"); + if (oracleTypeParameter == null) return; + _oracleTypeParameterSetMethod = oracleTypeParameter.GetSetMethod(); + if (_oracleTypeParameterSetMethod == null) return; + + var oracleDbType = oracleAssembly.GetType(_clientProviderName + ".OracleDbType"); + if (oracleDbType == null) return; + _oracleDbTypeTimeStampTzValue = Enum.Parse(oracleDbType, "TimeStampTZ"); + } + + public void SetParameterTimeStampTzType(IDbDataParameter p) + { + _oracleTypeParameterSetMethod.Invoke(p, new [] {_oracleDbTypeTimeStampTzValue}); + } } } diff --git a/src/ServiceStack.OrmLite.Oracle/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Oracle/Properties/AssemblyInfo.cs index 4df226ff9..22ae012d6 100644 --- a/src/ServiceStack.OrmLite.Oracle/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite.Oracle/Properties/AssemblyInfo.cs @@ -1,22 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("ServiceStack.OrmLite.Oracle")] -[assembly: AssemblyDescription("POCO ORM for Oracle")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("aicl")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - -[assembly: AssemblyVersion("4.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.Oracle/ServiceStack.OrmLite.Oracle.Signed.csproj b/src/ServiceStack.OrmLite.Oracle/ServiceStack.OrmLite.Oracle.Signed.csproj deleted file mode 100644 index f745d4c8e..000000000 --- a/src/ServiceStack.OrmLite.Oracle/ServiceStack.OrmLite.Oracle.Signed.csproj +++ /dev/null @@ -1,107 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {517B64BA-D7A6-4A15-8719-821B38147C61} - Library - ServiceStack.OrmLite.Oracle - ServiceStack.OrmLite.Oracle - v4.0 - - ..\ - true - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - pdbonly - false - bin\Release - prompt - 4 - false - false - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - true - - - servicestack-sn.pfx - - - - ..\..\lib\signed\ServiceStack.Text.dll - - - - - - ..\..\lib\signed\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - - - - - - - - - - - - Component - - - Component - - - - - - - - - - - - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/ServiceStack.OrmLite.Oracle.csproj b/src/ServiceStack.OrmLite.Oracle/ServiceStack.OrmLite.Oracle.csproj index d2a464c58..2d9abf1ac 100644 --- a/src/ServiceStack.OrmLite.Oracle/ServiceStack.OrmLite.Oracle.csproj +++ b/src/ServiceStack.OrmLite.Oracle/ServiceStack.OrmLite.Oracle.csproj @@ -1,101 +1,43 @@ - - + + - Debug - AnyCPU - 10.0.0 - 2.0 - {517B64BA-D7A6-4A15-8719-821B38147C61} - Library - ServiceStack.OrmLite.Oracle + net472;netstandard2.0;net6.0 ServiceStack.OrmLite.Oracle - v4.0 - - ..\ - true - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - pdbonly - false - bin\Release - prompt - 4 - false - false - true - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset + ServiceStack.OrmLite.Oracle + OrmLite.Oracle - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for Oracle RDBMS (Unofficial). + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently + stored in schemaless text blobs in Oracle. + + Oracle;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + + + + + - - ..\..\lib\ServiceStack.Text.dll - - - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - + + + - - - - - - - - - + Component - + Component - - - - - - - - - - - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - \ No newline at end of file + + diff --git a/src/ServiceStack.OrmLite.Oracle/app.config b/src/ServiceStack.OrmLite.Oracle/app.config index 9d14b2656..a2476edb7 100644 --- a/src/ServiceStack.OrmLite.Oracle/app.config +++ b/src/ServiceStack.OrmLite.Oracle/app.config @@ -1,11 +1,13 @@ - + + - - - - - - - - - \ No newline at end of file + + + + + + + + + + \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Oracle/packages.config b/src/ServiceStack.OrmLite.Oracle/packages.config deleted file mode 100644 index cc888a190..000000000 --- a/src/ServiceStack.OrmLite.Oracle/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/CreatePostgreSQLTablesTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/CreatePostgreSQLTablesTests.cs deleted file mode 100644 index a4f24c1fc..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/CreatePostgreSQLTablesTests.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - [TestFixture] - public class CreatePostgreSQLTablesTests : OrmLiteTestBase - { - public CreatePostgreSQLTablesTests() : base(Dialect.PostgreSql) { } - - [Test] - public void DropAndCreateTable_DropsTableAndCreatesTable() - { - using (var db = OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.Insert(new TestData { Id = Guid.NewGuid() }); - db.DropAndCreateTable(); - db.Insert(new TestData { Id = Guid.NewGuid() }); - } - } - - - [Test] - public void can_create_tables_after_UseUnicode_or_DefaultStringLenght_changed() - { - //first one passes - _reCreateTheTable(); - - //all of these pass now: - OrmLiteConfig.DialectProvider.UseUnicode = true; - _reCreateTheTable(); - - OrmLiteConfig.DialectProvider.UseUnicode = false; - _reCreateTheTable(); - - OrmLiteConfig.DialectProvider.DefaultStringLength = 98765; - - _reCreateTheTable(); - } - - private void _reCreateTheTable() - { - using(var db = OpenDbConnection()) { - db.CreateTable(true); - } - } - - private class CreatePostgreSQLTablesTests_dummy_table - { - [AutoIncrement] - public int Id { get; set; } - - public String StringNoExplicitLength { get; set; } - - [StringLength(100)] - public String String100Characters { get; set; } - } - - [Test] - public void can_create_same_table_in_multiple_schemas_based_on_conn_string_search_path() - { - var builder = new Npgsql.NpgsqlConnectionStringBuilder(ConnectionString); - var schema1 = "schema_1"; - var schema2 = "schema_2"; - using (var db = OpenDbConnection()) - { - CreateSchemaIfNotExists(db, schema1); - CreateSchemaIfNotExists(db, schema2); - } - - builder.SearchPath = schema1; - using (var dbS1 = builder.ToString().OpenDbConnection()) - { - dbS1.DropTable(); - dbS1.CreateTable(); - Assert.That(dbS1.Count(), Is.EqualTo(0)); - dbS1.DropTable(); - } - builder.SearchPath = schema2; - - using (var dbS2 = builder.ToString().OpenDbConnection()) - { - dbS2.DropTable(); - dbS2.CreateTable(); - Assert.That(dbS2.Count(), Is.EqualTo(0)); - dbS2.DropTable(); - } - - } - - public class TestData - { - [PrimaryKey] - public Guid Id { get; set; } - - public string Name { get; set; } - - public string Surname { get; set; } - } - - private void CreateSchemaIfNotExists(System.Data.IDbConnection db, string name) - { - string createSchemaSQL = @"DO $$ -BEGIN - - IF NOT EXISTS( - SELECT schema_name - FROM information_schema.schemata - WHERE schema_name = '{0}' - ) - THEN - EXECUTE 'CREATE SCHEMA ""{0}""'; - END IF; - -END -$$;" - .Fmt(name); - db.ExecuteSql(createSchemaSQL); - } - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/EnumTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/EnumTests.cs deleted file mode 100644 index 2ae8d688f..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/EnumTests.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System.Linq; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - public class EnumTests : OrmLiteTestBase - { - public EnumTests() : base(Dialect.PostgreSql) { } - - [Test] - public void CanCreateTable() - { - OpenDbConnection().CreateTable(true); - } - - [Test] - public void CanStoreEnumValue() - { - using(var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum {Id = 1, EnumValue = SomeEnum.Value1}); - } - } - - [Test] - public void CanGetEnumValue() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; - con.Save(obj); - var target = con.SingleById(obj.Id); - Assert.AreEqual(obj.Id, target.Id); - Assert.AreEqual(obj.EnumValue, target.EnumValue); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_expression() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Select(q => q.EnumValue == SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_string() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.SelectFmt("\"enum_value\" = {0}", SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Ignore("Where using anon type needs to be fixed")] - [Test] - public void CanQueryByEnumValue_using_where_with_AnonType() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Where(new { EnumValue = SomeEnum.Value1 }); - - Assert.AreEqual(2, target.Count()); - } - } - } - - public enum SomeEnum - { - Value1, - Value2, - Value3 - } - - public class TypeWithEnum - { - public int Id { get; set; } - public SomeEnum EnumValue { get; set; } - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AdditiveExpressionsTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AdditiveExpressionsTest.cs deleted file mode 100644 index 32c09c273..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AdditiveExpressionsTest.cs +++ /dev/null @@ -1,150 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class AdditiveExpressionsTest : ExpressionsTestBase - { - [Test] - public void Can_select_constant_add_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 4 + 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_constant_subtract_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 10 - 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_variable_add_expression() - { -// ReSharper disable ConvertToConstant.Local - var a = 4; - var b = 3; -// ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == a + b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_variable_subtract_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 10; - var b = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == a - b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_method_add_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == GetValue(4) + GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_method_subtract_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == GetValue(10) - GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AuthorUseCase.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AuthorUseCase.cs deleted file mode 100644 index 196720a3c..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AuthorUseCase.cs +++ /dev/null @@ -1,374 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class AuthorUseCase : OrmLiteTestBase - { - private List authors; - - public AuthorUseCase() : base(Dialect.PostgreSql) - { - authors = new List(); - authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); - authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); - authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); - authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); - authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); - authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); - authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); - authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); - authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); - authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); - authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); - authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico", LastActivity = DateTime.Today }); - } - - [SetUp] - public void Setup() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.SaveAll(authors); - } - } - - [Test] - public void AuthorUsesCases() - { - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (var db = OpenDbConnection()) - { - int year = DateTime.Today.AddYears(-20).Year; - var lastDay = new DateTime(year, 12, 31); - int expected = 5; - - ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - List result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - Assert.AreEqual(expected, result.Count); - Author a = new Author() { Birthday = lastDay }; - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); - Assert.AreEqual(expected, result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected = 6; - //Sql.In can take params object[] - var city = "Berlin"; - ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); - Assert.AreEqual(expected, result.Count); - - // select authors from Bogota and Cartagena : 7 - expected = 7; - //... or Sql.In can take List - city = "Bogota"; - List cities = new List(); - cities.Add(city); - cities.Add("Cartagena"); - ev.Where().Where(rn => Sql.In(rn.City, cities)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name starts with A - expected = 3; - ev.Where().Where(rn => rn.Name.StartsWith("A")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.StartsWith("A")); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected = 3; - var name = "GARZON"; - ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected = 3; - ev.Where().Where(rn => rn.Name.EndsWith("garzon")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name contains Benedict - expected = 2; - name = "Benedict"; - ev.Where().Where(rn => rn.Name.Contains(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Assert.AreEqual(expected, result.Count); - a.Name = name; - result = db.Select(rn => rn.Name.Contains(a.Name)); - Assert.AreEqual(expected, result.Count); - - - // select authors with Earnings <= 50 - expected = 3; - var earnings = 50; - ev.Where().Where(rn => rn.Earnings <= earnings); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Earnings <= 50); - Assert.AreEqual(expected, result.Count); - - // select authors with Rate = 10 and city=Mexio - expected = 1; - city = "Mexico"; - ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Assert.AreEqual(expected, result.Count); - - a.City = city; - result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); - Assert.AreEqual(expected, result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected = 2; - var rate = 0; - ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); - Assert.AreEqual(expected, rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected = 4; - ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); - ev.Where().Where(rn => !rn.Active); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - //update comment for City == null - expected = 2; - ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); - Assert.AreEqual(expected, rows); - - // delete where City is null - expected = 2; - rows = db.Delete(ev); - Assert.AreEqual(expected, rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected = 14; - ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - var author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel", author.Name); - - // select only first 5 rows .... - expected = 5; - ev.Limit(5); // note: order is the same as in the last sentence - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - //paging : - ev.Limit(0, 4);// first page, page size=4; - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Limit(4, 4);// second page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Jorge Garzon".ToUpper(), author.Name); - - ev.Limit(8, 4);// third page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Rodger Contreras".ToUpper(), author.Name); - - // select distinct.. - ev.Limit().OrderBy(); // clear limit, clear order for postres - ev.SelectDistinct(r => r.City); - expected = 6; - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); - result = db.Select(ev); - var expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - var r1 = db.Single(ev); - Assert.AreEqual(expectedResult, r1.Birthday); - - var r2 = db.Scalar(e => Sql.Max(e.Birthday)); - Assert.AreEqual(expectedResult, r2); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - var expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - r1 = db.Single(ev); - Assert.AreEqual(expectedStringResult, r1.City); - - var expectedDecimal = authors.Max(e => e.Earnings); - Decimal? r3 = db.Scalar(e => Sql.Max(e.Earnings)); - Assert.AreEqual(expectedDecimal, r3.Value); - - var expectedString = authors.Max(e => e.Name); - string r4 = db.Scalar(e => Sql.Max(e.Name)); - Assert.AreEqual(expectedString, r4); - - var expectedDate = authors.Max(e => e.LastActivity); - DateTime? r5 = db.Scalar(e => Sql.Max(e.LastActivity)); - Assert.AreEqual(expectedDate, r5); - - var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); - DateTime? r51 = db.Scalar( - e => Sql.Max(e.LastActivity), - e => e.City == "Bogota"); - Assert.AreEqual(expectedDate51, r51); - - try - { - var expectedBool = authors.Max(e => e.Active); - bool r6 = db.Scalar(e => Sql.Max(e.Active)); - Assert.AreEqual(expectedBool, r6); - } - catch (Exception e) - { - //???? - //if (dialect.Name == "PostgreSQL") - // Console.WriteLine("OK PostgreSQL: " + e.Message); - //else - // Console.WriteLine("************** FAILED *************** " + e.Message); - } - - - - // Tests for predicate overloads that make use of the expression visitor - author = db.Single(q => q.Name == "Jorge Garzon"); - - try - { - author = db.Single(q => q.Name == "Does not exist"); - Assert.Fail(); - } - catch - { - //"Expected exception thrown, OK? True" - } - - author = db.Single(q => q.Name == "Does not exist"); - Assert.IsNull(author); - - author = db.Single(q => q.City == "Bogota"); - Assert.AreEqual("Angel Colmenares", author.Name); - - a.City = "Bogota"; - author = db.Single(q => q.City == a.City); - Assert.AreEqual("Angel Colmenares", author.Name); - - // count test - - var expectedCount = authors.Count(); - long r7 = db.Scalar(e => Sql.Count(e.Id)); - Assert.AreEqual(expectedCount, r7); - - expectedCount = authors.Count(e => e.City == "Bogota"); - r7 = db.Scalar( - e => Sql.Count(e.Id), - e => e.City == "Bogota"); - Assert.AreEqual(expectedCount, r7); - - ev.Update();// all fields will be updated - // select and update - expected = 1; - var rr = db.Single(rn => rn.Name == "Luis garzon"); - rr.City = "Madrid"; - rr.Comments = "Updated"; - ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated - rows = db.UpdateOnly(rr, ev); // == dbCmd.Update(rr) but it returns void - Assert.AreEqual(expected, rows); - - expected = 0; - ev.Where().Where(r => r.City == "Ciudad Gotica"); - rows = db.UpdateOnly(rr, ev); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.City == "Madrid").Count; - author = new Author() { Active = false }; - rows = db.UpdateOnly(author, x => x.Active, x => x.City == "Madrid"); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.Active == false).Count; - rows = db.Delete(x => x.Active == false); - Assert.AreEqual(expected, rows); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ConditionalExpressionTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ConditionalExpressionTest.cs deleted file mode 100644 index b7101dd9e..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ConditionalExpressionTest.cs +++ /dev/null @@ -1,151 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class ConditionalExpressionTest : ExpressionsTestBase - { - [Test] - public void Can_select_conditional_and_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn > 2 && q.IntColumn < 4); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_conditional_or_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 3 || q.IntColumn < 0); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_evaluated_conditional_and_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 10; - var b = 5; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == (a >= b && a > 0)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_evaluated_conditional_or_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 10; - var b = 5; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 3 || a > b); - - Assert.IsNotNull(actual); - Assert.AreEqual(11, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_evaluated_invalid_conditional_or_valid_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => !q.BoolColumn || a); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - [Test] - public void Can_select_evaluated_conditional_and_valid_expression() - { - var model = new - { - StringValue = "4" - }; - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn && q.StringColumn == model.StringValue); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/EqualityExpressionsTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/EqualityExpressionsTest.cs deleted file mode 100644 index fb09c07ef..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/EqualityExpressionsTest.cs +++ /dev/null @@ -1,295 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class EqualityExpressionsTest : ExpressionsTestBase - { - #region int tests - - [Test] - public void Can_select_equals_constant_int_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_equals_variable_int_expression() - { -// ReSharper disable ConvertToConstant.Local - var columnValue = 3; -// ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = columnValue, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == columnValue); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_equals_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_not_equals_constant_int_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn != 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - } - - [Test] - public void Can_select_not_equals_variable_int_expression() - { - // ReSharper disable ConvertToConstant.Local - var columnValue = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = columnValue, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn != columnValue); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - } - - [Test] - public void Can_select_not_equals_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn != GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - } - - #endregion - - #region bool test - - [Test] - public void Can_select_equals_constant_bool_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - // ReSharper disable RedundantBoolCompare - var actual = con.Select(q => q.BoolColumn == true); - // ReSharper restore RedundantBoolCompare - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_equals_constant_bool_expression2() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - // ReSharper disable RedundantBoolCompare - var actual = con.Select(q => q.BoolColumn); - // ReSharper restore RedundantBoolCompare - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_equals_variable_bool_expression() - { - // ReSharper disable ConvertToConstant.Local - var columnValue = true; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == columnValue); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_equals_bool_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == GetValue(true)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_equals_null_espression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test", - NullableCol = new TestType { StringColumn = "sometext" } - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.NullableCol == null); - - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 10); - CollectionAssert.DoesNotContain(actual, expected); - } - } - - [Test] - public void Can_select_not_equals_null_espression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test", - NullableCol = new TestType { StringColumn = "sometext" } - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.NullableCol != null); - - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - } - - // Assume not equal works ;-) - #endregion - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ExpressionsTestBase.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ExpressionsTestBase.cs deleted file mode 100644 index 86822fd96..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ExpressionsTestBase.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Linq; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class ExpressionsTestBase : OrmLiteTestBase - { - public ExpressionsTestBase() : base(Dialect.PostgreSql) { } - - [SetUp] - public void Setup() - { - OpenDbConnection().CreateTable(true); - } - - public T GetValue(T item) - { - return item; - } - - protected void EstablishContext(int numberOfRandomObjects) - { - OrmLiteConfig.ClearCache(); - EstablishContext(numberOfRandomObjects, null); - } - - protected void EstablishContext(int numberOfRandomObjects, params TestType[] obj) - { - if (obj == null) - obj = new TestType[0]; - - using (var con = OpenDbConnection()) - { - foreach (var t in obj) - { - con.Insert(t); - } - - var random = new Random((int)(DateTime.UtcNow.Ticks ^ (DateTime.UtcNow.Ticks >> 4))); - for (var i = 0; i < numberOfRandomObjects; i++) - { - TestType o = null; - - while (o == null) - { - int intVal = random.Next(); - - o = new TestType - { - BoolColumn = random.Next()%2 == 0, - IntColumn = intVal, - StringColumn = Guid.NewGuid().ToString() - }; - - if (obj.Any(x => x.IntColumn == intVal)) - o = null; - } - - con.Insert(o); - } - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/LogicalExpressionsTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/LogicalExpressionsTest.cs deleted file mode 100644 index bef61aea6..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/LogicalExpressionsTest.cs +++ /dev/null @@ -1,169 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class LogicalExpressionsTest : ExpressionsTestBase - { - #region constants - - // Unlikely - // OpenDbConnection().Select(q => q.BoolColumn == (true & false)); - - #endregion - - #region variables - - [Test] - public void Can_select_logical_and_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - var b = false; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == (a & b)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_logical_or_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - var b = false; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == (a | b)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_logical_xor_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - var b = false; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == (a ^ b)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - #endregion - - #region method - - [Test] - public void Can_select_logical_and_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == (GetValue(true) & GetValue(false))); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_logical_or_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == (GetValue(true) | GetValue(false))); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_logical_xor_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == (GetValue(true) ^ GetValue(false))); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - #endregion - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/MultiplicativeExpressionsTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/MultiplicativeExpressionsTest.cs deleted file mode 100644 index 3f18b1f4e..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/MultiplicativeExpressionsTest.cs +++ /dev/null @@ -1,220 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class MultiplicativeExpressionsTest : ExpressionsTestBase - { - [Test] - public void Can_select_constant_multiply_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 4*3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_constant_divide_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 36/3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_constant_modulo_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == 37%10); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_variable_multiply_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 4; - var b = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == a*b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_variable_divide_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 36; - var b = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == a/b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_variablemodulo_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 37; - var b = 10; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == a%b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_method_multiply_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == GetValue(4)*GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_method_divide_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == GetValue(36)/GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_method_modulo_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == GetValue(37)%GetValue(10)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/OrmLiteCountTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/OrmLiteCountTests.cs deleted file mode 100644 index 832d2b49c..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/OrmLiteCountTests.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; - -using System.Data; -using System.Linq.Expressions; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - [TestFixture] - public class OrmLiteCountTests : OrmLiteTestBase - { - public OrmLiteCountTests() : base(Dialect.PostgreSql) { } - - [Test] - public void CanDoCountWithInterface() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - db.DeleteAll(); - - db.Insert(new CountTestTable { Id = 1, StringValue = "Your string value" }); - - var count = db.Scalar(e => Sql.Count(e.Id)); - - Assert.That(count, Is.EqualTo(1)); - - count = Count(db); - - Assert.That(count, Is.EqualTo(1)); - - count = CountByColumn(db); - - Assert.That(count, Is.EqualTo(0)); - - } - } - - [Test] - public void CanDoCountWithInterfaceAndPredicate() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - db.DeleteAll(); - db.Insert(new CountTestTable { Id = 1, StringValue = "Your string value" }); - - Expression> exp = q => q.Id == 2; - var count = Count(db, exp); - Assert.That(count, Is.EqualTo(0)); - - - exp = q => q.Id == 1; - count = Count(db, exp); - Assert.That(count, Is.EqualTo(1)); - - exp = q => q.CountColumn == null; - count = Count(db, exp); - Assert.That(count, Is.EqualTo(1)); - - exp = q => q.CountColumn == null; - count = CountByColumn(db, exp); - Assert.That(count, Is.EqualTo(0)); - } - } - - long Count(IDbConnection db) where T : IHasId - { - return db.Scalar(e => Sql.Count(e.Id)); - } - - - long CountByColumn(IDbConnection db) where T : IHasCountColumn - { - return db.Scalar(e => Sql.Count(e.CountColumn)).Value; - } - - - int Count(IDbConnection db, Expression> predicate) where T : IHasId - { - return db.Scalar(e => Sql.Count(e.Id), predicate); - } - - int CountByColumn(IDbConnection db, Expression> predicate) where T : IHasCountColumn - { - return db.Scalar(e => Sql.Count(e.CountColumn), predicate).Value; - } - - } - - public interface IHasCountColumn - { - int? CountColumn { get; set; } - } - - - public class CountTestTable : IHasId, IHasCountColumn - { - public CountTestTable() { } - #region IHasId implementation - public int Id { get; set; } - [StringLength(40)] - public string StringValue { get; set; } - #endregion - - #region IHasCountColumn implementation - public int? CountColumn { get; set; } - #endregion - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/PrimaryExpressionsTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/PrimaryExpressionsTest.cs deleted file mode 100644 index 5136e6bb8..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/PrimaryExpressionsTest.cs +++ /dev/null @@ -1,404 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class PrimaryExpressionsTest : ExpressionsTestBase - { - private static class TestClass - { - public static int StaticProperty { get { return 12; } } - public static int _staticField = 12; - } - - private class TestClass - { - public static T StaticMethod(T value) - { - return value; - } - - public T Property { get; set; } - - public T _field; - - public T Mehtod() - { - return _field; - } - - public TestClass(T value) - { - Property = value; - _field = value; - } - } - - private struct TestStruct - { - public T Property { get { return _field; } } - - public T _field; - - public T Mehtod() - { - return _field; - } - - public TestStruct(T value) - { - _field = value; - } - } - - #region int - - [Test] - public void Can_select_int_property_expression() - { - var tmp = new TestClass(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == tmp.Property); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_int_field_expression() - { - var tmp = new TestClass(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == tmp._field); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_int_method_expression() - { - var tmp = new TestClass(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == tmp.Mehtod()); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_static_int_property_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass.StaticProperty); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_static_int_field_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == TestClass._staticField); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_static_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == TestClass.StaticMethod(12)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_int_new_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == new TestClass(12).Property); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_struct_int_field_expression() - { - var tmp = new TestStruct(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == tmp._field); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_struct_int_property_expression() - { - var tmp = new TestStruct(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == tmp.Property); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_struct_int_method_expression() - { - var tmp = new TestStruct(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == tmp.Mehtod()); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - #endregion int - - - #region bool - - [Test] - public void Can_select_bool_property_expression() - { - var tmp = new TestClass(false); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == tmp.Property); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_bool_field_expression() - { - var tmp = new TestClass(false); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == tmp._field); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_bool_method_expression() - { - var tmp = new TestClass(false); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == tmp.Mehtod()); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_static_bool_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == TestClass.StaticMethod(false)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_bool_new_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == new TestClass(false).Property); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - } - - #endregion bool - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/RelationalExpressionsTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/RelationalExpressionsTest.cs deleted file mode 100644 index 843ee348a..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/RelationalExpressionsTest.cs +++ /dev/null @@ -1,94 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class RelationalExpressionsTest : ExpressionsTestBase - { - [Test] - public void Can_select_greater_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn > 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - } - - [Test] - public void Can_select_greater_or_equal_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn >= 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(11, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_smaller_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn < 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(0, actual.Count); - } - } - - [Test] - public void Can_select_smaller_or_equal_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn <= 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/StringFunctionTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/StringFunctionTests.cs deleted file mode 100644 index 0e9772fba..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/StringFunctionTests.cs +++ /dev/null @@ -1,259 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class StringFunctionTests : ExpressionsTestBase - { - [Test] - public void Can_select_using_contains() - { - var stringVal = "stringValue"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_contains_with_quote_in_string() - { - var stringVal = "string'ContainingAQuote"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_contains_with_double_quote_in_string() - { - var stringVal = "string\"ContainingAQuote"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_contains_with_backtick_in_string() - { - var stringVal = "string`ContainingAQuote"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith_with_quote_in_string() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "'asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith_with_double_quote_in_string() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "\"asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith_with_backtick_in_string() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "`asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasdfasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith_with_quote_in_string() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasd'fasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith_with_double_quote_in_string() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasd\"fasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith_with_backtick_in_string() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasd`fasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/UnaryExpressionsTest.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/UnaryExpressionsTest.cs deleted file mode 100644 index f4812a9b8..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/UnaryExpressionsTest.cs +++ /dev/null @@ -1,255 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions -{ - public class UnaryExpressionsTest : ExpressionsTestBase - { - #region constants - - [Test] - public void Can_select_unary_plus_constant_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == +12); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_unary_minus_constant_expression() - { - var expected = new TestType() - { - IntColumn = -12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == -12); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_unary_not_constant_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == !true); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_unary_not_constant_expression2() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => !q.BoolColumn); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - #endregion - - #region variables - - [Test] - public void Can_select_unary_plus_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var intVal = +12; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == intVal); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_unary_minus_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var intVal = -12; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = -12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == intVal); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_unary_not_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var boolVal = true; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == !boolVal); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_unary_cast_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - object intVal = 12; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == (int) intVal); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - #endregion - - #region method - - [Test] - public void Can_select_unary_not_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.BoolColumn == !GetValue(true)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } - - [Test] - public void Can_select_unary_cast_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - using (var con = OpenDbConnection()) - { - var actual = con.Select(q => q.IntColumn == (int) GetValue((object) 12)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } - - #endregion - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/ForeignKeyAttributeTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/ForeignKeyAttributeTests.cs deleted file mode 100644 index 7b90b9f9b..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/ForeignKeyAttributeTests.cs +++ /dev/null @@ -1,189 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - [TestFixture] - public class ForeignKeyAttributeTests : OrmLiteTestBase - { - public ForeignKeyAttributeTests() : base(Dialect.PostgreSql) { } - - [TestFixtureSetUp] - public void Setup() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateSimpleForeignKey() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascade() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CascadesOnDelete() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - - dbConn.Save(new ReferencedType { Id = 1 }); - dbConn.Save(new TypeWithOnDeleteCascade { RefId = 1 }); - - Assert.AreEqual(1, dbConn.Select().Count); - Assert.AreEqual(1, dbConn.Select().Count); - - dbConn.Delete(r => r.Id == 1); - - Assert.AreEqual(0, dbConn.Select().Count); - Assert.AreEqual(0, dbConn.Select().Count); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteNoAction() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteRestrict() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteSetDefault() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteSetNull() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [TestFixtureTearDown] - public void TearDwon() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - } - } - } - - public class ReferencedType - { - public int Id { get; set; } - } - - - public class TypeWithSimpleForeignKey - { - [AutoIncrement] - public int Id { get; set; } - [References(typeof(ReferencedType))] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteAndUpdateCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteNoAction - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteRestrict - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteSetDefault - { - [AutoIncrement] - public int Id { get; set; } - - [Default(typeof(int), "17")] - [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT")] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteSetNull - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL")] - public int? RefId { get; set; } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteCreateTableWithNamigStrategyTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteCreateTableWithNamigStrategyTests.cs deleted file mode 100644 index 25b48fbd4..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteCreateTableWithNamigStrategyTests.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System; -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; - - -namespace ServiceStack.OrmLite.Tests -{ - - [TestFixture] - public class OrmLiteCreateTableWithNamigStrategyTests - : OrmLiteTestBase - { - public OrmLiteCreateTableWithNamigStrategyTests() : base(Dialect.PostgreSql) { } - - [Test] - public void Can_create_TableWithNamigStrategy_table_prefix() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix ="tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - [Test] - public void Can_create_TableWithNamigStrategy_table_lowered() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new LowercaseNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - - [Test] - public void Can_create_TableWithNamigStrategy_table_nameUnderscoreCoumpound() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new UnderscoreSeparatedCompoundNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - [Test] - public void Can_get_data_from_TableWithNamigStrategy_with_GetById() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id= "999", AlbumId = "112", AlbumName="ElectroShip", Name = "MyNameIsBatman"}; - - db.Save(m); - var modelFromDb = db.SingleById("999"); - - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - - [Test] - public void Can_get_data_from_TableWithNamigStrategy_with_query_by_example() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - - [Test] - public void Can_get_data_from_TableWithNamigStrategy_AfterChangingNamingStrategy() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - - modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - - modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - - modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - } - - } - - public class PrefixNamingStrategy : OrmLiteNamingStrategyBase - { - - public string TablePrefix { get; set; } - - public string ColumnPrefix { get; set; } - - public override string GetTableName(string name) - { - return TablePrefix + name; - } - - public override string GetColumnName(string name) - { - return ColumnPrefix + name; - } - - } - - public class LowercaseNamingStrategy : OrmLiteNamingStrategyBase - { - - public override string GetTableName(string name) - { - return name.ToLower(); - } - - public override string GetColumnName(string name) - { - return name.ToLower(); - } - - } - - public class UnderscoreSeparatedCompoundNamingStrategy : OrmLiteNamingStrategyBase - { - - public override string GetTableName(string name) - { - return toUnderscoreSeparatedCompound(name); - } - - public override string GetColumnName(string name) - { - return toUnderscoreSeparatedCompound(name); - } - - - string toUnderscoreSeparatedCompound(string name) - { - - string r = char.ToLower(name[0]).ToString(); - - for (int i = 1; i < name.Length; i++) - { - char c = name[i]; - if (char.IsUpper(name[i])) - { - r += "_"; - r += char.ToLower(name[i]); - } - else - { - r += name[i]; - } - } - return r; - } - - } - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteDropTableWithNamingStrategyTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteDropTableWithNamingStrategyTests.cs deleted file mode 100644 index 11f2baa32..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteDropTableWithNamingStrategyTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - public class OrmLiteDropTableWithNamingStrategyTests - : OrmLiteTestBase - { - public OrmLiteDropTableWithNamingStrategyTests() : base(Dialect.PostgreSql) { } - - [Test] - public void Can_drop_TableWithNamigStrategy_table_PostgreSqlNamingStrategy() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new PostgreSqlNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - db.DropTable(); - Assert.False(db.TableExists("model_with_only_string_fields")); - } - - OrmLiteConfig.DialectProvider.NamingStrategy = new OrmLiteNamingStrategyBase(); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteExecuteProcedureTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteExecuteProcedureTests.cs deleted file mode 100644 index 0a2ae9582..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteExecuteProcedureTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Tests; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - [TestFixture] - public class OrmLiteExecuteProcedureTests : OrmLiteTestBase - { - public OrmLiteExecuteProcedureTests() : base(Dialect.PostgreSql) { } - - private const string Create = @" - CREATE OR REPLACE FUNCTION f_service_stack( - v_string_values text[], - v_integer_values integer[] - ) RETURNS BOOLEAN AS - $BODY$ - BEGIN - IF v_string_values[1] <> 'ServiceStack' THEN - RAISE EXCEPTION 'Unexpected value in string array[1] %', v_string_values[1]; - END IF; - IF v_string_values[2] <> 'Thoughtfully Architected' THEN - RAISE EXCEPTION 'Unexpected value in string array[2] %', v_string_values[2]; - END IF; - IF v_integer_values[1] <> 1 THEN - RAISE EXCEPTION 'Unexpected value in integer array[1] %', v_integer_values[1]; - END IF; - IF v_integer_values[2] <> 2 THEN - RAISE EXCEPTION 'Unexpected value in integer array[2] %', v_integer_values[2]; - END IF; - IF v_integer_values[3] <> 3 THEN - RAISE EXCEPTION 'Unexpected value in integer array[3] %', v_integer_values[3]; - END IF; - RETURN TRUE; - END; - $BODY$ - LANGUAGE plpgsql VOLATILE COST 100; - "; - - private const string Drop = "DROP FUNCTION f_service_stack(text[], integer[]);"; - - [Alias("f_service_stack")] - public class ServiceStackFunction - { - [CustomField("text[]")] - public string[] StringValues { get; set; } - [CustomField("integer[]")] - public int[] IntegerValues { get; set; } - } - - [Test] - public void Can_execute_stored_procedure_with_array_arguments() - { - using (var db = OpenDbConnection()) - { - db.ExecuteSql(Create); - db.GetLastSql().Print(); - - db.ExecuteProcedure(new ServiceStackFunction - { - StringValues = new[] { "ServiceStack", "Thoughtfully Architected" }, - IntegerValues = new[] { 1, 2, 3 } - }); - - db.ExecuteSql(Drop); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteGetScalarTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteGetScalarTests.cs deleted file mode 100644 index 0cb145752..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteGetScalarTests.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class OrmLiteGetScalarTests:OrmLiteTestBase - { - public OrmLiteGetScalarTests() : base(Dialect.PostgreSql) { } - - [Test] - public void Can_get_scalar_value(){ - - List authors = new List(); - authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London", FloatProperty=10.25f, DoubleProperty=3.23 }); - authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota",FloatProperty=7.59f,DoubleProperty=4.23 }); - authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London",FloatProperty=15.5f,DoubleProperty=5.42 }); - authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota",FloatProperty=0.57f, DoubleProperty=8.76}); - authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=8.43f, DoubleProperty=7.35}); - authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=1.25f, DoubleProperty=0.3652}); - authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota", FloatProperty=1.5f, DoubleProperty=100.563}); - authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena", FloatProperty=3.5f,DoubleProperty=7.23 }); - authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena", FloatProperty=0.25f,DoubleProperty=9.23 }); - authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London", FloatProperty=9.95f,DoubleProperty=4.91 }); - authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin",FloatProperty=4.44f,DoubleProperty=6.41 }); - authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid", FloatProperty=6.67f, DoubleProperty=8.05 }); - authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid", FloatProperty=1.25f, DoubleProperty=3.99}); - authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, - City = "Mexico", - LastActivity= DateTime.Today, - NRate=5, - FloatProperty=1.25f, - NFloatProperty=3.15f, - DoubleProperty= 1.25, - NDoubleProperty= 8.25 - }); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - db.DeleteAll(); - - db.InsertAll(authors); - - var expectedDate = authors.Max(e=>e.Birthday); - var r1 = db.Scalar( e => Sql.Max(e.Birthday) ); - Assert.That(expectedDate, Is.EqualTo(r1)); - - expectedDate = authors.Where(e=>e.City=="London").Max(e=>e.Birthday); - r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="London" ); - Assert.That(expectedDate, Is.EqualTo(r1)); - - r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="SinCity" ); - Assert.That( default(DateTime), Is.EqualTo(r1)); - - - var expectedNullableDate= authors.Max(e=>e.LastActivity); - DateTime? r2 = db.Scalar(e=> Sql.Max(e.LastActivity)); - Assert.That(expectedNullableDate, Is.EqualTo(r2)); - - expectedNullableDate= authors.Where(e=> e.City=="Bogota").Max(e=>e.LastActivity); - r2 = db.Scalar( - e=> Sql.Max(e.LastActivity), - e=> e.City=="Bogota" ); - Assert.That(expectedNullableDate, Is.EqualTo(r2)); - - r2 = db.Scalar( e => Sql.Max(e.LastActivity), e=>e.City=="SinCity" ); - Assert.That( default(DateTime?), Is.EqualTo(r2)); - - - var expectedDecimal= authors.Max(e=>e.Earnings); - decimal r3 = db.Scalar(e=> Sql.Max(e.Earnings)); - Assert.That(expectedDecimal, Is.EqualTo(r3)); - - expectedDecimal= authors.Where(e=>e.City=="London").Max(e=>e.Earnings); - r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="London"); - Assert.That(expectedDecimal, Is.EqualTo(r3)); - - r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="SinCity"); - Assert.That( default(decimal), Is.EqualTo(r3)); - - - var expectedNullableDecimal= authors.Max(e=>e.NEarnings); - decimal? r4 = db.Scalar(e=> Sql.Max(e.NEarnings)); - Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); - - expectedNullableDecimal= authors.Where(e=>e.City=="London").Max(e=>e.NEarnings); - r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="London"); - Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); - - r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="SinCity"); - Assert.That( default(decimal?), Is.EqualTo(r4)); - - - var expectedDouble =authors.Max(e=>e.DoubleProperty); - double r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty)); - Assert.That(expectedDouble, Is.EqualTo(r5)); - - expectedDouble =authors.Where(e=>e.City=="London").Max(e=>e.DoubleProperty); - r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="London"); - Assert.That(expectedDouble, Is.EqualTo(r5)); - - r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="SinCity"); - Assert.That(default(double),Is.EqualTo(r5)); - - - var expectedNullableDouble =authors.Max(e=>e.NDoubleProperty); - double? r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty)); - Assert.That(expectedNullableDouble, Is.EqualTo(r6)); - - - expectedNullableDouble =authors.Where(e=>e.City=="London").Max(e=>e.NDoubleProperty); - r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="London"); - Assert.That(expectedNullableDouble, Is.EqualTo(r6)); - - r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="SinCity"); - Assert.That(default(double?),Is.EqualTo(r6)); - - - - var expectedFloat =authors.Max(e=>e.FloatProperty); - var r7 = db.Scalar(e=> Sql.Max(e.FloatProperty)); - Assert.That(expectedFloat, Is.EqualTo(r7)); - - expectedFloat =authors.Where(e=>e.City=="London").Max(e=>e.FloatProperty); - r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="London"); - Assert.That(expectedFloat, Is.EqualTo(r7)); - - r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="SinCity"); - Assert.That(default(float),Is.EqualTo(r7)); - - - var expectedNullableFloat =authors.Max(e=>e.NFloatProperty); - var r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty)); - Assert.That(expectedNullableFloat, Is.EqualTo(r8)); - - expectedNullableFloat =authors.Where(e=>e.City=="London").Max(e=>e.NFloatProperty); - r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="London"); - Assert.That(expectedNullableFloat, Is.EqualTo(r8)); - - r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="SinCity"); - Assert.That(default(float?),Is.EqualTo(r8)); - - - var expectedString=authors.Min(e=>e.Name); - var r9 = db.Scalar(e=> Sql.Min(e.Name)); - Assert.That(expectedString, Is.EqualTo(r9)); - - expectedString=authors.Where(e=>e.City=="London").Min(e=>e.Name); - r9 = db.Scalar(e=> Sql.Min(e.Name), e=>e.City=="London"); - Assert.That(expectedString, Is.EqualTo(r9)); - - r9 = db.Scalar(e=> Sql.Max(e.Name), e=>e.City=="SinCity"); - Assert.IsNullOrEmpty(r9); - - //var expectedBool=authors.Min(e=>e.Active); - //var r10 = db.GetScalar(e=> Sql.Min(e.Active)); - //Assert.That(expectedBool, Is.EqualTo(r10)); - - //expectedBool=authors.Max(e=>e.Active); - //r10 = db.GetScalar(e=> Sql.Max(e.Active)); - //Assert.That(expectedBool, Is.EqualTo(r10)); - - //r10 = db.GetScalar(e=> Sql.Max(e.Active), e=>e.City=="SinCity"); - //Assert.IsFalse(r10); - - - - var expectedShort =authors.Max(e=>e.Rate); - var r11 = db.Scalar(e=> Sql.Max(e.Rate)); - Assert.That(expectedShort, Is.EqualTo(r11)); - - expectedShort =authors.Where(e=>e.City=="London").Max(e=>e.Rate); - r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="London"); - Assert.That(expectedShort, Is.EqualTo(r11)); - - r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="SinCity"); - Assert.That(default(short),Is.EqualTo(r7)); - - - var expectedNullableShort =authors.Max(e=>e.NRate); - var r12 = db.Scalar(e=> Sql.Max(e.NRate)); - Assert.That(expectedNullableShort, Is.EqualTo(r12)); - - expectedNullableShort =authors.Where(e=>e.City=="London").Max(e=>e.NRate); - r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="London"); - Assert.That(expectedNullableShort, Is.EqualTo(r12)); - - r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="SinCity"); - Assert.That(default(short?),Is.EqualTo(r12)); - - } - - } - - } - - - public class Author - { - public Author(){} - - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - - public DateTime Birthday { get; set;} - public DateTime? LastActivity { get; set;} - public decimal Earnings { get; set;} - public decimal? NEarnings { get; set;} - - public bool Active { get; set; } - - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - - public short Rate{ get; set;} - public short? NRate{ get; set;} - public float FloatProperty { get; set;} - public float? NFloatProperty { get; set;} - public double DoubleProperty { get; set;} - public double? NDoubleProperty { get; set;} - - } - - -} - diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteSelectTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteSelectTests.cs deleted file mode 100644 index 5e3d445a7..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteSelectTests.cs +++ /dev/null @@ -1,351 +0,0 @@ -using System.Collections.Generic; -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; -using ServiceStack.OrmLite.Tests; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - [TestFixture] - public class OrmLiteSelectTests - : OrmLiteTestBase - { - public OrmLiteSelectTests() : base(Dialect.PostgreSql) { } - - [Test] - public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var row = db.SingleById(1); - - Assert.That(row.Id, Is.EqualTo(1)); - } - } - - [Test] - public void Can_GetById_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var row = db.SingleById("id-1"); - - Assert.That(row.Id, Is.EqualTo("id-1")); - } - } - - [Test] - public void Can_GetByIds_int_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var rows = db.SelectByIds(rowIds); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_GetByIds_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var rows = db.SelectByIds(rowIds); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; - - db.Insert(filterRow); - - var rows = db.SelectFmt("\"album_name\" = {0}", filterRow.AlbumName); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } - - [Test] - public void Can_select_scalar_value() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var count = db.ScalarFmt("SELECT COUNT(*) FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); - - Assert.That(count, Is.EqualTo(n)); - } - } - - [Test] - public void Can_loop_each_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var dbRowIds = new List(); - foreach (var row in db.SelectLazy()) - { - dbRowIds.Add(row.Id); - } - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; - - db.Insert(filterRow); - db.GetLastSql().Print(); - - var dbRowIds = new List(); - var rows = db.SelectLazyFmt("\"album_name\" = {0}", filterRow.AlbumName); - foreach (var row in rows) - { - dbRowIds.Add(row.Id); - } - - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } - - [Test] - public void Can_GetFirstColumn() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var ids = db.ColumnFmt("SELECT \"id\" FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); - - Assert.That(ids.Count, Is.EqualTo(n)); - } - } - - [Test] - public void Can_GetFirstColumnDistinct() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var ids = db.ColumnDistinctFmt("SELECT \"id\" FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); - - Assert.That(ids.Count, Is.EqualTo(n)); - } - } - - [Test] - public void Can_GetLookup() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => { - var row = ModelWithIdAndName.Create(x); - row.Name = x % 2 == 0 ? "OddGroup" : "EvenGroup"; - db.Insert(row); - }); - - var lookup = db.LookupFmt("SELECT \"name\", \"id\" FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); - - Assert.That(lookup, Has.Count.EqualTo(2)); - Assert.That(lookup["OddGroup"], Has.Count.EqualTo(3)); - Assert.That(lookup["EvenGroup"], Has.Count.EqualTo(2)); - } - } - - [Test] - public void Can_GetDictionary() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var dictionary = db.Dictionary("SELECT \"id\", \"name\" FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); - - Assert.That(dictionary, Has.Count.EqualTo(5)); - - //Console.Write(dictionary.Dump()); - } - } - - [Test] - public void Can_Select_subset_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var rows = db.SelectFmt("SELECT \"id\", \"name\" FROM {0}" - .Fmt("ModelWithFieldsOfDifferentTypes".SqlTable())); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_Query_ModelWithFieldsOfDifferentTypes_with_dictionary_parameters() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var rows = db.Select("SELECT * FROM {0} where \"id\" = :Id " - .Fmt("ModelWithFieldsOfDifferentTypes".SqlTable()), - new Dictionary { {"Id", 3} }); - - Assert.AreEqual(rows.Count, 1); - Assert.AreEqual(rows[0].Id, 3); - } - } - - [Test] - public void Can_Select_Into_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var rowIds = new List(new[] { 1, 2, 3 }); - - rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - - var rows = db.Select(typeof(ModelWithFieldsOfDifferentTypes)); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_Select_In_for_string_value() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var selectInNames = new[] {"Name1", "Name2"}; - var rows = db.SelectFmt("\"name\" IN ({0})", selectInNames.SqlInValues()); - - Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); - } - } - - [Test] - public void Can_Select_With_Subquery() - { - const int n = 5; - - using (var db = OpenDbConnection()) - { - db.CreateTable(); - - n.Times(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(n))); - - var sql = @" - WITH max_id AS ( - SELECT 3 AS three) - SELECT * - FROM {0} - WHERE id <= (SELECT three FROM max_id)".Fmt("ModelWithFieldsOfDifferentTypes".SqlTable()); - - var rows = db.SqlList(sql); - - Assert.That(rows.Count, Is.EqualTo((3))); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlArrayTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlArrayTests.cs deleted file mode 100644 index 90d347691..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlArrayTests.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Linq; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Tests; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - public class ModelWithArrayType - { - public int Id { get; set; } - - [CustomField("integer[]")] - public int[] IntegerArray { get; set; } - - [CustomField("bigint[]")] - public long[] BigIntegerArray { get; set; } - } - - [TestFixture] - public class PostgreSqlArrayTests : OrmLiteTestBase - { - public PostgreSqlArrayTests() : base(Dialect.PostgreSql) {} - - [Test] - public void Can_save_integer_array() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - db.GetLastSql().Print(); - - var row = new ModelWithArrayType - { - Id = 1, - IntegerArray = new []{1,2,3} - }; - - try - { - db.Insert(row); - } - catch (Exception e) - { - e.Message.Print(); - } - - var result = db.Select(); - - Assert.That(result.Count, Is.EqualTo(1)); - Assert.That(result[0].IntegerArray.Count(), Is.EqualTo(3)); - } - } - - [Test] - public void Can_save_big_integer_array() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - db.GetLastSql().Print(); - - var row = new ModelWithArrayType - { - Id = 2, - BigIntegerArray = new long[] { 1, 2, 3, 4 } - }; - - try - { - db.Insert(row); - } - catch (Exception e) - { - e.Message.Print(); - } - - var result = db.Select(); - - Assert.That(result.Count, Is.EqualTo(1)); - Assert.That(result[0].BigIntegerArray.Count(), Is.EqualTo(4)); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlJsonTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlJsonTests.cs deleted file mode 100644 index 998f8d0eb..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlJsonTests.cs +++ /dev/null @@ -1,69 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Tests; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - public class ModelWithJsonType - { - public int Id { get; set; } - - [CustomField("json")] - public ComplexType ComplexTypeJson { get; set; } - } - - public class ComplexType - { - public int Id { get; set; } - public SubType SubType { get; set; } - } - - public class SubType - { - public string Name { get; set; } - } - - - [TestFixture] - public class PostgreSqlJsonTests : OrmLiteTestBase - { - public PostgreSqlJsonTests() : base(Dialect.PostgreSql) {} - - [Test] - public void Can_save_complex_types_as_JSON() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - db.GetLastSql().Print(); - - var row = new ModelWithJsonType - { - Id = 1, - ComplexTypeJson = new ComplexType - { - Id = 2, SubType = new SubType { Name = "SubType2" } - }, - //ComplexTypeJsonb = new ComplexType - //{ - // Id = 3, SubType = new SubType { Name = "SubType3" } - //}, - }; - - db.Insert(row); - - var result = db.Select( - "complex_type_json->'SubType'->>'Name' = 'SubType2'"); - - db.GetLastSql().Print(); - - Assert.That(result.Count, Is.EqualTo(1)); - Assert.That(result[0].Id, Is.EqualTo(1)); - Assert.That(result[0].ComplexTypeJson.Id, Is.EqualTo(2)); - Assert.That(result[0].ComplexTypeJson.SubType.Name, Is.EqualTo("SubType2")); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 0799e3f2d..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.PostgreSQL.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.PostgreSQL.Tests")] -[assembly: AssemblyCopyright("Copyright © Tomasz Kubacki 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("38883b7a-520a-46dc-86dd-87d4ea07d9e9")] - diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/SchemaTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/SchemaTests.cs deleted file mode 100644 index 1d766ecca..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/SchemaTests.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class SchemaTests : OrmLiteTestBase - { - public SchemaTests() : base(Dialect.PostgreSql){} - - [Alias("Users")] - [Schema("TestSchema")] - public class User - { - [AutoIncrement] - public int Id { get; set; } - - [Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - } - - private void CreateSchemaIfNotExists(System.Data.IDbConnection db) - { - const string createSchemaSQL = @"DO $$ -BEGIN - - IF NOT EXISTS( - SELECT schema_name - FROM information_schema.schemata - WHERE schema_name = 'TestSchema' - ) - THEN - EXECUTE 'CREATE SCHEMA ""TestSchema""'; - END IF; - -END -$$;"; - db.ExecuteSql(createSchemaSQL); - } - - [Test] - public void Can_Create_Tables_With_Schema_in_PostgreSQL() - { - using (var db = OpenDbConnection()) - using (var dbCmd = db.CreateCommand()) - { - CreateSchemaIfNotExists(db); - db.DropAndCreateTable(); - - var tables = db.ColumnFmt - (@"SELECT '[' || n.nspname || '].[' || c.relname ||']' FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relname = 'Users' AND n.nspname = 'TestSchema'"); - - //PostgreSQL dialect should create the table in the schema - Assert.That(tables.Contains("[TestSchema].[Users]")); - } - } - - [Test] - public void Can_Perform_CRUD_Operations_On_Table_With_Schema() - { - using (var db = OpenDbConnection()) - using (var dbCmd = db.CreateCommand()) - { - CreateSchemaIfNotExists(db); - db.CreateTable(true); - - db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now }); - db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); - db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - - var lastInsertId = db.LastInsertId(); - Assert.That(lastInsertId, Is.GreaterThan(0)); - - var rowsB = db.SelectFmt("\"Name\" = {0}", "B"); - Assert.That(rowsB, Has.Count.EqualTo(2)); - - var rowIds = rowsB.ConvertAll(x => x.Id); - Assert.That(rowIds, Is.EquivalentTo(new List { 2, 3 })); - - rowsB.ForEach(x => db.Delete(x)); - - rowsB = db.SelectFmt("\"Name\" = {0}", "B"); - Assert.That(rowsB, Has.Count.EqualTo(0)); - - var rowsLeft = db.Select(); - Assert.That(rowsLeft, Has.Count.EqualTo(1)); - - Assert.That(rowsLeft[0].Name, Is.EqualTo("A")); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/ServiceStack.OrmLite.PostgreSQL.Tests.csproj b/src/ServiceStack.OrmLite.PostgreSQL.Tests/ServiceStack.OrmLite.PostgreSQL.Tests.csproj deleted file mode 100644 index 90caccaab..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/ServiceStack.OrmLite.PostgreSQL.Tests.csproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {E692B423-82E9-46DE-AA80-F4E36A4B4D56} - Library - Properties - ServiceStack.OrmLite.PostgreSQL.Tests - ServiceStack.OrmLite.PostgreSQL.Tests - v4.5 - 512 - - ..\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - false - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - - False - ..\packages\Npgsql.2.2.3\lib\net45\Mono.Security.dll - - - False - ..\packages\Npgsql.2.2.3\lib\net45\Npgsql.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - - - - - - - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - - - - {9b64f4a7-c008-46a8-ad6f-99626dcfefbd} - ServiceStack.OrmLite.Tests - - - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5} - ServiceStack.OrmLite.PostgreSQL - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/TypeWithByteArrayFieldTests.cs b/src/ServiceStack.OrmLite.PostgreSQL.Tests/TypeWithByteArrayFieldTests.cs deleted file mode 100644 index eb3c2aa84..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/TypeWithByteArrayFieldTests.cs +++ /dev/null @@ -1,151 +0,0 @@ -using NUnit.Framework; -using ServiceStack.OrmLite.Tests; - -namespace ServiceStack.OrmLite.PostgreSQL.Tests -{ - public class TypeWithByteArrayFieldTests : OrmLiteTestBase - { - public TypeWithByteArrayFieldTests() : base(Dialect.PostgreSql) { } - TypeWithByteArrayField getSampleObject() - { - var testByteArray = new byte[256]; - for(int i = 0; i < 256; i++) { testByteArray[i] = (byte)i; } - - return new TypeWithByteArrayField { Id = 1, Content = testByteArray }; - } - - [Test] - public void CanInsertAndSelectByteArray() - { - var orig = getSampleObject(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Save(orig); - - var target = db.SingleById(orig.Id); - - Assert.AreEqual(orig.Id, target.Id); - Assert.AreEqual(orig.Content, target.Content); - } - } - - [Test] - public void CanInsertAndSelectByteArray__manual_insert__manual_select() - { - var orig = getSampleObject(); - - using(var db = OpenDbConnection()) { - //insert and select manually - ok - db.CreateTable(true); - _insertManually(orig, db); - - _selectAndVerifyManually(orig, db); - } - } - - [Test] - public void CanInsertAndSelectByteArray__InsertParam_insert__manual_select() - { - var orig = getSampleObject(); - - using(var db = OpenDbConnection()) { - //insert using InsertParam, and select manually - ok - db.CreateTable(true); - db.Insert(orig); - - _selectAndVerifyManually(orig, db); - } - } - - [Test] - public void CanInsertAndSelectByteArray__InsertParam_insert__GetById_select() - { - var orig = getSampleObject(); - - using(var db = OpenDbConnection()) { - //InsertParam + GetByID - fails - db.CreateTable(true); - db.Insert(orig); - - var target = db.SingleById(orig.Id); - - Assert.AreEqual(orig.Id, target.Id); - Assert.AreEqual(orig.Content, target.Content); - } - } - - [Test] - public void CanInsertAndSelectByteArray__Insert_insert__GetById_select() - { - var orig = getSampleObject(); - - using(var db = OpenDbConnection()) { - //InsertParam + GetByID - fails - db.CreateTable(true); - db.Insert(orig); - - var target = db.SingleById(orig.Id); - - Assert.AreEqual(orig.Id, target.Id); - Assert.AreEqual(orig.Content, target.Content); - } - } - - [Test] - public void CanInsertAndSelectByteArray__Insert_insert__manual_select() - { - var orig = getSampleObject(); - - using(var db = OpenDbConnection()) { - //InsertParam + GetByID - fails - db.CreateTable(true); - db.Insert(orig); - - _selectAndVerifyManually(orig, db); - } - } - - private static void _selectAndVerifyManually(TypeWithByteArrayField orig, System.Data.IDbConnection db) - { - using(var cmd = db.CreateCommand()) { - cmd.CommandText = @"select ""content"" from ""type_with_byte_array_field"" where ""id"" = 1 --manual select"; - using(var reader = cmd.ExecuteReader()) { - reader.Read(); - var ba = reader["content"] as byte[]; - Assert.AreEqual(orig.Content.Length, ba.Length); - Assert.AreEqual(orig.Content, ba); - } - } - } - - private static void _insertManually(TypeWithByteArrayField orig, System.Data.IDbConnection db) - { - using(var cmd = db.CreateCommand()) { - cmd.CommandText = @"INSERT INTO ""type_with_byte_array_field"" (""id"",""content"") VALUES (@Id, @Content) --manual parameterized insert"; - - var p_id = cmd.CreateParameter(); - p_id.ParameterName = "@Id"; - p_id.Value = orig.Id; - - cmd.Parameters.Add(p_id); - - var p_content = cmd.CreateParameter(); - p_content.ParameterName = "@Content"; - p_content.Value = orig.Content; - - cmd.Parameters.Add(p_content); - - cmd.ExecuteNonQuery(); - } - } - } - - class TypeWithByteArrayField - { - public int Id { get; set; } - public byte[] Content { get; set; } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/app.config b/src/ServiceStack.OrmLite.PostgreSQL.Tests/app.config deleted file mode 100644 index 007e1545e..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/app.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/packages.config b/src/ServiceStack.OrmLite.PostgreSQL.Tests/packages.config deleted file mode 100644 index 6780ed6d8..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlArrayConverters.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlArrayConverters.cs new file mode 100644 index 000000000..5ff1158ee --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlArrayConverters.cs @@ -0,0 +1,135 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostrgreSqlByteArrayConverter : ByteArrayConverter + { + public override string ColumnDefinition => "BYTEA"; + + public override string ToQuotedString(Type fieldType, object value) + { + return "E'" + this.ToBinary(value) + "'"; + } + } + + public class PostgreSqlStringArrayConverter : ReferenceTypeConverter + { + public override string ColumnDefinition => "text[]"; + + public override DbType DbType => DbType.Object; + + public override string GetColumnDefinition(int? stringLength) + { + return stringLength != null + ? base.GetColumnDefinition(stringLength) + : ColumnDefinition; + } + + public override string ToQuotedString(Type fieldType, object value) + { + var stringArray = (string[])value; + return this.ToArray(stringArray); + } + + public override object ToDbValue(Type fieldType, object value) + { + return fieldType == typeof(string[]) + ? value + : DialectProvider.StringSerializer.SerializeToString(value); + } + + public override object FromDbValue(Type fieldType, object value) + { + return value is string strVal + ? strVal.FromJson() + : value; + } + } + + public abstract class PostgreSqlArrayConverterBase : NativeValueOrmLiteConverter + { + public override DbType DbType => DbType.Object; + + public override string ToQuotedString(Type fieldType, object value) + { + var integerArray = (T[])value; + return this.ToArray(integerArray); + } + } + + public class PostgreSqlShortArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "short[]"; + } + + public class PostgreSqlIntArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "integer[]"; + } + + public class PostgreSqlLongArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "bigint[]"; + } + + public class PostgreSqlFloatArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "real[]"; + } + + public class PostgreSqlDoubleArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "double precision[]"; + } + + public class PostgreSqlDecimalArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "numeric[]"; + } + + public class PostgreSqlDateTimeTimeStampArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "timestamp[]"; + } + + public class PostgreSqlDateTimeOffsetTimeStampTzArrayConverter : PostgreSqlArrayConverterBase + { + public override string ColumnDefinition => "timestamp with time zone[]"; + } + + + public static class PostgreSqlConverterExtensions + { + /// + /// based on Npgsql2's source: Npgsql2\src\NpgsqlTypes\NpgsqlTypeConverters.cs + /// + public static string ToBinary(this IOrmLiteConverter converter, object NativeData) + { + var byteArray = (byte[])NativeData; + var res = StringBuilderCache.Allocate(); + foreach (byte b in byteArray) + if (b >= 0x20 && b < 0x7F && b != 0x27 && b != 0x5C) + res.Append((char)b); + else + res.Append("\\\\") + .Append((char)('0' + (7 & (b >> 6)))) + .Append((char)('0' + (7 & (b >> 3)))) + .Append((char)('0' + (7 & b))); + return StringBuilderCache.ReturnAndFree(res); + } + + public static string ToArray(this IOrmLiteConverter converter, T[] source) + { + var values = StringBuilderCache.Allocate(); + foreach (var value in source) + { + if (values.Length > 0) values.Append(","); + values.Append(converter.DialectProvider.GetQuotedValue(value, typeof(T))); + } + return "{" + StringBuilderCache.ReturnAndFree(values) + "}"; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlBoolConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlBoolConverter.cs new file mode 100644 index 000000000..46903c51f --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlBoolConverter.cs @@ -0,0 +1,13 @@ +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlBoolConverter : BoolConverter + { + public override string ColumnDefinition + { + get { return "BOOLEAN"; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateOnlyConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateOnlyConverter.cs new file mode 100644 index 000000000..d0a46d047 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateOnlyConverter.cs @@ -0,0 +1,34 @@ +using System; +using ServiceStack.OrmLite.Converters; + +#if NET6_0 +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlDateOnlyConverter : PostgreSqlDateTimeConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + var dateOnly = (DateOnly)value; + return DateTimeFmt(dateOnly.ToDateTime(default, DateTimeKind.Utc), "yyyy-MM-dd HH:mm:ss.fff"); + } + + public override object ToDbValue(Type fieldType, object value) + { + var dateOnly = (DateOnly)value; + var dateTime = dateOnly.ToDateTime(default, DateTimeKind.Utc); + if (dateTime.Kind != DateTimeKind.Utc) + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); + return dateTime; + } + + public override object FromDbValue(object value) + { + var dateTime = (DateTime)base.FromDbValue(value); + if (dateTime.Kind == DateTimeKind.Unspecified) + dateTime = dateTime.ToLocalTime(); + var dateOnly = DateOnly.FromDateTime(dateTime); + return dateOnly; + } + } +} +#endif diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateTimeConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateTimeConverter.cs new file mode 100644 index 000000000..9349d272b --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateTimeConverter.cs @@ -0,0 +1,9 @@ +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlDateTimeConverter : DateTimeConverter + { + public override string ColumnDefinition => "timestamp"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateTimeOffsetConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateTimeOffsetConverter.cs new file mode 100644 index 000000000..d411536c5 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDateTimeOffsetConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Globalization; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlDateTimeOffsetConverter : DateTimeOffsetConverter + { + public override string ColumnDefinition => "timestamp with time zone"; + + public override string ToQuotedString(Type fieldType, object value) + { + var dateValue = (DateTimeOffset) value; + const string iso8601Format = "yyyy-MM-dd HH:mm:ss.fff zzz"; + return base.DialectProvider.GetQuotedValue(dateValue.ToString(iso8601Format, CultureInfo.InvariantCulture), typeof(string)); + } + + public override object ToDbValue(Type fieldType, object value) + { + return value; + } + } +} diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDecimalConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDecimalConverter.cs new file mode 100644 index 000000000..34f9ba753 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlDecimalConverter.cs @@ -0,0 +1,29 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlDecimalConverter : DecimalConverter + { + public PostgreSqlDecimalConverter() : base(38, 6) { } + + public override string GetColumnDefinition(int? precision, int? scale) + { + return $"NUMERIC({precision.GetValueOrDefault(Precision)},{scale.GetValueOrDefault(Scale)})"; + } + + public override object GetValue(IDataReader reader, int columnIndex, object[] values) + { + try + { + return base.GetValue(reader, columnIndex, values); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlGuidConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlGuidConverter.cs new file mode 100644 index 000000000..6d1d398e3 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlGuidConverter.cs @@ -0,0 +1,20 @@ + +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlGuidConverter : GuidConverter + { + public override string ColumnDefinition + { + get { return "UUID"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var guidValue = (Guid)value; + return base.DialectProvider.GetQuotedValue(guidValue.ToString("N"), typeof(string)); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlHstoreConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlHstoreConverter.cs new file mode 100644 index 000000000..d4fc19e23 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlHstoreConverter.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Data; +using Npgsql; +using NpgsqlTypes; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlHstoreConverter : ReferenceTypeConverter + { + public override string ColumnDefinition => "hstore"; + + public override DbType DbType => DbType.Object; + + public override object FromDbValue(Type fieldType, object value) + { + return (IDictionary)value; + } + + public override object ToDbValue(Type fieldType, object value) + { + return (IDictionary)value; + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + var sqlParam = (NpgsqlParameter)p; + sqlParam.NpgsqlDbType = NpgsqlDbType.Hstore; + base.InitDbParam(p, fieldType); + } + + public override string GetColumnDefinition(int? stringLength) => ColumnDefinition; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlIntegerConverters.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlIntegerConverters.cs new file mode 100644 index 000000000..2fe3304ab --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlIntegerConverters.cs @@ -0,0 +1,42 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + //throws unknown type exceptions in parameterized queries, e.g: p.DbType = DbType.SByte + public class PostrgreSqlSByteConverter : SByteConverter + { + public override DbType DbType => DbType.Byte; + } + + public class PostrgreSqlUInt16Converter : UInt16Converter + { + public override DbType DbType => DbType.Int16; + + public override object ToDbValue(Type fieldType, object value) + { + return this.ConvertNumber(typeof(short), value); + } + } + + public class PostrgreSqlUInt32Converter : UInt32Converter + { + public override DbType DbType => DbType.Int32; + + public override object ToDbValue(Type fieldType, object value) + { + return this.ConvertNumber(typeof(int), value); + } + } + + public class PostrgreSqlUInt64Converter : UInt64Converter + { + public override DbType DbType => DbType.Int64; + + public override object ToDbValue(Type fieldType, object value) + { + return this.ConvertNumber(typeof(long), value); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlRowVersionConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlRowVersionConverter.cs new file mode 100644 index 000000000..69e0e0a52 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlRowVersionConverter.cs @@ -0,0 +1,22 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlRowVersionConverter : RowVersionConverter + { + public override object ToDbValue(Type fieldType, object value) + { + var ret = base.ToDbValue(fieldType, value); + if (ret is ulong u) + return (long) u; + return ret; + } + + public override object FromDbValue(Type fieldType, object value) + { + var ret = base.FromDbValue(fieldType, value); + return ret; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlStringConverters.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlStringConverters.cs new file mode 100644 index 000000000..04dde919c --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlStringConverters.cs @@ -0,0 +1,34 @@ +using System; +using System.Text; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlStringConverter : StringConverter + { + public override string ColumnDefinition => "TEXT"; + + //https://dba.stackexchange.com/questions/189876/size-limit-of-character-varying-postgresql + public override int MaxVarCharLength => UseUnicode ? 10485760 / 2 : 10485760; + + public override string GetColumnDefinition(int? stringLength) + { + //PostgreSQL doesn't support NVARCHAR when UseUnicode = true so just use TEXT + if (stringLength == null || stringLength == StringLengthAttribute.MaxText) + return ColumnDefinition; + + return $"VARCHAR({stringLength.Value})"; + } + } + + public class PostgreSqlCharArrayConverter : CharArrayConverter + { + public override string ColumnDefinition => "TEXT"; + + public override string GetColumnDefinition(int? stringLength) + { + return ColumnDefinition; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlXmlConverter.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlXmlConverter.cs new file mode 100644 index 000000000..128c0c557 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostgreSqlXmlConverter.cs @@ -0,0 +1,14 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostgreSqlXmlConverter : PostgreSqlStringConverter + { + public override string ColumnDefinition => "XML"; + public override void InitDbParam(IDbDataParameter p, Type fieldType) => p.DbType = DbType.Xml; + public override object ToDbValue(Type fieldType, object value) => value?.ToString(); + public override string ToQuotedString(Type fieldType, object value) => + base.ToQuotedString(fieldType, value.ToString()); + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostrgreSqlFloatConverters.cs b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostrgreSqlFloatConverters.cs new file mode 100644 index 000000000..ff3c9cea2 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/Converters/PostrgreSqlFloatConverters.cs @@ -0,0 +1,34 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.PostgreSQL.Converters +{ + public class PostrgreSqlFloatConverter : FloatConverter + { + public override string ColumnDefinition => "DOUBLE PRECISION"; + } + + public class PostrgreSqlDoubleConverter : DoubleConverter + { + public override string ColumnDefinition => "DOUBLE PRECISION"; + } + + public class PostrgreSqlDecimalConverter : DecimalConverter + { + public PostrgreSqlDecimalConverter() + : base(38, 6) {} + + public override object GetValue(IDataReader reader, int columnIndex, object[] values) + { + try + { + return base.GetValue(reader, columnIndex, values); + } + catch (OverflowException) + { + return decimal.MaxValue; + } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/PgSql.cs b/src/ServiceStack.OrmLite.PostgreSQL/PgSql.cs new file mode 100644 index 000000000..abd29ae62 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/PgSql.cs @@ -0,0 +1,20 @@ +using Npgsql; + +namespace ServiceStack.OrmLite.PostgreSQL +{ + public static class PgSql + { + public static NpgsqlParameter Param(string name, T value) => + new NpgsqlParameter(name, PostgreSqlDialect.Instance.GetDbType()) { + Value = value + }; + + public static string Array(params T[] items) => + "ARRAY[" + PostgreSqlDialect.Provider.SqlSpread(items) + "]"; + + public static string Array(T[] items, bool nullIfEmpty) => + nullIfEmpty && (items == null || items.Length == 0) + ? "null" + : "ARRAY[" + PostgreSqlDialect.Provider.SqlSpread(items) + "]"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs index 0289cb2f1..5d5ddaf6a 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs +++ b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs @@ -1,397 +1,847 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -using Npgsql; -using NpgsqlTypes; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.PostgreSQL -{ - public class PostgreSQLDialectProvider : OrmLiteDialectProviderBase - { - public static PostgreSQLDialectProvider Instance = new PostgreSQLDialectProvider(); - const string textColumnDefinition = "text"; - - public bool UseReturningForLastInsertId { get; set; } - - public PostgreSQLDialectProvider() - { - base.AutoIncrementDefinition = ""; - base.IntColumnDefinition = "integer"; - base.BoolColumnDefinition = "boolean"; - base.TimeColumnDefinition = "time"; - base.DateTimeColumnDefinition = "timestamp"; - base.DateTimeOffsetColumnDefinition = "timestamp"; - base.DecimalColumnDefinition = "numeric(38,6)"; - base.GuidColumnDefinition = "uuid"; - base.ParamString = ":"; - base.BlobColumnDefinition = "bytea"; - base.RealColumnDefinition = "double precision"; - base.StringLengthColumnDefinitionFormat = textColumnDefinition; - //there is no "n"varchar in postgres. All strings are either unicode or non-unicode, inherited from the database. - base.StringLengthUnicodeColumnDefinitionFormat = "character varying({0})"; - base.StringLengthNonUnicodeColumnDefinitionFormat = "character varying({0})"; - base.MaxStringColumnDefinition = "TEXT"; - base.InitColumnTypeMap(); - base.SelectIdentitySql = "SELECT LASTVAL()"; - this.UseReturningForLastInsertId = true; - this.NamingStrategy = new PostgreSqlNamingStrategy(); - this.StringSerializer = new JsonStringSerializer(); - } - - public override void OnAfterInitColumnTypeMap() - { - DbTypeMap.Set(DbType.Time, "interval"); - DbTypeMap.Set(DbType.Time, "interval"); - DbTypeMap.Set(DbType.DateTimeOffset, DateTimeOffsetColumnDefinition); - DbTypeMap.Set(DbType.DateTimeOffset, DateTimeOffsetColumnDefinition); - - //throws unknown type exceptions in parameterized queries, e.g: p.DbType = DbType.SByte - DbTypeMap.Set(DbType.Byte, IntColumnDefinition); - DbTypeMap.Set(DbType.Int16, IntColumnDefinition); - DbTypeMap.Set(DbType.Int32, IntColumnDefinition); - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); - - base.OnAfterInitColumnTypeMap(); - } - - public override string GetColumnDefinition( - string fieldName, - Type fieldType, - bool isPrimaryKey, - bool autoIncrement, - bool isNullable, - bool isRowVersion, - int? fieldLength, - int? scale, - string defaultValue, - string customFieldDefinition) - { - if (isRowVersion) - return null; - - string fieldDefinition = null; - if (customFieldDefinition != null) - { - fieldDefinition = customFieldDefinition; - } - else if (fieldType == typeof(string)) - { - fieldDefinition = fieldLength == int.MaxValue - ? MaxStringColumnDefinition - : fieldLength != null ? - string.Format(StringLengthColumnDefinitionFormat, fieldLength) : - textColumnDefinition; - } - else - { - if (autoIncrement) - { - if (fieldType == typeof(long)) - fieldDefinition = "bigserial"; - else if (fieldType == typeof(int)) - fieldDefinition = "serial"; - } - else - { - fieldDefinition = GetColumnTypeDefinition(fieldType); - } - } - - var sql = new StringBuilder(); - sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldName), fieldDefinition); - - if (isPrimaryKey) - { - sql.Append(" PRIMARY KEY"); - } - else - { - if (isNullable) - { - sql.Append(" NULL"); - } - else - { - sql.Append(" NOT NULL"); - } - } - - if (!string.IsNullOrEmpty(defaultValue)) - { - sql.AppendFormat(DefaultValueFormat, defaultValue); - } - - return sql.ToString(); - } - - //Convert xmin into an integer so it can be used in comparisons - public const string RowVersionFieldComparer = "int8in(xidout(xmin))"; - - public override string GetRowVersionColumnName(FieldDefinition field) - { - return "xmin as " + GetQuotedColumnName(field.FieldName); - } - - public override void AppendFieldCondition(StringBuilder sqlFilter, FieldDefinition fieldDef, IDbCommand cmd) - { - var columnName = fieldDef.IsRowVersion - ? RowVersionFieldComparer - : GetQuotedColumnName(fieldDef.FieldName); - - sqlFilter - .Append(columnName) - .Append("=") - .Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); - - AddParameter(cmd, fieldDef); - } - - public override string GetQuotedValue(string paramValue) - { - return "'" + paramValue.Replace("'", @"''") + "'"; - } - - public override IDbConnection CreateConnection(string connectionString, Dictionary options) - { - return new NpgsqlConnection(connectionString); - } - - public override string GetQuotedValue(object value, Type fieldType) - { - if (value == null) return "NULL"; - - if (fieldType == typeof(DateTime)) - { - var dateValue = (DateTime)value; - const string iso8601Format = "yyyy-MM-dd HH:mm:ss.fff"; - return base.GetQuotedValue(dateValue.ToString(iso8601Format), typeof(string)); - } - if (fieldType == typeof(DateTimeOffset)) - { - var dateValue = (DateTimeOffset)value; - const string iso8601Format = "yyyy-MM-dd HH:mm:ss.fff zzz"; - return base.GetQuotedValue(dateValue.ToString(iso8601Format), typeof(string)); - } - if (fieldType == typeof(Guid)) - { - var guidValue = (Guid)value; - return base.GetQuotedValue(guidValue.ToString("N"), typeof(string)); - } - if (fieldType == typeof(byte[])) - { - return "E'" + ToBinary(value) + "'"; - } - if (fieldType.IsArray && typeof(string).IsAssignableFrom(fieldType.GetElementType())) - { - var stringArray = (string[])value; - return ToArray(stringArray); - } - if (fieldType.IsArray && typeof(int).IsAssignableFrom(fieldType.GetElementType())) - { - var integerArray = (int[])value; - return ToArray(integerArray); - } - if (fieldType.IsArray && typeof(long).IsAssignableFrom(fieldType.GetElementType())) - { - var longArray = (long[])value; - return ToArray(longArray); - } - - return base.GetQuotedValue(value, fieldType); - } - - public override object ConvertDbValue(object value, Type type) - { - if (value == null || value is DBNull) return null; - - if (type == typeof(byte[])) { return value; } - - return base.ConvertDbValue(value, type); - } - - public override SqlExpression SqlExpression() - { - return new PostgreSqlExpression(this); - } - - public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) - { - var sql = "SELECT COUNT(*) FROM pg_class WHERE relname = {0}" - .SqlFmt(tableName); - - var conn = dbCmd.Connection; - if (conn != null) - { - var builder = new NpgsqlConnectionStringBuilder(conn.ConnectionString); - if (schema == null) - schema = builder.SearchPath; - - // If a search path (schema) is specified, and there is only one, then assume the CREATE TABLE directive should apply to that schema. - if (!string.IsNullOrEmpty(schema) && !schema.Contains(",")) - sql = "SELECT COUNT(*) FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid = pg_class.relnamespace WHERE relname = {0} AND nspname = {1}" - .SqlFmt(tableName, schema); - } - - dbCmd.CommandText = sql; - var result = dbCmd.LongScalar(); - - return result > 0; - } - - public override string ToExecuteProcedureStatement(object objWithProperties) - { - var sbColumnValues = new StringBuilder(); - - var tableType = objWithProperties.GetType(); - var modelDef = GetModel(tableType); - - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (sbColumnValues.Length > 0) sbColumnValues.Append(","); - try - { - sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties)); - } - catch (Exception) - { - throw; - } - } - - var sql = string.Format("{0} {1}{2}{3};", - GetQuotedTableName(modelDef), - sbColumnValues.Length > 0 ? "(" : "", - sbColumnValues, - sbColumnValues.Length > 0 ? ")" : ""); - - return sql; - } - - public override string GetQuotedTableName(ModelDefinition modelDef) - { - if (!modelDef.IsInSchema) - { - return base.GetQuotedTableName(modelDef); - } - string escapedSchema = modelDef.Schema.Replace(".", "\".\""); - return string.Format("\"{0}\".\"{1}\"", escapedSchema, base.NamingStrategy.GetTableName(modelDef.ModelName)); - } - - /// - /// based on Npgsql2's source: Npgsql2\src\NpgsqlTypes\NpgsqlTypeConverters.cs - /// - /// - /// - /// - /// - internal static String ToBinary(Object NativeData) - { - var byteArray = (Byte[])NativeData; - var res = new StringBuilder(byteArray.Length * 5); - foreach (byte b in byteArray) - if (b >= 0x20 && b < 0x7F && b != 0x27 && b != 0x5C) - res.Append((char)b); - else - res.Append("\\\\") - .Append((char)('0' + (7 & (b >> 6)))) - .Append((char)('0' + (7 & (b >> 3)))) - .Append((char)('0' + (7 & b))); - return res.ToString(); - } - - internal string ToArray(T[] source) - { - var values = new StringBuilder(); - foreach (var value in source) - { - if (values.Length > 0) values.Append(","); - values.Append(base.GetQuotedValue(value, typeof(T))); - } - return "ARRAY[" + values + "]"; - } - - public override long InsertAndGetLastInsertId(IDbCommand dbCmd) - { - if (SelectIdentitySql == null) - throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider."); - - if (UseReturningForLastInsertId) - { - var modelDef = GetModel(typeof(T)); - var pkName = NamingStrategy.GetColumnName(modelDef.PrimaryKey.FieldName); - dbCmd.CommandText += " RETURNING " + pkName; - } - else - { - dbCmd.CommandText += "; " + SelectIdentitySql; - } - - return dbCmd.ExecLongScalar(); - } - - public override void SetParameter(FieldDefinition fieldDef, IDbDataParameter p) - { - if (fieldDef.CustomFieldDefinition == "json") - { - p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)); - ((NpgsqlParameter) p).NpgsqlDbType = NpgsqlDbType.Json; - return; - } - if (fieldDef.CustomFieldDefinition == "text[]") - { - p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)); - ((NpgsqlParameter)p).NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Text; - return; - } - if (fieldDef.CustomFieldDefinition == "integer[]") - { - p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)); - ((NpgsqlParameter) p).NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Integer; - return; - } - if (fieldDef.CustomFieldDefinition == "bigint[]") - { - p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)); - ((NpgsqlParameter) p).NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Bigint; - return; - } - base.SetParameter(fieldDef, p); - } - protected override object GetValue(FieldDefinition fieldDef, object obj) - { - if (fieldDef.CustomFieldDefinition == "text[]") - { - return fieldDef.GetValue(obj); - } - if (fieldDef.CustomFieldDefinition == "integer[]") - { - return fieldDef.GetValue(obj); - } - if (fieldDef.CustomFieldDefinition == "bigint[]") - { - return fieldDef.GetValue(obj); - } - return base.GetValue(fieldDef, obj); - } - - public override void PrepareStoredProcedureStatement(IDbCommand cmd, T obj) - { - var tableType = obj.GetType(); - var modelDef = GetModel(tableType); - - cmd.CommandText = GetQuotedTableName(modelDef); - cmd.CommandType = CommandType.StoredProcedure; - - foreach (var fieldDef in modelDef.FieldDefinitions) - { - var p = cmd.CreateParameter(); - SetParameter(fieldDef, p); - cmd.Parameters.Add(p); - } - - SetParameterValues(cmd, obj); - } - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Npgsql; +using Npgsql.TypeMapping; +using NpgsqlTypes; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; +using ServiceStack.OrmLite.PostgreSQL.Converters; +using ServiceStack.OrmLite.Support; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL +{ + public class PostgreSqlDialectProvider : OrmLiteDialectProviderBase + { + public static PostgreSqlDialectProvider Instance = new(); + + public bool UseReturningForLastInsertId { get; set; } = true; + + public string AutoIdGuidFunction { get; set; } = "uuid_generate_v4()"; + + public PostgreSqlDialectProvider() + { + base.AutoIncrementDefinition = ""; + base.ParamString = ":"; + base.SelectIdentitySql = "SELECT LASTVAL()"; + this.NamingStrategy = new PostgreSqlNamingStrategy(); + this.StringSerializer = new JsonStringSerializer(); + + base.InitColumnTypeMap(); + + this.RowVersionConverter = new PostgreSqlRowVersionConverter(); + + RegisterConverter(new PostgreSqlStringConverter()); + RegisterConverter(new PostgreSqlCharArrayConverter()); + + RegisterConverter(new PostgreSqlBoolConverter()); + RegisterConverter(new PostgreSqlGuidConverter()); + + RegisterConverter(new PostgreSqlDateTimeConverter()); + RegisterConverter(new PostgreSqlDateTimeOffsetConverter()); + + + RegisterConverter(new PostrgreSqlSByteConverter()); + RegisterConverter(new PostrgreSqlUInt16Converter()); + RegisterConverter(new PostrgreSqlUInt32Converter()); + RegisterConverter(new PostrgreSqlUInt64Converter()); + + RegisterConverter(new PostrgreSqlFloatConverter()); + RegisterConverter(new PostrgreSqlDoubleConverter()); + RegisterConverter(new PostrgreSqlDecimalConverter()); + + RegisterConverter(new PostrgreSqlByteArrayConverter()); + + //TODO provide support for pgsql native data structures: + RegisterConverter(new PostgreSqlStringArrayConverter()); + RegisterConverter(new PostgreSqlShortArrayConverter()); + RegisterConverter(new PostgreSqlIntArrayConverter()); + RegisterConverter(new PostgreSqlLongArrayConverter()); + RegisterConverter(new PostgreSqlFloatArrayConverter()); + RegisterConverter(new PostgreSqlDoubleArrayConverter()); + RegisterConverter(new PostgreSqlDecimalArrayConverter()); + RegisterConverter(new PostgreSqlDateTimeTimeStampArrayConverter()); + RegisterConverter(new PostgreSqlDateTimeOffsetTimeStampTzArrayConverter()); + + RegisterConverter(new PostgreSqlXmlConverter()); + +#if NET6_0 + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); + AppContext.SetSwitch("Npgsql.EnableLegacyCaseInsensitiveDbParameters", true); + RegisterConverter(new PostgreSqlDateOnlyConverter()); +#endif + + this.Variables = new Dictionary + { + { OrmLiteVariables.SystemUtc, "now() at time zone 'utc'" }, + { OrmLiteVariables.MaxText, "TEXT" }, + { OrmLiteVariables.MaxTextUnicode, "TEXT" }, + { OrmLiteVariables.True, SqlBool(true) }, + { OrmLiteVariables.False, SqlBool(false) }, + }; + + //this.ExecFilter = new PostgreSqlExecFilter { + // OnCommand = cmd => cmd.AllResultTypesAreUnknown = true + //}; + } + + public bool UseHstore + { + set + { + if (value) + { + RegisterConverter>(new PostgreSqlHstoreConverter()); + RegisterConverter>(new PostgreSqlHstoreConverter()); + } + else + { + RemoveConverter>(); + RemoveConverter>(); + } + } + } + + private bool normalize; + public bool Normalize + { + get => normalize; + set + { + normalize = value; + NamingStrategy = normalize + ? new OrmLiteNamingStrategyBase() + : new PostgreSqlNamingStrategy(); + } + } + + //https://www.postgresql.org/docs/7.3/static/sql-keywords-appendix.html + public static HashSet ReservedWords = new(new[] + { + "ALL", + "ANALYSE", + "ANALYZE", + "AND", + "ANY", + "AS", + "ASC", + "AUTHORIZATION", + "BETWEEN", + "BINARY", + "BOTH", + "CASE", + "CAST", + "CHECK", + "COLLATE", + "COLUMN", + "CONSTRAINT", + "CURRENT_DATE", + "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "CURRENT_USER", + "DEFAULT", + "DEFERRABLE", + "DISTINCT", + "DO", + "ELSE", + "END", + "EXCEPT", + "FOR", + "FOREIGN", + "FREEZE", + "FROM", + "FULL", + "HAVING", + "ILIKE", + "IN", + "INITIALLY", + "INNER", + "INTERSECT", + "INTO", + "IS", + "ISNULL", + "JOIN", + "LEADING", + "LEFT", + "LIKE", + "LIMIT", + "LOCALTIME", + "LOCALTIMESTAMP", + "NEW", + "NOT", + "NOTNULL", + "NULL", + "OFF", + "OFFSET", + "OLD", + "ON", + "ONLY", + "OR", + "ORDER", + "OUTER", + "OVERLAPS", + "PLACING", + "PRIMARY", + "REFERENCES", + "RIGHT", + "SELECT", + "SESSION_USER", + "SIMILAR", + "SOME", + "TABLE", + "THEN", + "TO", + "TRAILING", + "TRUE", + "UNION", + "UNIQUE", + "USER", + "USING", + "VERBOSE", + "WHEN", + "WHERE", + }, StringComparer.OrdinalIgnoreCase); + + public override string GetColumnDefinition(FieldDefinition fieldDef) + { + if (fieldDef.IsRowVersion) + return null; + + string fieldDefinition = null; + if (fieldDef.CustomFieldDefinition != null) + { + fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition); + } + else + { + if (fieldDef.AutoIncrement) + { + if (fieldDef.ColumnType == typeof(long)) + fieldDefinition = "bigserial"; + else if (fieldDef.ColumnType == typeof(int)) + fieldDefinition = "serial"; + } + else + { + fieldDefinition = GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale); + } + } + + var sql = StringBuilderCache.Allocate(); + sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldDef.FieldName), fieldDefinition); + + if (fieldDef.IsPrimaryKey) + { + sql.Append(" PRIMARY KEY"); + } + else + { + if (fieldDef.IsNullable) + { + sql.Append(" NULL"); + } + else + { + sql.Append(" NOT NULL"); + } + } + + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } + + var defaultValue = GetDefaultValue(fieldDef); + if (!string.IsNullOrEmpty(defaultValue)) + { + sql.AppendFormat(DefaultValueFormat, defaultValue); + } + + var definition = StringBuilderCache.ReturnAndFree(sql); + return definition; + } + + public override string GetAutoIdDefaultValue(FieldDefinition fieldDef) + { + return fieldDef.FieldType == typeof(Guid) + ? AutoIdGuidFunction + : null; + } + + public override bool IsFullSelectStatement(string sql) + { + sql = sql?.TrimStart(); + if (string.IsNullOrEmpty(sql)) + return false; + + return sql.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase) || + sql.StartsWith("WITH ", StringComparison.OrdinalIgnoreCase); + } + + protected override bool ShouldSkipInsert(FieldDefinition fieldDef) => + fieldDef.ShouldSkipInsert() || fieldDef.AutoId; + + protected virtual bool ShouldReturnOnInsert(ModelDefinition modelDef, FieldDefinition fieldDef) => + fieldDef.ReturnOnInsert || (fieldDef.IsPrimaryKey && fieldDef.AutoIncrement && HasInsertReturnValues(modelDef)) || fieldDef.AutoId; + + public override bool HasInsertReturnValues(ModelDefinition modelDef) => + modelDef.FieldDefinitions.Any(x => x.ReturnOnInsert || (x.AutoId && x.FieldType == typeof(Guid))); + + public override void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null, + Func shouldInclude=null) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var sbReturningColumns = StringBuilderCacheAlt.Allocate(); + var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T)); + + cmd.Parameters.Clear(); + + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) + { + if (ShouldReturnOnInsert(modelDef, fieldDef)) + { + sbReturningColumns.Append(sbReturningColumns.Length == 0 ? " RETURNING " : ","); + sbReturningColumns.Append(GetQuotedColumnName(fieldDef.FieldName)); + } + + if ((ShouldSkipInsert(fieldDef) && !fieldDef.AutoId) + && shouldInclude?.Invoke(fieldDef) != true) + continue; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName),fieldDef.CustomInsert)); + AddParameter(cmd, fieldDef); + } + catch (Exception ex) + { + Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex); + throw; + } + } + + foreach (var fieldDef in modelDef.AutoIdFields) // need to include any AutoId fields that weren't included + { + if (fieldDefs.Contains(fieldDef)) + continue; + + sbReturningColumns.Append(sbReturningColumns.Length == 0 ? " RETURNING " : ","); + sbReturningColumns.Append(GetQuotedColumnName(fieldDef.FieldName)); + } + + var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns); + cmd.CommandText = sbColumnNames.Length > 0 + ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) " + + $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)}){strReturning}" + : $"INSERT INTO {GetQuotedTableName(modelDef)} DEFAULT VALUES{strReturning}"; + } + + //Convert xmin into an integer so it can be used in comparisons + public const string RowVersionFieldComparer = "int8in(xidout(xmin))"; + + public override SelectItem GetRowVersionSelectColumn(FieldDefinition field, string tablePrefix = null) + { + return new SelectItemColumn(this, "xmin", field.FieldName, tablePrefix); + } + + public override string GetRowVersionColumn(FieldDefinition field, string tablePrefix = null) + { + return RowVersionFieldComparer; + } + + public override void AppendFieldCondition(StringBuilder sqlFilter, FieldDefinition fieldDef, IDbCommand cmd) + { + var columnName = fieldDef.IsRowVersion + ? RowVersionFieldComparer + : GetQuotedColumnName(fieldDef.FieldName); + + sqlFilter + .Append(columnName) + .Append("=") + .Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); + + AddParameter(cmd, fieldDef); + } + + public override string GetQuotedValue(string paramValue) + { + return "'" + paramValue.Replace("'", @"''") + "'"; + } + + public override IDbConnection CreateConnection(string connectionString, Dictionary options) + { + return new NpgsqlConnection(connectionString); + } + + public override SqlExpression SqlExpression() + { + return new PostgreSqlExpression(this); + } + + public override IDbDataParameter CreateParam() + { + return new NpgsqlParameter(); + } + + public override string ToTableNamesStatement(string schema) + { + var sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"; + + var schemaName = schema != null + ? NamingStrategy.GetSchemaName(schema) + : "public"; + return sql + " AND table_schema = {0}".SqlFmt(this, schemaName); + } + + public override string ToTableNamesWithRowCountsStatement(bool live, string schema) + { + var schemaName = schema != null + ? NamingStrategy.GetSchemaName(schema) + : "public"; + return live + ? null + : "SELECT relname, reltuples FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid = pg_class.relnamespace WHERE relkind = 'r' AND nspname = {0}".SqlFmt(this, schemaName); + } + + public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) + { + var sql = DoesTableExistSql(dbCmd, tableName, schema); + var result = dbCmd.ExecLongScalar(sql); + return result > 0; + } + + public override async Task DoesTableExistAsync(IDbCommand dbCmd, string tableName, string schema = null, CancellationToken token=default) + { + var sql = DoesTableExistSql(dbCmd, tableName, schema); + var result = await dbCmd.ExecLongScalarAsync(sql, token); + return result > 0; + } + + private string DoesTableExistSql(IDbCommand dbCmd, string tableName, string schema) + { + var sql = !Normalize || ReservedWords.Contains(tableName) + ? "SELECT COUNT(*) FROM pg_class WHERE relname = {0} AND relkind = 'r'".SqlFmt(tableName) + : "SELECT COUNT(*) FROM pg_class WHERE lower(relname) = {0} AND relkind = 'r'".SqlFmt(tableName.ToLower()); + + var conn = dbCmd.Connection; + if (conn != null) + { + var builder = new NpgsqlConnectionStringBuilder(conn.ConnectionString); + if (schema == null) + schema = builder.SearchPath; + if (schema == null) + schema = "public"; + + // If a search path (schema) is specified, and there is only one, then assume the CREATE TABLE directive should apply to that schema. + if (!string.IsNullOrEmpty(schema) && !schema.Contains(",")) + { + sql = !Normalize || ReservedWords.Contains(schema) + ? "SELECT COUNT(*) FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid = pg_class.relnamespace WHERE relname = {0} AND relkind = 'r' AND nspname = {1}" + .SqlFmt(tableName, schema) + : "SELECT COUNT(*) FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid = pg_class.relnamespace WHERE lower(relname) = {0} AND relkind = 'r' AND lower(nspname) = {1}" + .SqlFmt(tableName.ToLower(), schema.ToLower()); + } + } + + return sql; + } + + public override bool DoesSchemaExist(IDbCommand dbCmd, string schemaName) + { + dbCmd.CommandText = $"SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = '{GetSchemaName(schemaName).SqlParam()}');"; + var query = dbCmd.ExecuteScalar(); + return query as bool? ?? false; + } + + public override async Task DoesSchemaExistAsync(IDbCommand dbCmd, string schemaName, CancellationToken token = default) + { + dbCmd.CommandText = $"SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = '{GetSchemaName(schemaName).SqlParam()}');"; + var query = await dbCmd.ScalarAsync(); + return query as bool? ?? false; + } + + public override string ToCreateSchemaStatement(string schemaName) + { + var sql = $"CREATE SCHEMA {GetSchemaName(schemaName)}"; + return sql; + } + + public override bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null) + { + var sql = DoesColumnExistSql(columnName, tableName, ref schema); + var result = db.SqlScalar(sql, new { tableName, columnName, schema }); + return result > 0; + } + + public override async Task DoesColumnExistAsync(IDbConnection db, string columnName, string tableName, string schema = null, + CancellationToken token = default) + { + var sql = DoesColumnExistSql(columnName, tableName, ref schema); + var result = await db.SqlScalarAsync(sql, new { tableName, columnName, schema }, token); + return result > 0; + } + + private string DoesColumnExistSql(string columnName, string tableName, ref string schema) + { + var sql = !Normalize || ReservedWords.Contains(tableName) + ? "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName".SqlFmt(tableName) + : "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE lower(TABLE_NAME) = @tableName".SqlFmt( + tableName.ToLower()); + + sql += !Normalize || ReservedWords.Contains(columnName) + ? " AND COLUMN_NAME = @columnName".SqlFmt(columnName) + : " AND lower(COLUMN_NAME) = @columnName".SqlFmt(columnName.ToLower()); + + if (schema != null) + { + sql += !Normalize || ReservedWords.Contains(schema) + ? " AND TABLE_SCHEMA = @schema" + : " AND lower(TABLE_SCHEMA) = @schema"; + + if (Normalize) + schema = schema.ToLower(); + } + + return sql; + } + + public override string ToExecuteProcedureStatement(object objWithProperties) + { + var sbColumnValues = StringBuilderCache.Allocate(); + + var tableType = objWithProperties.GetType(); + var modelDef = GetModel(tableType); + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (sbColumnValues.Length > 0) sbColumnValues.Append(","); + sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties)); + } + + var colValues = StringBuilderCache.ReturnAndFree(sbColumnValues); + var sql = string.Format("{0} {1}{2}{3};", + GetQuotedTableName(modelDef), + colValues.Length > 0 ? "(" : "", + colValues, + colValues.Length > 0 ? ")" : ""); + + return sql; + } + + public override string ToAlterColumnStatement(Type modelType, FieldDefinition fieldDef) + { + var columnDefinition = GetColumnDefinition(fieldDef); + var modelName = GetQuotedTableName(GetModel(modelType)); + + var parts = columnDefinition.SplitOnFirst(' '); + var columnName = parts[0]; + var columnType = parts[1]; + + var notNull = columnDefinition.Contains("NOT NULL"); + + var nullLiteral = notNull ? " NOT NULL" : " NULL"; + columnType = columnType.Replace(nullLiteral, ""); + + var nullSql = notNull + ? "SET NOT NULL" + : "DROP NOT NULL"; + + var sql = $"ALTER TABLE {modelName}\n" + + $" ALTER COLUMN {columnName} TYPE {columnType},\n" + + $" ALTER COLUMN {columnName} {nullSql}"; + + return sql; + } + + public override bool ShouldQuote(string name) => !string.IsNullOrEmpty(name) && + (Normalize || ReservedWords.Contains(name) || name.IndexOf(' ') >= 0 || name.IndexOf('.') >= 0); + + public override string GetQuotedName(string name) + { + return name.IndexOf('.') >= 0 + ? base.GetQuotedName(name.Replace(".", "\".\"")) + : base.GetQuotedName(name); + } + + public override string GetQuotedTableName(ModelDefinition modelDef) + { + if (!modelDef.IsInSchema) + return base.GetQuotedTableName(modelDef); + if (Normalize && !ShouldQuote(modelDef.ModelName) && !ShouldQuote(modelDef.Schema)) + return GetQuotedName(NamingStrategy.GetSchemaName(modelDef.Schema)) + "." + GetQuotedName(NamingStrategy.GetTableName(modelDef.ModelName)); + + return $"{GetQuotedName(NamingStrategy.GetSchemaName(modelDef.Schema))}.{GetQuotedName(NamingStrategy.GetTableName(modelDef.ModelName))}"; + } + + public override string GetTableName(string table, string schema, bool useStrategy) + { + if (useStrategy) + { + return schema != null + ? $"{QuoteIfRequired(NamingStrategy.GetSchemaName(schema))}.{QuoteIfRequired(NamingStrategy.GetTableName(table))}" + : QuoteIfRequired(NamingStrategy.GetTableName(table)); + } + + return schema != null + ? $"{QuoteIfRequired(schema)}.{QuoteIfRequired(table)}" + : QuoteIfRequired(table); + } + + public override string GetLastInsertIdSqlSuffix() + { + if (SelectIdentitySql == null) + throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider."); + + if (UseReturningForLastInsertId) + { + var modelDef = GetModel(typeof(T)); + var pkName = NamingStrategy.GetColumnName(modelDef.PrimaryKey.FieldName); + return !Normalize + ? $" RETURNING \"{pkName}\"" + : " RETURNING " + pkName; + } + + return "; " + SelectIdentitySql; + } + + public Dictionary TypesMap { get; } = new Dictionary + { + [typeof(bool)] = NpgsqlDbType.Boolean, + [typeof(short)] = NpgsqlDbType.Smallint, + [typeof(int)] = NpgsqlDbType.Integer, + [typeof(long)] = NpgsqlDbType.Bigint, + [typeof(float)] = NpgsqlDbType.Real, + [typeof(double)] = NpgsqlDbType.Double, + [typeof(decimal)] = NpgsqlDbType.Numeric, + [typeof(string)] = NpgsqlDbType.Text, + [typeof(char[])] = NpgsqlDbType.Varchar, + [typeof(char)] = NpgsqlDbType.Char, + [typeof(NpgsqlPoint)] = NpgsqlDbType.Point, + [typeof(NpgsqlLSeg)] = NpgsqlDbType.LSeg, + [typeof(NpgsqlPath)] = NpgsqlDbType.Path, + [typeof(NpgsqlPolygon)] = NpgsqlDbType.Polygon, + [typeof(NpgsqlLine)] = NpgsqlDbType.Line, + [typeof(NpgsqlCircle)] = NpgsqlDbType.Circle, + [typeof(NpgsqlBox)] = NpgsqlDbType.Box, + [typeof(BitArray)] = NpgsqlDbType.Varbit, + [typeof(IDictionary)] = NpgsqlDbType.Hstore, + [typeof(Guid)] = NpgsqlDbType.Uuid, + [typeof(ValueTuple)] = NpgsqlDbType.Cidr, + [typeof(ValueTuple)] = NpgsqlDbType.Inet, + [typeof(IPAddress)] = NpgsqlDbType.Inet, + [typeof(PhysicalAddress)] = NpgsqlDbType.MacAddr, + [typeof(NpgsqlTsQuery)] = NpgsqlDbType.TsQuery, + [typeof(NpgsqlTsVector)] = NpgsqlDbType.TsVector, + [typeof(NpgsqlDate)] = NpgsqlDbType.Date, + [typeof(DateTime)] = NpgsqlDbType.Timestamp, + [typeof(DateTimeOffset)] = NpgsqlDbType.TimestampTz, + [typeof(TimeSpan)] = NpgsqlDbType.Time, + [typeof(NpgsqlTimeSpan)] = NpgsqlDbType.Time, + [typeof(byte[])] = NpgsqlDbType.Bytea, + [typeof(uint)] = NpgsqlDbType.Oid, + [typeof(uint[])] = NpgsqlDbType.Oidvector, + }; + + public NpgsqlDbType GetDbType() => GetDbType(typeof(T)); + public NpgsqlDbType GetDbType(Type type) + { + if (TypesMap.TryGetValue(type, out var paramType)) + return paramType; + var genericEnum = type.GetTypeWithGenericTypeDefinitionOf(typeof(IEnumerable<>)); + if (genericEnum != null) + return GetDbType(genericEnum.GenericTypeArguments[0]) | NpgsqlDbType.Array; + + throw new NotSupportedException($"Type '{type.Name}' not found in 'TypesMap'"); + } + + public Dictionary NativeTypes = new Dictionary { + { "json", NpgsqlDbType.Json }, + { "jsonb", NpgsqlDbType.Jsonb }, + { "hstore", NpgsqlDbType.Hstore }, + { "text[]", NpgsqlDbType.Array | NpgsqlDbType.Text }, + { "short[]", NpgsqlDbType.Array | NpgsqlDbType.Smallint }, + { "int[]", NpgsqlDbType.Array | NpgsqlDbType.Integer }, + { "integer[]", NpgsqlDbType.Array | NpgsqlDbType.Integer }, + { "bigint[]", NpgsqlDbType.Array | NpgsqlDbType.Bigint }, + { "real[]", NpgsqlDbType.Array | NpgsqlDbType.Real }, + { "double precision[]", NpgsqlDbType.Array | NpgsqlDbType.Double }, + { "numeric[]", NpgsqlDbType.Array | NpgsqlDbType.Numeric }, + { "timestamp[]", NpgsqlDbType.Array | NpgsqlDbType.Timestamp }, + { "timestamp with time zone[]", NpgsqlDbType.Array | NpgsqlDbType.TimestampTz }, + { "bool[]", NpgsqlDbType.Array | NpgsqlDbType.Boolean }, + { "boolean[]", NpgsqlDbType.Array | NpgsqlDbType.Boolean }, + }; + + public override void SetParameter(FieldDefinition fieldDef, IDbDataParameter p) + { + if (fieldDef.CustomFieldDefinition != null && + NativeTypes.TryGetValue(fieldDef.CustomFieldDefinition, out var npgsqlDbType)) + { + p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)); + ((NpgsqlParameter) p).NpgsqlDbType = npgsqlDbType; + } + else + { + base.SetParameter(fieldDef, p); + } + } + + public virtual bool UseRawValue(string columnDef) => columnDef?.EndsWith("[]") == true; + + protected override object GetValue(FieldDefinition fieldDef, object obj) + { + if (fieldDef.CustomFieldDefinition != null && NativeTypes.ContainsKey(fieldDef.CustomFieldDefinition) + && UseRawValue(fieldDef.CustomFieldDefinition)) + { + return fieldDef.GetValue(obj); + } + + return base.GetValue(fieldDef, obj); + } + + public override void PrepareStoredProcedureStatement(IDbCommand cmd, T obj) + { + var tableType = obj.GetType(); + var modelDef = GetModel(tableType); + + cmd.CommandText = GetQuotedTableName(modelDef); + cmd.CommandType = CommandType.StoredProcedure; + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + var p = cmd.CreateParameter(); + SetParameter(fieldDef, p); + cmd.Parameters.Add(p); + } + + SetParameterValues(cmd, obj); + } + + public override string SqlConflict(string sql, string conflictResolution) + { + //https://www.postgresql.org/docs/current/static/sql-insert.html + return sql + " ON CONFLICT " + (conflictResolution == ConflictResolution.Ignore + ? " DO NOTHING" + : conflictResolution); + } + + public override string SqlConcat(IEnumerable args) => string.Join(" || ", args); + + public override string SqlCurrency(string fieldOrValue, string currencySymbol) => currencySymbol == "$" + ? fieldOrValue + "::text::money::text" + : "replace(" + fieldOrValue + "::text::money::text,'$','" + currencySymbol + "')"; + + public override string SqlCast(object fieldOrValue, string castAs) => + $"({fieldOrValue})::{castAs}"; + + public override string SqlRandom => "RANDOM()"; + + protected NpgsqlConnection Unwrap(IDbConnection db) + { + return (NpgsqlConnection)db.ToDbConnection(); + } + + protected NpgsqlCommand Unwrap(IDbCommand cmd) + { + return (NpgsqlCommand)cmd.ToDbCommand(); + } + + protected NpgsqlDataReader Unwrap(IDataReader reader) + { + return (NpgsqlDataReader)reader; + } + +#if ASYNC + public override Task OpenAsync(IDbConnection db, CancellationToken token = default) + { + return Unwrap(db).OpenAsync(token); + } + + public override Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default) + { + return Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x); + } + + public override Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default) + { + return Unwrap(cmd).ExecuteNonQueryAsync(token); + } + + public override Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default) + { + return Unwrap(cmd).ExecuteScalarAsync(token); + } + + public override Task ReadAsync(IDataReader reader, CancellationToken token = default) + { + return Unwrap(reader).ReadAsync(token); + } + + public override async Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = default) + { + try + { + var to = new List(); + while (await ReadAsync(reader, token).ConfigureAwait(false)) + { + var row = fn(); + to.Add(row); + } + return to; + } + finally + { + reader.Dispose(); + } + } + + public override async Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = default) + { + try + { + while (await ReadAsync(reader, token).ConfigureAwait(false)) + { + fn(); + } + return source; + } + finally + { + reader.Dispose(); + } + } + + public override async Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = default) + { + try + { + if (await ReadAsync(reader, token).ConfigureAwait(false)) + return fn(); + + return default(T); + } + finally + { + reader.Dispose(); + } + } +#endif + } +} diff --git a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlDialect.cs b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlDialect.cs index b7d3487ec..e56fda5d2 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlDialect.cs +++ b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlDialect.cs @@ -4,6 +4,7 @@ namespace ServiceStack.OrmLite { public static class PostgreSqlDialect { - public static IOrmLiteDialectProvider Provider { get { return PostgreSQLDialectProvider.Instance; } } + public static IOrmLiteDialectProvider Provider => PostgreSqlDialectProvider.Instance; + public static PostgreSqlDialectProvider Instance => PostgreSqlDialectProvider.Instance; } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExecFilter.cs b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExecFilter.cs new file mode 100644 index 000000000..9f600ecdd --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExecFilter.cs @@ -0,0 +1,24 @@ +using System; +using System.Data; +using Npgsql; + +namespace ServiceStack.OrmLite.PostgreSQL +{ + public class PostgreSqlExecFilter : OrmLiteExecFilter + { + public Action OnCommand { get; set; } + + public override IDbCommand CreateCommand(IDbConnection dbConn) + { + var cmd = base.CreateCommand(dbConn); + if (OnCommand != null) + { + if (cmd.ToDbCommand() is NpgsqlCommand psqlCmd) + { + OnCommand?.Invoke(psqlCmd); + } + } + return cmd; + } + } +} diff --git a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExpression.cs b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExpression.cs index 2a5f10b76..681167162 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExpression.cs +++ b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlExpression.cs @@ -11,15 +11,14 @@ protected override string GetQuotedColumnName(ModelDefinition tableDef, string m { if (useFieldName) { - var fd = tableDef.FieldDefinitions.FirstOrDefault(x => x.Name == memberName); - if (fd != null && fd.IsRowVersion && !PrefixFieldWithTableName) - { - return PostgreSQLDialectProvider.RowVersionFieldComparer; - } + var fieldDef = tableDef.FieldDefinitions.FirstOrDefault(x => x.Name == memberName); + if (fieldDef != null && fieldDef.IsRowVersion && !PrefixFieldWithTableName) + return PostgreSqlDialectProvider.RowVersionFieldComparer; return base.GetQuotedColumnName(tableDef, memberName); } return memberName; } } + } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlNamingStrategy.cs b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlNamingStrategy.cs index 4ef1445ef..873c07982 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlNamingStrategy.cs +++ b/src/ServiceStack.OrmLite.PostgreSQL/PostgreSqlNamingStrategy.cs @@ -13,5 +13,10 @@ public override string GetColumnName(string name) { return name.ToLowercaseUnderscore(); } + + public override string GetSchemaName(string name) + { + return name.ToLowercaseUnderscore(); + } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.PostgreSQL/Properties/AssemblyInfo.cs index 39a6d62f7..22ae012d6 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite.PostgreSQL/Properties/AssemblyInfo.cs @@ -1,25 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.PostgreSQL")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.PostgreSQL")] -[assembly: AssemblyCopyright("Copyright © Tomasz Kubacki 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b89c24c2-77c5-843c-f1bf-c33d25af3f16")] - -[assembly: AssemblyVersion("4.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.Core.csproj b/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.Core.csproj new file mode 100644 index 000000000..b7d6e734e --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.Core.csproj @@ -0,0 +1,22 @@ + + + + ServiceStack.OrmLite.PostgreSQL.Core + ServiceStack.OrmLite.PostgreSQL + ServiceStack.OrmLite.PostgreSQL + netstandard2.0;net6.0 + ServiceStack.OrmLite.PostgreSQL .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite.PostgreSQL + + PostgreSQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.Source.csproj b/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.Source.csproj new file mode 100644 index 000000000..80e2ed1d8 --- /dev/null +++ b/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.Source.csproj @@ -0,0 +1,23 @@ + + + + ServiceStack.OrmLite.PostgreSQL + ServiceStack.OrmLite.PostgreSQL + netstandard2.0;net6.0 + OrmLite.PostgreSQL - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for PostgreSQL. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Postgres. + + PostgreSQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + false + $(DefineConstants);ASYNC + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.csproj b/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.csproj index d366a213c..94e1e9bc6 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.csproj +++ b/src/ServiceStack.OrmLite.PostgreSQL/ServiceStack.OrmLite.PostgreSQL.csproj @@ -1,98 +1,31 @@ - - + + - Debug - AnyCPU - 8.0.30703 - 2.0 - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5} - Library - Properties - ServiceStack.OrmLite.PostgreSQL + ServiceStack.OrmLite.PostgreSQL ServiceStack.OrmLite.PostgreSQL - 512 - v4.0 - - ..\ - true + net472;netstandard2.0;net6.0 + OrmLite.PostgreSQL - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for PostgreSQL. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in Postgres. + + PostgreSQL;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - False - ..\packages\Npgsql.2.2.3\lib\net40\Mono.Security.dll - - - False - ..\packages\Npgsql.2.2.3\lib\net40\Npgsql.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - + + + - - - - - - + + - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - + + - - + + + + - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + + diff --git a/src/ServiceStack.OrmLite.PostgreSQL/packages.config b/src/ServiceStack.OrmLite.PostgreSQL/packages.config deleted file mode 100644 index 447feeba4..000000000 --- a/src/ServiceStack.OrmLite.PostgreSQL/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer.Converters/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.SqlServer.Converters/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..22ae012d6 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Converters/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.SqlServer.Converters/ServiceStack.OrmLite.SqlServer.Converters.csproj b/src/ServiceStack.OrmLite.SqlServer.Converters/ServiceStack.OrmLite.SqlServer.Converters.csproj new file mode 100644 index 000000000..20219e89b --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Converters/ServiceStack.OrmLite.SqlServer.Converters.csproj @@ -0,0 +1,21 @@ + + + + ServiceStack.OrmLite.SqlServer.Converters + ServiceStack.OrmLite.SqlServer.Converters + net472;netstandard2.0;net6.0 + OrmLite.SqlServer.Converters - Converters for SQL Server Types + + Add OrmLite Converters for SQL Servers SqlGeography and SqlGeometry Types + + SQLServer;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerConverters.cs b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerConverters.cs new file mode 100644 index 000000000..aa330b351 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerConverters.cs @@ -0,0 +1,97 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; +using Microsoft.SqlServer.Types; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public static class SqlServerConverters + { + public static string Msvcr100FileName = "msvcr100.dll"; + public static string SqlServerSpatial110FileName = "SqlServerSpatial110.dll"; + + public static IOrmLiteDialectProvider Configure(IOrmLiteDialectProvider dialectProvider, string[] fileNames, string libraryPath = null) + { + foreach (var fileName in fileNames) + { + LoadAssembly(fileName, libraryPath); + } + + dialectProvider.RegisterConverter(new SqlServerExtendedStringConverter()); + dialectProvider.RegisterConverter(new SqlServerGeographyTypeConverter()); + dialectProvider.RegisterConverter(new SqlServerGeometryTypeConverter()); + dialectProvider.RegisterConverter(new SqlServerHierarchyIdTypeConverter()); + return dialectProvider; + } + + public static IOrmLiteDialectProvider Configure(IOrmLiteDialectProvider dialectProvider, string libraryPath = null) => + Configure(dialectProvider, new string[] { Msvcr100FileName, SqlServerSpatial110FileName }, libraryPath); + + public static void LoadAssembly(string assemblyName, string libraryPath = null) + { + // default libraryPath to Windows System + if (string.IsNullOrEmpty(libraryPath)) + { + // Get the appropriate Windows System Path + // 32-bit: C:\Windows\System32 + // 64-bit: C:\Windows\SysWOW64 + var systemPathEnum = (!Environment.Is64BitProcess) + ? Environment.SpecialFolder.SystemX86 + : Environment.SpecialFolder.System; + + libraryPath = Environment.GetFolderPath(systemPathEnum); + } + + var arch = Environment.Is64BitProcess + ? "x64" + : "x86"; + + var libraryPaths = new[] + { + libraryPath, + "~/SqlServerTypes/{0}/".Fmt(arch).MapAbsolutePath(), + "~/SqlServerTypes/{0}/".Fmt(arch).MapHostAbsolutePath(), + }; + + foreach (var libraryDir in libraryPaths) + { + var assemblyPath = Path.Combine(libraryDir, assemblyName); + if (!File.Exists(assemblyPath)) + continue; + + // The versions of the files must match the version associated with Sql Server + // These files can been installed from the Microsoft SQL Server Feature Pack + // + // SQL Server 2008: https://www.microsoft.com/en-us/download/details.aspx?id=44277 + // SQL Server 2008 R2: https://www.microsoft.com/en-us/download/details.aspx?id=44272 + // SQL Server 2012 SP2: http://www.microsoft.com/en-us/download/details.aspx?id=43339 + // SQL Server 2014 SP1: https://www.microsoft.com/en-us/download/details.aspx?id=46696 + + var ptr = LoadLibrary(assemblyPath); + if (ptr == IntPtr.Zero) + throw new Exception("Error loading {0} (ErrorCode: {1})".Fmt( + assemblyPath, Marshal.GetLastWin32Error())); + + return; + } + } + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr LoadLibrary(string libname); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + private static extern bool FreeLibrary(IntPtr hModule); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + private static extern bool GetModuleHandleExA(int dwFlags, string moduleName, IntPtr phModule); + + public static void UnloadUnmanagedAssembly(string assemblyName) + { + var hMod = IntPtr.Zero; + if (GetModuleHandleExA(0, assemblyName, hMod)) + { + while (FreeLibrary(hMod)); + } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerExtendedStringConverters.cs b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerExtendedStringConverters.cs new file mode 100644 index 000000000..b571df6cb --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerExtendedStringConverters.cs @@ -0,0 +1,60 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using ServiceStack.DataAnnotations; +using Microsoft.SqlServer.Types; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerExtendedStringConverter : SqlServerStringConverter + { + public override object FromDbValue(Type fieldType, object value) + { + if (value is SqlHierarchyId) + { + var hierarchyId = (SqlHierarchyId)value; + return (hierarchyId.IsNull) ? null : hierarchyId.ToString(); + } + + if (value is SqlGeography) + { + var geography = (SqlGeography)value; + return (geography.IsNull) ? null : geography.ToString(); + } + + if (value is SqlGeometry) + { + var geometry = (SqlGeometry)value; + return (geometry.IsNull) ? null : geometry.ToString(); + } + + return base.FromDbValue(fieldType, value); + } + + //public override object ToDbValue(Type fieldType, object value) + //{ + // var str = value?.ToString(); + + // if (fieldType == typeof(SqlHierarchyId)) + // { + // return (str == null) ? SqlHierarchyId.Null : SqlHierarchyId.Parse(str); + // } + + // if (fieldType == typeof(SqlGeography)) + // { + // var geography = (SqlGeography)value; + // var srid = geography.STSrid.Value; + // return (str == null) ? SqlGeography.Null : SqlGeography.STGeomFromText(new System.Data.SqlTypes.SqlChars(str), srid); + // } + + // if (fieldType == typeof(SqlGeometry)) + // { + // var geometry = (SqlGeometry)value; + // var srid = geometry.STSrid.Value; + // return (str == null) ? SqlGeometry.Null : SqlGeometry.STGeomFromText(new System.Data.SqlTypes.SqlChars(str), srid); + // } + + // return base.ToDbValue(fieldType, value); + //} + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeographyTypeConverter.cs b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeographyTypeConverter.cs new file mode 100644 index 000000000..40b21ed27 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeographyTypeConverter.cs @@ -0,0 +1,85 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using Microsoft.SqlServer.Types; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + /// + /// SqlServer Database Converter for the Geometry data type + /// https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeography.aspx + /// + public class SqlServerGeographyTypeConverter : OrmLiteConverter + { + public override string ColumnDefinition => "geography"; + + public override DbType DbType => DbType.Object; + + public override string ToQuotedString(Type fieldType, object value) + { + if (fieldType == typeof(SqlGeography)) + { + string str = null; + if (value != null) + { + var geo = (SqlGeography)value; + if (!geo.IsNull) + str = geo.ToString(); + } + str = (str == null) ? "null" : $"'{str}'"; + return $"CAST({str} AS {ColumnDefinition})"; + } + + return base.ToQuotedString(fieldType, value); + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + if (fieldType == typeof(SqlGeography)) + { + var sqlParam = (SqlParameter)p; + sqlParam.IsNullable = fieldType.IsNullableType(); + sqlParam.SqlDbType = SqlDbType.Udt; + sqlParam.UdtTypeName = ColumnDefinition; + } + base.InitDbParam(p, fieldType); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value == null || value is DBNull) + return SqlGeography.Null; + + if (value is SqlGeography) + return (SqlGeography)value; + + if (value is string) + { + return SqlGeography.Parse(value.ToString()); + } + + return base.FromDbValue(fieldType, value); + } + + public override object ToDbValue(Type fieldType, object value) + { + if (value == null || value is DBNull) + { + return SqlGeography.Null; + } + + if (value is SqlGeography) + { + return value; + } + + if (value is string) + { + var str = value as string; + return SqlGeography.Parse(str); + } + + return base.ToDbValue(fieldType, value); + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeometryTypeConverter.cs b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeometryTypeConverter.cs new file mode 100644 index 000000000..dd336b5a2 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerGeometryTypeConverter.cs @@ -0,0 +1,85 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using Microsoft.SqlServer.Types; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + /// + /// SqlServer Database Converter for the Geometry data type + /// https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeometry.aspx + /// + public class SqlServerGeometryTypeConverter : OrmLiteConverter + { + public override string ColumnDefinition => "geometry"; + + public override DbType DbType => DbType.Object; + + public override string ToQuotedString(Type fieldType, object value) + { + if (fieldType == typeof(SqlGeometry)) + { + string str = null; + if (value != null) + { + var geo = (SqlGeometry)value; + if (!geo.IsNull) + str = geo.ToString(); + } + str = (str == null) ? "null" : $"'{str}'"; + return $"CAST({str} AS {ColumnDefinition})"; + } + + return base.ToQuotedString(fieldType, value); + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + if (fieldType == typeof(SqlGeometry)) + { + var sqlParam = (SqlParameter)p; + sqlParam.IsNullable = fieldType.IsNullableType(); + sqlParam.SqlDbType = SqlDbType.Udt; + sqlParam.UdtTypeName = ColumnDefinition; + } + base.InitDbParam(p, fieldType); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value == null || value is DBNull) + return SqlGeometry.Null; + + if (value is SqlGeometry) + return (SqlGeometry)value; + + if (value is string) + { + return SqlGeometry.Parse(value.ToString()); + } + + return base.FromDbValue(fieldType, value); + } + + public override object ToDbValue(Type fieldType, object value) + { + if (value == null || value is DBNull) + { + return SqlGeometry.Null; + } + + if (value is SqlGeometry) + { + return value; + } + + if (value is string) + { + var str = value as string; + return SqlGeometry.Parse(str); + } + + return base.ToDbValue(fieldType, value); + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerHierarchyIdTypeConverter.cs b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerHierarchyIdTypeConverter.cs new file mode 100644 index 000000000..595a77034 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Converters/SqlServerHierarchyIdTypeConverter.cs @@ -0,0 +1,85 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using Microsoft.SqlServer.Types; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + /// + /// SqlServer Database Converter for the HierarchyId data type + /// https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlhierarchyid.aspx + /// + public class SqlServerHierarchyIdTypeConverter : OrmLiteConverter + { + public override string ColumnDefinition => "hierarchyId"; + + public override DbType DbType => DbType.Object; + + public override string ToQuotedString(Type fieldType, object value) + { + if (fieldType == typeof(SqlHierarchyId)) + { + string str = null; + if (value != null) + { + var hierarchyId = (SqlHierarchyId)value; + if (!hierarchyId.IsNull) + str = hierarchyId.ToString(); + } + str = (str == null) ? "null" : $"'{str}'"; + return $"CAST({str} AS {ColumnDefinition})"; + } + + return base.ToQuotedString(fieldType, value); + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + if (fieldType == typeof(SqlHierarchyId)) + { + var sqlParam = (SqlParameter)p; + sqlParam.IsNullable = fieldType.IsNullableType(); + sqlParam.SqlDbType = SqlDbType.Udt; + sqlParam.UdtTypeName = ColumnDefinition; + } + base.InitDbParam(p, fieldType); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value == null || value is DBNull) + return SqlHierarchyId.Null; + + if (value is SqlHierarchyId) + return (SqlHierarchyId)value; + + if (value is string) + { + return SqlHierarchyId.Parse(value.ToString()); + } + + return base.FromDbValue(fieldType, value); + } + + public override object ToDbValue(Type fieldType, object value) + { + if (value == null || value is DBNull) + { + return SqlHierarchyId.Null; + } + + if (value is SqlHierarchyId) + { + return value; + } + + if (value is string) + { + var str = value as string; + return SqlHierarchyId.Parse(str); + } + + return base.ToDbValue(fieldType, value); + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServer.Data/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.SqlServer.Data/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..22ae012d6 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Data/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.SqlServer.Data/ServiceStack.OrmLite.SqlServer.Data.Core.csproj b/src/ServiceStack.OrmLite.SqlServer.Data/ServiceStack.OrmLite.SqlServer.Data.Core.csproj new file mode 100644 index 000000000..f28b26da1 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Data/ServiceStack.OrmLite.SqlServer.Data.Core.csproj @@ -0,0 +1,91 @@ + + + + ServiceStack.OrmLite.SqlServer.Data.Core + netstandard2.0;net6.0 + ServiceStack.OrmLite.SqlServer.Data + ServiceStack.OrmLite.SqlServer + ServiceStack.OrmLite.SqlServer.Data .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite.SqlServer.Data + + SQLServer;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC;MSDATA + + + + + + + + + + + Converters\SqlServerBoolConverter.cs + + + Converters\SqlServerByteArrayConverter.cs + + + Converters\SqlServerDateTime2Converter.cs + + + Converters\SqlServerDateTimeConverter.cs + + + Converters\SqlServerFloatConverters.cs + + + Converters\SqlServerGuidConverter.cs + + + Converters\SqlServerIntegerConverters.cs + + + Converters\SqlServerJsonStringConverters.cs + + + Converters\SqlServerSpecialConverters.cs + + + Converters\SqlServerStringConverters.cs + + + Converters\SqlServerTimeConverter.cs + + + SqlServer2008OrmLiteDialectProvider.cs + + + SqlServer2012OrmLiteDialectProvider.cs + + + SqlServer2014OrmLiteDialectProvider.cs + + + SqlServer2016Expression.cs + + + SqlServer2016OrmLiteDialectProvider.cs + + + SqlServer2017OrmLiteDialectProvider.cs + + + SqlServer2019OrmLiteDialectProvider.cs + + + SqlServerDialect.cs + + + SqlServerExpression.cs + + + SqlServerOrmLiteDialectProvider.cs + + + SqlServerTableHint.cs + + + + diff --git a/src/ServiceStack.OrmLite.SqlServer.Data/ServiceStack.OrmLite.SqlServer.Data.csproj b/src/ServiceStack.OrmLite.SqlServer.Data/ServiceStack.OrmLite.SqlServer.Data.csproj new file mode 100644 index 000000000..0e1912d4a --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer.Data/ServiceStack.OrmLite.SqlServer.Data.csproj @@ -0,0 +1,93 @@ + + + + ServiceStack.OrmLite.SqlServer.Data + netstandard2.0;net6.0 + ServiceStack.OrmLite.SqlServer.Data + ServiceStack.OrmLite.SqlServer + OrmLite.SqlServer - Fast, code-first, config-free POCO ORM + + Uses Microsoft.Data.SqlClient. + Light, simple and fast convention-based code-first POCO ORM for Sql Server. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLServer. + + SQLServer;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC;MSDATA + + + + + + + + + + + Converters\SqlServerBoolConverter.cs + + + Converters\SqlServerByteArrayConverter.cs + + + Converters\SqlServerDateTime2Converter.cs + + + Converters\SqlServerDateTimeConverter.cs + + + Converters\SqlServerFloatConverters.cs + + + Converters\SqlServerGuidConverter.cs + + + Converters\SqlServerIntegerConverters.cs + + + Converters\SqlServerJsonStringConverters.cs + + + Converters\SqlServerSpecialConverters.cs + + + Converters\SqlServerStringConverters.cs + + + Converters\SqlServerTimeConverter.cs + + + SqlServer2008OrmLiteDialectProvider.cs + + + SqlServer2012OrmLiteDialectProvider.cs + + + SqlServer2014OrmLiteDialectProvider.cs + + + SqlServer2016Expression.cs + + + SqlServer2016OrmLiteDialectProvider.cs + + + SqlServer2017OrmLiteDialectProvider.cs + + + SqlServer2019OrmLiteDialectProvider.cs + + + SqlServerDialect.cs + + + SqlServerExpression.cs + + + SqlServerOrmLiteDialectProvider.cs + + + SqlServerTableHint.cs + + + + diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerBoolConverter.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerBoolConverter.cs new file mode 100644 index 000000000..496616b1d --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerBoolConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerBoolConverter : BoolConverter + { + public override string ColumnDefinition + { + get { return "BIT"; } + } + + public override DbType DbType + { + get { return DbType.Boolean; } + } + + public override object ToDbValue(Type fieldType, object value) + { + if (value is bool) + return value; + + return 0 != (long)this.ConvertNumber(typeof(long), value); + } + + public override string ToQuotedString(Type fieldType, object value) + { + var boolValue = (bool)value; + return base.DialectProvider.GetQuotedValue(boolValue ? 1 : 0, typeof(int)); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is bool) + return value; + + return 0 != (long)this.ConvertNumber(typeof(long), value); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerByteArrayConverter.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerByteArrayConverter.cs new file mode 100644 index 000000000..e091eec42 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerByteArrayConverter.cs @@ -0,0 +1,15 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerByteArrayConverter : ByteArrayConverter + { + public override string ColumnDefinition => "VARBINARY(MAX)"; + + public override string ToQuotedString(Type fieldType, object value) + { + return "0x" + BitConverter.ToString((byte[])value).Replace("-", ""); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerDateTime2Converter.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerDateTime2Converter.cs new file mode 100644 index 000000000..bd62dadee --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerDateTime2Converter.cs @@ -0,0 +1,28 @@ +using System; +using System.Data; +using System.Globalization; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerDateTime2Converter : SqlServerDateTimeConverter + { + public override string ColumnDefinition => "DATETIME2"; + + const string DateTimeFormat = "yyyyMMdd HH:mm:ss.fffffff"; + + public override DbType DbType => DbType.DateTime2; + + public override string ToQuotedString(Type fieldType, object value) + { + return DateTimeFmt((DateTime)value, DateTimeFormat); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is string str && DateTime.TryParseExact(str, DateTimeFormat, null, DateTimeStyles.None, out var date)) + return date; + + return base.FromDbValue(fieldType, value); + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerDateTimeConverter.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerDateTimeConverter.cs new file mode 100644 index 000000000..566097314 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerDateTimeConverter.cs @@ -0,0 +1,24 @@ +using System; +using ServiceStack.OrmLite.Converters; +using System.Globalization; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerDateTimeConverter : DateTimeConverter + { + const string DateTimeFormat = "yyyyMMdd HH:mm:ss.fff"; + + public override string ToQuotedString(Type fieldType, object value) + { + return DateTimeFmt((DateTime)value, DateTimeFormat); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is string str && DateTime.TryParseExact(str, DateTimeFormat, null, DateTimeStyles.None, out var date)) + return date; + + return base.FromDbValue(fieldType, value); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerFloatConverters.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerFloatConverters.cs new file mode 100644 index 000000000..e33644181 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerFloatConverters.cs @@ -0,0 +1,25 @@ +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerFloatConverter : FloatConverter + { + public override string ColumnDefinition + { + get { return "FLOAT"; } + } + } + + public class SqlServerDoubleConverter : DoubleConverter + { + public override string ColumnDefinition + { + get { return "FLOAT"; } + } + } + + public class SqlServerDecimalConverter : DecimalConverter + { + public SqlServerDecimalConverter() : base(38, 6) {} + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerGuidConverter.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerGuidConverter.cs new file mode 100644 index 000000000..b66580f02 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerGuidConverter.cs @@ -0,0 +1,20 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerGuidConverter : GuidConverter + { + public override string ColumnDefinition + { + get { return "UniqueIdentifier"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var guidValue = (Guid)value; + return string.Format("CAST('{0}' AS UNIQUEIDENTIFIER)", guidValue); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerIntegerConverters.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerIntegerConverters.cs new file mode 100644 index 000000000..afed55b32 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerIntegerConverters.cs @@ -0,0 +1,38 @@ +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + //throws unknown type exceptions in parameterized queries, e.g: p.DbType = DbType.SByte + public class SqlServerSByteConverter : SByteConverter + { + public override DbType DbType + { + get { return DbType.Byte; } + } + } + + public class SqlServerUInt16Converter : UInt16Converter + { + public override DbType DbType + { + get { return DbType.Int16; } + } + } + + public class SqlServerUInt32Converter : UInt32Converter + { + public override DbType DbType + { + get { return DbType.Int32; } + } + } + + public class SqlServerUInt64Converter : UInt64Converter + { + public override DbType DbType + { + get { return DbType.Int64; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerJsonStringConverters.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerJsonStringConverters.cs new file mode 100644 index 000000000..30efaa125 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerJsonStringConverters.cs @@ -0,0 +1,30 @@ +using System; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerJsonStringConverter : SqlServerStringConverter + { + // json string to object + public override object FromDbValue(Type fieldType, object value) + { + if (value is string raw && fieldType.HasAttributeCached()) + return JsonSerializer.DeserializeFromString(raw, fieldType); + + return base.FromDbValue(fieldType, value); + } + + // object to json string + public override object ToDbValue(Type fieldType, object value) + { + if (value.GetType().HasAttributeCached()) + return JsonSerializer.SerializeToString(value, value.GetType()); + + return base.ToDbValue(fieldType, value); + } + } + + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public class SqlJsonAttribute : Attribute + { } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerSpecialConverters.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerSpecialConverters.cs new file mode 100644 index 000000000..ddd0ca8a4 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerSpecialConverters.cs @@ -0,0 +1,9 @@ +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerRowVersionConverter : RowVersionConverter + { + public override string ColumnDefinition => "rowversion"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerStringConverters.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerStringConverters.cs new file mode 100644 index 000000000..802aad772 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerStringConverters.cs @@ -0,0 +1,45 @@ +using System; +using System.Data; +#if MSDATA +using Microsoft.Data.SqlClient; +#else +using System.Data.SqlClient; +#endif +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerStringConverter : StringConverter + { + public override string MaxColumnDefinition => UseUnicode ? "NVARCHAR(MAX)" : "VARCHAR(MAX)"; + + public override int MaxVarCharLength => UseUnicode ? 4000 : 8000; + + public override string GetColumnDefinition(int? stringLength) + { + if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText) + return MaxColumnDefinition; + + var safeLength = Math.Min( + stringLength.GetValueOrDefault(StringLength), + UseUnicode ? 4000 : 8000); + + return UseUnicode + ? $"NVARCHAR({safeLength})" + : $"VARCHAR({safeLength})"; + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + base.InitDbParam(p, fieldType); + + if (!(p is SqlParameter sqlParam)) return; + + if (!UseUnicode) + { + sqlParam.SqlDbType = SqlDbType.VarChar; + } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerTimeConverter.cs b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerTimeConverter.cs new file mode 100644 index 000000000..a3d62575c --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/Converters/SqlServerTimeConverter.cs @@ -0,0 +1,24 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.SqlServer.Converters +{ + public class SqlServerTimeConverter : OrmLiteConverter + { + private static readonly DateTime timeSpanOffset = new DateTime(1900, 01, 01); + + public int? Precision { get; set; } + + public override string ColumnDefinition => Precision != null + ? $"TIME({Precision.Value})" + : "TIME"; + + public override DbType DbType => DbType.DateTime; + + public override object ToDbValue(Type fieldType, object value) + { + var timeSpan = (TimeSpan)value; + return timeSpanOffset + timeSpan; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.SqlServer/Properties/AssemblyInfo.cs index aad420ac7..22ae012d6 100644 --- a/src/ServiceStack.OrmLite.SqlServer/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite.SqlServer/Properties/AssemblyInfo.cs @@ -1,26 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.SqlServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.SqlServer")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("19f4a9ca-8076-4743-a4f3-e60708f24708")] - -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Core.csproj b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Core.csproj new file mode 100644 index 000000000..c928e7da5 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Core.csproj @@ -0,0 +1,29 @@ + + + + ServiceStack.OrmLite.SqlServer.Core + ServiceStack.OrmLite.SqlServer + ServiceStack.OrmLite.SqlServer + netstandard2.0;net6.0 + ServiceStack.OrmLite.SqlServer .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite.SqlServer + + SQLServer;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Signed.csproj b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Signed.csproj deleted file mode 100644 index 4cab5ffc7..000000000 --- a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Signed.csproj +++ /dev/null @@ -1,134 +0,0 @@ - - - - Debug - AnyCPU - 9.0.21022 - 2.0 - {1887DC99-9139-43E3-A7AA-6D74714B3A5D} - Library - Properties - ServiceStack.OrmLite.SqlServer - ServiceStack.OrmLite.SqlServer - v4.0 - 512 - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - AllRules.ruleset - - - true - - - servicestack-sn.pfx - - - - False - ..\..\lib\signed\ServiceStack.Common.dll - - - False - ..\..\lib\ServiceStack.Interfaces.dll - - - False - ..\..\lib\signed\ServiceStack.Text.dll - - - - 3.5 - - - 3.5 - - - 3.5 - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Source.csproj b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Source.csproj new file mode 100644 index 000000000..3d53cade1 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.Source.csproj @@ -0,0 +1,30 @@ + + + + ServiceStack.OrmLite.SqlServer + ServiceStack.OrmLite.SqlServer + netstandard2.0;net6.0 + OrmLite.SqlServer - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for Sql Server. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLServer. + + SQLServer;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + false + $(DefineConstants);ASYNC + + + + + + + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.csproj b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.csproj index cf8f1e6a6..60968f012 100644 --- a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.csproj +++ b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServer.csproj @@ -1,128 +1,29 @@ - - + + - Debug - AnyCPU - 9.0.21022 - 2.0 - {1887DC99-9139-43E3-A7AA-6D74714B3A5D} - Library - Properties - ServiceStack.OrmLite.SqlServer + ServiceStack.OrmLite.SqlServer ServiceStack.OrmLite.SqlServer - v4.0 - 512 - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - AllRules.ruleset + net472;netstandard2.0;net6.0 + OrmLite.SqlServer - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for Sql Server. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLServer. + + SQLServer;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + - - False - ..\..\lib\ServiceStack.Common.dll - - - False - ..\..\lib\ServiceStack.Interfaces.dll - - - False - ..\..\lib\ServiceStack.Text.dll - - - - 3.5 - - - 3.5 - - - 3.5 - - - + + - - - - - + + + - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - + + + - - - \ No newline at end of file + + diff --git a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServerV45.Signed.csproj b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServerV45.Signed.csproj deleted file mode 100644 index 9774bf5d7..000000000 --- a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServerV45.Signed.csproj +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Debug - AnyCPU - {9A5CCB1A-D127-41D1-9F25-91848E60672B} - Library - Properties - ServiceStack.OrmLite.SqlServer - ServiceStack.OrmLite.SqlServer - v4.5 - 512 - - - true - full - false - bin\net45_Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\net45\ - TRACE;NET45 - prompt - 4 - - - bin\net45_Signed\ - TRACE;NET45 - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - true - - - servicestack-sn.pfx - - - - ..\..\lib\signed\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\signed\ServiceStack.Text.dll - - - - - - - - - - - - SqlServerDialect.cs - - - SqlServerExpression.cs - - - SqlServerOrmLiteDialectProvider.cs - - - - - - - - - {96179ac6-f6f1-40c3-9fdd-4f6582f54c5c} - ServiceStack.OrmLite - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServerV45.csproj b/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServerV45.csproj deleted file mode 100644 index a9553c7a2..000000000 --- a/src/ServiceStack.OrmLite.SqlServer/ServiceStack.OrmLite.SqlServerV45.csproj +++ /dev/null @@ -1,88 +0,0 @@ - - - - - Debug - AnyCPU - {9A5CCB1A-D127-41D1-9F25-91848E60672B} - Library - Properties - ServiceStack.OrmLite.SqlServer - ServiceStack.OrmLite.SqlServer - v4.5 - 512 - - - true - full - false - bin\net45_Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\net45\ - TRACE;NET45 - prompt - 4 - - - bin\net45_Signed\ - TRACE;NET45 - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - SqlServerDialect.cs - - - SqlServerExpression.cs - - - SqlServerOrmLiteDialectProvider.cs - - - - - - - - - {fdc37335-9ecc-413b-bec5-16b466b0e689} - ServiceStack.OrmLiteV45 - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServer2008OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServer2008OrmLiteDialectProvider.cs new file mode 100644 index 000000000..8acb4a049 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServer2008OrmLiteDialectProvider.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Text; + +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServer2008OrmLiteDialectProvider : SqlServerOrmLiteDialectProvider + { + public new static SqlServer2008OrmLiteDialectProvider Instance = new SqlServer2008OrmLiteDialectProvider(); + + public override string SqlConcat(IEnumerable args) + { + var sb = new StringBuilder(); + foreach (var arg in args) + { + if (sb.Length > 0) + sb.Append(" + "); + + var argType = arg.GetType(); + if (argType.IsValueType) + { + sb.AppendFormat("'{0}'", arg); + } + else if (arg is string s && s.StartsWith("'") || arg is PartialSqlString p) + { + sb.Append(arg); + } + else + { + sb.Append($"CAST({arg} AS VARCHAR(MAX))"); + } + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServer2012OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServer2012OrmLiteDialectProvider.cs new file mode 100644 index 000000000..99842f335 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServer2012OrmLiteDialectProvider.cs @@ -0,0 +1,307 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServer2012OrmLiteDialectProvider : SqlServerOrmLiteDialectProvider + { + public new static SqlServer2012OrmLiteDialectProvider Instance = new SqlServer2012OrmLiteDialectProvider(); + + public override bool DoesSequenceExist(IDbCommand dbCmd, string sequenceName) + { + var sql = "SELECT CASE WHEN EXISTS (SELECT 1 FROM sys.sequences WHERE object_id=object_id({0})) THEN 1 ELSE 0 END" + .SqlFmt(this, sequenceName); + + var result = dbCmd.ExecLongScalar(sql); + + return result == 1; + } + + public override async Task DoesSequenceExistAsync(IDbCommand dbCmd, string sequenceName, CancellationToken token = default) + { + var sql = "SELECT CASE WHEN EXISTS (SELECT 1 FROM sys.sequences WHERE object_id=object_id({0})) THEN 1 ELSE 0 END" + .SqlFmt(this, sequenceName); + + var result = await dbCmd.ExecLongScalarAsync(sql, token); + + return result == 1; + } + + protected override string GetAutoIncrementDefinition(FieldDefinition fieldDef) + { + if (!string.IsNullOrEmpty(fieldDef.Sequence)) + return $"DEFAULT NEXT VALUE FOR {Sequence(NamingStrategy.GetSchemaName(GetModel(fieldDef.PropertyInfo?.ReflectedType)), fieldDef.Sequence)}"; + else + return AutoIncrementDefinition; + } + + protected override bool ShouldSkipInsert(FieldDefinition fieldDef) => + fieldDef.ShouldSkipInsert() && string.IsNullOrEmpty(fieldDef.Sequence); + + protected override bool SupportsSequences(FieldDefinition fieldDef) => + !string.IsNullOrEmpty(fieldDef.Sequence); + + public override List ToCreateSequenceStatements(Type tableType) + { + var modelDef = GetModel(tableType); + return SequenceList(tableType).Select(seq => $"CREATE SEQUENCE {Sequence(NamingStrategy.GetSchemaName(modelDef), seq)} AS BIGINT START WITH 1 INCREMENT BY 1 NO CACHE;").ToList(); + } + + public override string ToCreateSequenceStatement(Type tableType, string sequenceName) + { + var modelDef = GetModel(tableType); + return $"CREATE SEQUENCE {Sequence(NamingStrategy.GetSchemaName(modelDef), sequenceName)} AS BIGINT START WITH 1 INCREMENT BY 1 NO CACHE;"; + } + + public override List SequenceList(Type tableType) + { + var gens = new List(); + var modelDef = GetModel(tableType); + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (!string.IsNullOrEmpty(fieldDef.Sequence)) + { + gens.AddIfNotExists(fieldDef.Sequence); + } + } + return gens; + } + + public override string ToSelectStatement(QueryType queryType, ModelDefinition modelDef, + string selectExpression, + string bodyExpression, + string orderByExpression = null, + int? offset = null, + int? rows = null, + ISet tags=null) + { + var sb = StringBuilderCache.Allocate(); + ApplyTags(sb, tags); + + sb.Append(selectExpression) + .Append(bodyExpression); + + if (!string.IsNullOrEmpty(orderByExpression)) + sb.Append(orderByExpression); + + var skip = offset ?? 0; + if (skip > 0 || rows is > 0) + { + // Use TOP if offset is unspecified + if (skip == 0) + { + var sql = StringBuilderCache.ReturnAndFree(sb); + return SqlTop(sql, rows.GetValueOrDefault()); + } + + if (queryType == QueryType.Select || rows == 1) + { + // ORDER BY mandatory when using OFFSET/FETCH NEXT + if (orderByExpression.IsEmpty()) + { + var orderBy = rows == 1 //Avoid for Single requests + ? "1" + : this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey); + + sb.Append(" ORDER BY " + orderBy); + } + sb.Append(" ").Append(SqlLimit(offset, rows)); + } + } + + return StringBuilderCache.ReturnAndFree(sb); + } + + public override string GetColumnDefinition(FieldDefinition fieldDef) + { + // https://msdn.microsoft.com/en-us/library/ms182776.aspx + if (fieldDef.IsRowVersion) + return $"{fieldDef.FieldName} rowversion NOT NULL"; + + var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) ?? + GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale); + + var sql = StringBuilderCache.Allocate(); + sql.Append($"{GetQuotedColumnName(fieldDef.FieldName)} {fieldDefinition}"); + + if (fieldDef.FieldType == typeof(string)) + { + // https://msdn.microsoft.com/en-us/library/ms184391.aspx + var collation = fieldDef.PropertyInfo?.FirstAttribute()?.Collation; + if (!string.IsNullOrEmpty(collation)) + { + sql.Append($" COLLATE {collation}"); + } + } + + if (fieldDef.IsPrimaryKey) + { + sql.Append(" PRIMARY KEY"); + + if (fieldDef.IsNonClustered) + sql.Append(" NONCLUSTERED"); + + if (fieldDef.AutoIncrement) + { + sql.Append(" ").Append(AutoIncrementDefinition); + } + } + else + { + sql.Append(fieldDef.IsNullable ? " NULL" : " NOT NULL"); + } + + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } + + var defaultValue = GetDefaultValue(fieldDef); + if (!string.IsNullOrEmpty(defaultValue)) + { + sql.AppendFormat(DefaultValueFormat, defaultValue); + } + + return StringBuilderCache.ReturnAndFree(sql); + } + + public override string ToCreateTableStatement(Type tableType) + { + var sbColumns = StringBuilderCache.Allocate(); + var sbConstraints = StringBuilderCacheAlt.Allocate(); + var sbTableOptions = StringBuilderCacheAlt.Allocate(); + + var fileTableAttrib = tableType.FirstAttribute(); + + var modelDef = GetModel(tableType); + + if (fileTableAttrib == null) + { + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (fieldDef.CustomSelect != null || (fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; + + var columnDefinition = GetColumnDefinition(fieldDef); + + if (columnDefinition == null) + continue; + + if (sbColumns.Length != 0) + sbColumns.Append(", \n "); + + sbColumns.Append(columnDefinition); + + var sqlConstraint = GetCheckConstraint(modelDef, fieldDef); + if (sqlConstraint != null) + { + sbConstraints.Append(",\n" + sqlConstraint); + } + + if (fieldDef.ForeignKey == null || OrmLiteConfig.SkipForeignKeys) + continue; + + var refModelDef = GetModel(fieldDef.ForeignKey.ReferenceType); + sbConstraints.Append( + $", \n\n CONSTRAINT {GetQuotedName(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef))} " + + $"FOREIGN KEY ({GetQuotedColumnName(fieldDef.FieldName)}) " + + $"REFERENCES {GetQuotedTableName(refModelDef)} ({GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)})"); + + sbConstraints.Append(GetForeignKeyOnDeleteClause(fieldDef.ForeignKey)); + sbConstraints.Append(GetForeignKeyOnUpdateClause(fieldDef.ForeignKey)); + } + } + else + { + if (fileTableAttrib.FileTableDirectory != null || fileTableAttrib.FileTableCollateFileName != null) + { + sbTableOptions.Append(" WITH ("); + + if (fileTableAttrib.FileTableDirectory != null) + { + sbTableOptions.Append($" FILETABLE_DIRECTORY = N'{fileTableAttrib.FileTableDirectory}'\n"); + } + + if (fileTableAttrib.FileTableCollateFileName != null) + { + if (fileTableAttrib.FileTableDirectory != null) + sbTableOptions.Append(" ,"); + + sbTableOptions.Append($" FILETABLE_COLLATE_FILENAME = {fileTableAttrib.FileTableCollateFileName ?? "database_default" }\n"); + } + sbTableOptions.Append(")"); + } + } + + var uniqueConstraints = GetUniqueConstraints(modelDef); + if (uniqueConstraints != null) + { + sbConstraints.Append(",\n" + uniqueConstraints); + } + + var sql = $"CREATE TABLE {GetQuotedTableName(modelDef)} "; + sql += (fileTableAttrib != null) + ? $"\n AS FILETABLE{StringBuilderCache.ReturnAndFree(sbTableOptions)};" + : $"\n(\n {StringBuilderCache.ReturnAndFree(sbColumns)}{StringBuilderCacheAlt.ReturnAndFree(sbConstraints)} \n){StringBuilderCache.ReturnAndFree(sbTableOptions)}; \n"; + + return sql; + } + + public override void AppendFieldCondition(StringBuilder sqlFilter, FieldDefinition fieldDef, IDbCommand cmd) + { + if (isSpatialField(fieldDef)) + { + // Append condition statement to determine if SqlGeometry or SqlGeography type is Equal + // using the type's STEquals method + // + // SqlGeometry: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeometry.stequals.aspx + // SqlGeography: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeography.stequals.aspx + sqlFilter + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append(".STEquals(") + .Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))) + .Append(") = 1"); + + AddParameter(cmd, fieldDef); + } + else + { + base.AppendFieldCondition(sqlFilter, fieldDef, cmd); + } + } + + public override void AppendNullFieldCondition(StringBuilder sqlFilter, FieldDefinition fieldDef) + { + if (hasIsNullProperty(fieldDef)) + { + // Append condition statement to determine if SqlHierarchyId, SqlGeometry, or SqlGeography type is NULL + // using the type's IsNull property + // + // SqlHierarchyId: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlhierarchyid.isnull.aspx + // SqlGeometry: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeometry.isnull.aspx + // SqlGeography: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeography.isnull.aspx + sqlFilter + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append(".IsNull = 1"); + } + else + { + base.AppendNullFieldCondition(sqlFilter, fieldDef); + } + } + + internal bool isSpatialField(FieldDefinition fieldDef) => + fieldDef.FieldType.Name == "SqlGeography" || fieldDef.FieldType.Name == "SqlGeometry"; + + internal bool hasIsNullProperty(FieldDefinition fieldDef) => + isSpatialField(fieldDef) || fieldDef.FieldType.Name == "SqlHierarchyId"; + } +} diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServer2014OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServer2014OrmLiteDialectProvider.cs new file mode 100644 index 000000000..8c6f2dc8e --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServer2014OrmLiteDialectProvider.cs @@ -0,0 +1,189 @@ +using System; +using ServiceStack.Text; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServer2014OrmLiteDialectProvider : SqlServer2012OrmLiteDialectProvider + { + public new static SqlServer2014OrmLiteDialectProvider Instance = new SqlServer2014OrmLiteDialectProvider(); + + public override string GetColumnDefinition(FieldDefinition fieldDef) + { + // https://msdn.microsoft.com/en-us/library/ms182776.aspx + if (fieldDef.IsRowVersion) + return $"{fieldDef.FieldName} rowversion NOT NULL"; + + var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) ?? + GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale); + + var memTableAttrib = fieldDef.PropertyInfo?.ReflectedType.FirstAttribute(); + var isMemoryTable = memTableAttrib != null; + + var sql = StringBuilderCache.Allocate(); + sql.Append($"{GetQuotedColumnName(fieldDef.FieldName)} {fieldDefinition}"); + + if (fieldDef.FieldType == typeof(string)) + { + // https://msdn.microsoft.com/en-us/library/ms184391.aspx + var collation = fieldDef.PropertyInfo?.FirstAttribute()?.Collation; + if (!string.IsNullOrEmpty(collation)) + { + sql.Append($" COLLATE {collation}"); + } + } + + var bucketCount = fieldDef.PropertyInfo?.FirstAttribute()?.Count; + + if (fieldDef.IsPrimaryKey) + { + if (isMemoryTable) + { + sql.Append($" NOT NULL PRIMARY KEY NONCLUSTERED"); + } + else + { + sql.Append(" PRIMARY KEY"); + + if (fieldDef.IsNonClustered) + sql.Append(" NONCLUSTERED"); + } + + if (fieldDef.AutoIncrement) + { + sql.Append(" ").Append(GetAutoIncrementDefinition(fieldDef)); + } + + if (isMemoryTable && bucketCount.HasValue) + { + sql.Append($" HASH WITH (BUCKET_COUNT = {bucketCount.Value})"); + } + } + else + { + if (isMemoryTable && bucketCount.HasValue) + { + sql.Append($" NOT NULL INDEX {GetQuotedColumnName("IDX_" + fieldDef.FieldName)}"); + + if (fieldDef.IsNonClustered) + { + sql.Append(" NONCLUSTERED"); + } + + sql.Append($" HASH WITH (BUCKET_COUNT = {bucketCount.Value})"); + } + else + { + sql.Append(fieldDef.IsNullable ? " NULL" : " NOT NULL"); + } + } + + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } + + var defaultValue = GetDefaultValue(fieldDef); + if (!string.IsNullOrEmpty(defaultValue)) + { + sql.AppendFormat(DefaultValueFormat, defaultValue); + } + + return StringBuilderCache.ReturnAndFree(sql); + } + + public override string ToCreateTableStatement(Type tableType) + { + var sbColumns = StringBuilderCache.Allocate(); + var sbConstraints = StringBuilderCacheAlt.Allocate(); + var sbTableOptions = StringBuilderCacheAlt.Allocate(); + + var fileTableAttrib = tableType.FirstAttribute(); + var memoryTableAttrib = tableType.FirstAttribute(); + + var modelDef = GetModel(tableType); + + if (fileTableAttrib == null) + { + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (fieldDef.CustomSelect != null || (fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; + + var columnDefinition = GetColumnDefinition(fieldDef); + if (columnDefinition == null) + continue; + + if (sbColumns.Length != 0) + sbColumns.Append(", \n "); + + sbColumns.Append(columnDefinition); + + var sqlConstraint = GetCheckConstraint(modelDef, fieldDef); + if (sqlConstraint != null) + { + sbConstraints.Append(",\n" + sqlConstraint); + } + + if (fieldDef.ForeignKey == null || OrmLiteConfig.SkipForeignKeys) + continue; + + var refModelDef = OrmLiteUtils.GetModelDefinition(fieldDef.ForeignKey.ReferenceType); + sbConstraints.Append( + $", \n\n CONSTRAINT {GetQuotedName(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef))} " + + $"FOREIGN KEY ({GetQuotedColumnName(fieldDef.FieldName)}) " + + $"REFERENCES {GetQuotedTableName(refModelDef)} ({GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)})"); + + sbConstraints.Append(GetForeignKeyOnDeleteClause(fieldDef.ForeignKey)); + sbConstraints.Append(GetForeignKeyOnUpdateClause(fieldDef.ForeignKey)); + } + + if (memoryTableAttrib != null) + { + var attrib = tableType.FirstAttribute(); + sbTableOptions.Append(" WITH (MEMORY_OPTIMIZED = ON"); + if (attrib.Durability == SqlServerDurability.SchemaOnly) + sbTableOptions.Append(", DURABILITY = SCHEMA_ONLY"); + else if (attrib.Durability == SqlServerDurability.SchemaAndData) + sbTableOptions.Append(", DURABILITY = SCHEMA_AND_DATA"); + sbTableOptions.Append(")"); + } + } + else + { + var hasFileTableDir = !string.IsNullOrEmpty(fileTableAttrib.FileTableDirectory); + var hasFileTableCollateFileName = !string.IsNullOrEmpty(fileTableAttrib.FileTableCollateFileName); + + if (hasFileTableDir || hasFileTableCollateFileName) + { + sbTableOptions.Append(" WITH ("); + + if (hasFileTableDir) + { + sbTableOptions.Append($" FILETABLE_DIRECTORY = N'{fileTableAttrib.FileTableDirectory}'\n"); + } + + if (hasFileTableCollateFileName) + { + if (hasFileTableDir) sbTableOptions.Append(" ,"); + sbTableOptions.Append($" FILETABLE_COLLATE_FILENAME = {fileTableAttrib.FileTableCollateFileName ?? "database_default" }\n"); + } + sbTableOptions.Append(")"); + } + } + + var uniqueConstraints = GetUniqueConstraints(modelDef); + if (uniqueConstraints != null) + { + sbConstraints.Append(",\n" + uniqueConstraints); + } + + var sql = $"CREATE TABLE {GetQuotedTableName(modelDef)} "; + sql += (fileTableAttrib != null) + ? $"\n AS FILETABLE{StringBuilderCache.ReturnAndFree(sbTableOptions)};" + : $"\n(\n {StringBuilderCache.ReturnAndFree(sbColumns)}{StringBuilderCacheAlt.ReturnAndFree(sbConstraints)} \n){StringBuilderCache.ReturnAndFree(sbTableOptions)}; \n"; + + return sql; + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServer2016Expression.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServer2016Expression.cs new file mode 100644 index 000000000..be455ffbc --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServer2016Expression.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServer2016Expression : SqlServerExpression + { + public SqlServer2016Expression(IOrmLiteDialectProvider dialectProvider) + : base(dialectProvider) {} + + protected override object VisitSqlMethodCall(MethodCallExpression m) + { + List args = VisitInSqlExpressionList(m.Arguments); + object quotedColName = args[0]; + args.RemoveAt(0); + + string statement; + + switch (m.Method.Name) + { + case nameof(Sql.In): + statement = ConvertInExpressionToSql(m, quotedColName); + break; + case nameof(Sql.Desc): + statement = $"{quotedColName} DESC"; + break; + case nameof(Sql.As): + statement = $"{quotedColName} AS {DialectProvider.GetQuotedColumnName(RemoveQuoteFromAlias(args[0].ToString()))}"; + break; + case nameof(Sql.Cast): + statement = DialectProvider.SqlCast(quotedColName, args[0].ToString()); + break; + case nameof(Sql.Sum): + case nameof(Sql.Count): + case nameof(Sql.Min): + case nameof(Sql.Max): + case nameof(Sql.Avg): + statement = $"{m.Method.Name}({quotedColName}{(args.Count == 1 ? $",{args[0]}" : "")})"; + break; + case nameof(Sql.CountDistinct): + statement = $"COUNT(DISTINCT {quotedColName})"; + break; + case nameof(Sql.AllFields): + var argDef = m.Arguments[0].Type.GetModelMetadata(); + statement = DialectProvider.GetQuotedTableName(argDef) + ".*"; + break; + case nameof(Sql.JoinAlias): + case nameof(Sql.TableAlias): + statement = args[0] + "." + quotedColName.ToString().LastRightPart('.'); + break; + case nameof(Sql.Custom): + statement = quotedColName.ToString(); + break; + case nameof(Sql.IsJson): + statement = $"ISJSON({quotedColName})"; + break; + case nameof(Sql.JsonValue): + statement = $"JSON_VALUE({quotedColName}, '{args[0]}')"; + break; + case nameof(Sql.JsonQuery): + statement = $"JSON_QUERY({quotedColName}"; + if (DialectProvider is SqlServer2017OrmLiteDialectProvider && args.Count > 0) + { + statement += $", '{args[0]}'"; + } + statement += ")"; + break; + default: + throw new NotSupportedException(); + } + + return new PartialSqlString(statement); + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServer2016OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServer2016OrmLiteDialectProvider.cs new file mode 100644 index 000000000..3a443deca --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServer2016OrmLiteDialectProvider.cs @@ -0,0 +1,18 @@ +using System; + +using ServiceStack.OrmLite.SqlServer.Converters; + +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServer2016OrmLiteDialectProvider : SqlServer2014OrmLiteDialectProvider + { + public SqlServer2016OrmLiteDialectProvider() : base() + { + base.RegisterConverter(new SqlServerJsonStringConverter()); + } + + public new static SqlServer2016OrmLiteDialectProvider Instance = new SqlServer2016OrmLiteDialectProvider(); + + public override SqlExpression SqlExpression() => new SqlServer2016Expression(this); + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServer2017OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServer2017OrmLiteDialectProvider.cs new file mode 100644 index 000000000..ac19ab19c --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServer2017OrmLiteDialectProvider.cs @@ -0,0 +1,7 @@ +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServer2017OrmLiteDialectProvider : SqlServer2016OrmLiteDialectProvider + { + public new static SqlServer2017OrmLiteDialectProvider Instance = new SqlServer2017OrmLiteDialectProvider(); + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServer2019OrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServer2019OrmLiteDialectProvider.cs new file mode 100644 index 000000000..76e2a7a2c --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServer2019OrmLiteDialectProvider.cs @@ -0,0 +1,7 @@ +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServer2019OrmLiteDialectProvider : SqlServer2017OrmLiteDialectProvider + { + public new static SqlServer2019OrmLiteDialectProvider Instance = new SqlServer2019OrmLiteDialectProvider(); + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServerDialect.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServerDialect.cs index c8d12a1f8..b788d1492 100644 --- a/src/ServiceStack.OrmLite.SqlServer/SqlServerDialect.cs +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServerDialect.cs @@ -4,6 +4,44 @@ namespace ServiceStack.OrmLite { public static class SqlServerDialect { - public static IOrmLiteDialectProvider Provider { get { return SqlServerOrmLiteDialectProvider.Instance; } } + public static IOrmLiteDialectProvider Provider => SqlServer2012Dialect.Instance; + public static SqlServerOrmLiteDialectProvider Instance => SqlServer2012Dialect.Instance; } + + public static class SqlServer2008Dialect + { + public static IOrmLiteDialectProvider Provider => SqlServer2008OrmLiteDialectProvider.Instance; + public static SqlServer2008OrmLiteDialectProvider Instance => SqlServer2008OrmLiteDialectProvider.Instance; + } + + public static class SqlServer2012Dialect + { + public static IOrmLiteDialectProvider Provider => SqlServer2012OrmLiteDialectProvider.Instance; + public static SqlServer2012OrmLiteDialectProvider Instance => SqlServer2012OrmLiteDialectProvider.Instance; + } + + public static class SqlServer2014Dialect + { + public static IOrmLiteDialectProvider Provider => SqlServer2014OrmLiteDialectProvider.Instance; + public static SqlServer2014OrmLiteDialectProvider Instance => SqlServer2014OrmLiteDialectProvider.Instance; + } + + public static class SqlServer2016Dialect + { + public static IOrmLiteDialectProvider Provider => SqlServer2016OrmLiteDialectProvider.Instance; + public static SqlServer2016OrmLiteDialectProvider Instance => SqlServer2016OrmLiteDialectProvider.Instance; + } + + public static class SqlServer2017Dialect + { + public static IOrmLiteDialectProvider Provider => SqlServer2017OrmLiteDialectProvider.Instance; + public static SqlServer2017OrmLiteDialectProvider Instance => SqlServer2017OrmLiteDialectProvider.Instance; + } + + public static class SqlServer2019Dialect + { + public static IOrmLiteDialectProvider Provider => SqlServer2019OrmLiteDialectProvider.Instance; + public static SqlServer2019OrmLiteDialectProvider Instance => SqlServer2019OrmLiteDialectProvider.Instance; + } + } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServerExpression.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServerExpression.cs index ff961c104..b4260d74a 100644 --- a/src/ServiceStack.OrmLite.SqlServer/SqlServerExpression.cs +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServerExpression.cs @@ -1,37 +1,104 @@ -using System.Text; +using System; +using System.Data; +using ServiceStack.OrmLite.SqlServer.Converters; +using ServiceStack.Text; namespace ServiceStack.OrmLite.SqlServer { - public class SqlServerExpression : SqlExpression - { + public class SqlServerExpression : SqlExpression + { public SqlServerExpression(IOrmLiteDialectProvider dialectProvider) : base(dialectProvider) {} - public override string ToUpdateStatement(T item, bool excludeDefaults = false) + public override void PrepareUpdateStatement(IDbCommand dbCmd, T item, bool excludeDefaults = false) { - var setFields = new StringBuilder(); + SqlServerExpressionUtils.PrepareSqlServerUpdateStatement(dbCmd, this, item, excludeDefaults); + } + + public override string GetSubstringSql(object quotedColumn, int startIndex, int? length = null) + { + return length != null + ? $"substring({quotedColumn}, {startIndex}, {length.Value})" + : $"substring({quotedColumn}, {startIndex}, LEN({quotedColumn}) - {startIndex} + 1)"; + } + + protected override PartialSqlString ToLengthPartialString(object arg) + { + return new PartialSqlString($"LEN({arg})"); + } + + protected override void ConvertToPlaceholderAndParameter(ref object right) + { + var paramName = Params.Count.ToString(); + var paramValue = right; + var parameter = CreateParam(paramName, paramValue); + + // Prevents a new plan cache for each different string length. Every string is parameterized as NVARCHAR(max) + if (parameter.DbType == System.Data.DbType.String) + parameter.Size = -1; + + Params.Add(parameter); + + right = parameter.ParameterName; + } + + protected override void VisitFilter(string operand, object originalLeft, object originalRight, ref object left, ref object right) + { + base.VisitFilter(operand, originalLeft, originalRight, ref left, ref right); + + if (originalRight is TimeSpan && DialectProvider.GetConverter() is SqlServerTimeConverter) + { + right = $"CAST({right} AS TIME)"; + } + } + + public override string ToDeleteRowStatement() + { + return base.tableDefs.Count > 1 + ? $"DELETE {DialectProvider.GetQuotedTableName(modelDef)} {FromExpression} {WhereExpression}" + : base.ToDeleteRowStatement(); + } + } + + internal class SqlServerExpressionUtils + { + internal static void PrepareSqlServerUpdateStatement(IDbCommand dbCmd, SqlExpression q, T item, bool excludeDefaults = false) + { + q.CopyParamsTo(dbCmd); + + var modelDef = q.ModelDef; + var dialectProvider = q.DialectProvider; - foreach (var fieldDef in ModelDef.FieldDefinitions) + var setFields = StringBuilderCache.Allocate(); + + foreach (var fieldDef in modelDef.FieldDefinitions) { if (fieldDef.ShouldSkipUpdate()) continue; if (fieldDef.IsRowVersion) continue; - if (UpdateFields.Count > 0 && !UpdateFields.Contains(fieldDef.Name) || fieldDef.AutoIncrement) continue; // added + if (q.UpdateFields.Count > 0 + && !q.UpdateFields.Contains(fieldDef.Name) + || fieldDef.AutoIncrement) + continue; // added var value = fieldDef.GetValue(item); - if (excludeDefaults && (value == null || value.Equals(value.GetType().GetDefaultValue()))) continue; //GetDefaultValue? - - fieldDef.GetQuotedValue(item); + if (excludeDefaults + && (value == null || (!fieldDef.IsNullable && value.Equals(value.GetType().GetDefaultValue())))) + continue; - if (setFields.Length > 0) + if (setFields.Length > 0) setFields.Append(", "); - setFields.AppendFormat("{0}={1}", - base.DialectProvider.GetQuotedColumnName(fieldDef.FieldName), - base.DialectProvider.GetQuotedValue(value, fieldDef.FieldType)); + setFields + .Append(dialectProvider.GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(dialectProvider.GetUpdateParam(dbCmd, value, fieldDef)); } - return string.Format("UPDATE {0} SET {1} {2}", - base.DialectProvider.GetQuotedTableName(ModelDef), setFields, WhereExpression); + var strFields = StringBuilderCache.ReturnAndFree(setFields); + if (strFields.Length == 0) + throw new ArgumentException($"No non-null or non-default values were provided for type: {typeof(T).Name}"); + + dbCmd.CommandText = $"UPDATE {dialectProvider.GetQuotedTableName(modelDef)} SET {strFields} {q.WhereExpression}"; } - } + } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServerOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServerOrmLiteDialectProvider.cs index 14bb16269..ae37a163c 100644 --- a/src/ServiceStack.OrmLite.SqlServer/SqlServerOrmLiteDialectProvider.cs +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServerOrmLiteDialectProvider.cs @@ -1,13 +1,21 @@ using System; using System.Collections.Generic; using System.Data; +#if MSDATA +using Microsoft.Data.SqlClient; +#else using System.Data.SqlClient; -using System.Globalization; +#endif using System.IO; -using System.Text; +using System.Linq; using System.Threading; using System.Threading.Tasks; -using ServiceStack.Data; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServer.Converters; +using ServiceStack.Text; +#if NETCORE +using ApplicationException = System.InvalidOperationException; +#endif namespace ServiceStack.OrmLite.SqlServer { @@ -15,43 +23,46 @@ public class SqlServerOrmLiteDialectProvider : OrmLiteDialectProviderBase(new SqlServerStringConverter()); + base.RegisterConverter(new SqlServerBoolConverter()); + + base.RegisterConverter(new SqlServerSByteConverter()); + base.RegisterConverter(new SqlServerUInt16Converter()); + base.RegisterConverter(new SqlServerUInt32Converter()); + base.RegisterConverter(new SqlServerUInt64Converter()); + + base.RegisterConverter(new SqlServerFloatConverter()); + base.RegisterConverter(new SqlServerDoubleConverter()); + base.RegisterConverter(new SqlServerDecimalConverter()); - DbTypeMap.Set(DbType.DateTime, TimeColumnDefinition); - DbTypeMap.Set(DbType.DateTime, TimeColumnDefinition); + base.RegisterConverter(new SqlServerDateTimeConverter()); - //throws unknown type exceptions in parameterized queries, e.g: p.DbType = DbType.SByte - DbTypeMap.Set(DbType.Byte, IntColumnDefinition); - DbTypeMap.Set(DbType.Int16, IntColumnDefinition); - DbTypeMap.Set(DbType.Int32, IntColumnDefinition); - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); + base.RegisterConverter(new SqlServerGuidConverter()); + + base.RegisterConverter(new SqlServerByteArrayConverter()); + + this.Variables = new Dictionary + { + { OrmLiteVariables.SystemUtc, "SYSUTCDATETIME()" }, + { OrmLiteVariables.MaxText, "VARCHAR(MAX)" }, + { OrmLiteVariables.MaxTextUnicode, "NVARCHAR(MAX)" }, + { OrmLiteVariables.True, SqlBool(true) }, + { OrmLiteVariables.False, SqlBool(false) }, + }; } public override string GetQuotedValue(string paramValue) { - return (UseUnicode ? "N'" : "'") + paramValue.Replace("'", "''") + "'"; + return (StringConverter.UseUnicode ? "N'" : "'") + paramValue.Replace("'", "''") + "'"; } public override IDbConnection CreateConnection(string connectionString, Dictionary options) @@ -62,16 +73,14 @@ public override IDbConnection CreateConnection(string connectionString, Dictiona { var filePath = connectionString; - var filePathWithExt = filePath.ToLower().EndsWith(".mdf") + var filePathWithExt = filePath.EndsWithIgnoreCase(".mdf") ? filePath : filePath + ".mdf"; var fileName = Path.GetFileName(filePathWithExt); var dbName = fileName.Substring(0, fileName.Length - ".mdf".Length); - connectionString = string.Format( - @"Data Source=.\SQLEXPRESS;AttachDbFilename={0};Initial Catalog={1};Integrated Security=True;User Instance=True;", - filePathWithExt, dbName); + connectionString = $@"Data Source=.\SQLEXPRESS;AttachDbFilename={filePathWithExt};Initial Catalog={dbName};Integrated Security=True;User Instance=True;"; } if (options != null) @@ -93,158 +102,103 @@ public override IDbConnection CreateConnection(string connectionString, Dictiona return new SqlConnection(connectionString); } - public override void SetDbValue(FieldDefinition fieldDef, IDataReader reader, int colIndex, object instance) + public override SqlExpression SqlExpression() => new SqlServerExpression(this); + + public override IDbDataParameter CreateParam() => new SqlParameter(); + + private const string DefaultSchema = "dbo"; + public override string ToTableNamesStatement(string schema) { - if (fieldDef.IsRowVersion) - { - var bytes = reader.GetValue(colIndex) as byte[]; - if (bytes != null) - { - var ulongValue = OrmLiteUtils.ConvertToULong(bytes); - try - { - fieldDef.SetValueFn(instance, ulongValue); - } - catch (NullReferenceException ignore) { } - } - } - else - { - base.SetDbValue(fieldDef, reader, colIndex, instance); - } + var sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"; + return sql + " AND TABLE_SCHEMA = {0}".SqlFmt(this, schema ?? DefaultSchema); } - public override object ConvertDbValue(object value, Type type) + public override string ToTableNamesWithRowCountsStatement(bool live, string schema) { - try - { - if (value == null || value is DBNull) return null; - - if (type == typeof(bool) && !(value is bool)) - { - var intVal = Convert.ToInt32(value.ToString()); - return intVal != 0; - } - - if (type == typeof(TimeSpan) && value is DateTime) - { - var dateTimeValue = (DateTime)value; - return dateTimeValue - timeSpanOffset; - } - - if (_ensureUtc && type == typeof(DateTime)) - { - var result = base.ConvertDbValue(value, type); - if (result is DateTime) - return DateTime.SpecifyKind((DateTime)result, DateTimeKind.Utc); - return result; - } - - if (type == typeof(byte[])) - return value; - - return base.ConvertDbValue(value, type); - } - catch (Exception ex) - { - throw; - } + var schemaSql = " AND s.Name = {0}".SqlFmt(this, schema ?? DefaultSchema); + + var sql = @"SELECT t.NAME, p.rows FROM sys.tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id + INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id + INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id + WHERE t.is_ms_shipped = 0 " + schemaSql + " GROUP BY t.NAME, p.Rows"; + return sql; } - public override string GetQuotedValue(object value, Type fieldType) + public override bool DoesSchemaExist(IDbCommand dbCmd, string schemaName) { - if (value == null) return "NULL"; - - if (fieldType == typeof(Guid)) - { - var guidValue = (Guid)value; - return string.Format("CAST('{0}' AS UNIQUEIDENTIFIER)", guidValue); - } - if (fieldType == typeof(DateTime)) - { - var dateValue = (DateTime)value; - if (_ensureUtc && dateValue.Kind == DateTimeKind.Local) - dateValue = dateValue.ToUniversalTime(); - const string iso8601Format = "yyyyMMdd HH:mm:ss.fff"; - return base.GetQuotedValue(dateValue.ToString(iso8601Format, CultureInfo.InvariantCulture), typeof(string)); - } - if (fieldType == typeof(DateTimeOffset)) - { - var dateValue = (DateTimeOffset)value; - const string iso8601Format = "yyyyMMdd HH:mm:ss.fff zzz"; - return base.GetQuotedValue(dateValue.ToString(iso8601Format, CultureInfo.InvariantCulture), typeof(string)); - } - if (fieldType == typeof(bool)) - { - var boolValue = (bool)value; - return base.GetQuotedValue(boolValue ? 1 : 0, typeof(int)); - } - if (fieldType == typeof(string)) - { - return GetQuotedValue(value.ToString()); - } - - if (fieldType == typeof(byte[])) - { - return "0x" + BitConverter.ToString((byte[])value).Replace("-", ""); - } - - return base.GetQuotedValue(value, fieldType); + var sql = $"SELECT count(*) FROM sys.schemas WHERE name = '{schemaName.SqlParam()}'"; + var result = dbCmd.ExecLongScalar(sql); + return result > 0; } - protected override string GetUndefinedColumnDefinition(Type fieldType, int? fieldLength) + public override async Task DoesSchemaExistAsync(IDbCommand dbCmd, string schemaName, CancellationToken token = default) { - return string.Format(StringLengthColumnDefinitionFormat, fieldLength.HasValue ? fieldLength.Value.ToString() : "MAX"); + var sql = $"SELECT count(*) FROM sys.schemas WHERE name = '{schemaName.SqlParam()}'"; + var result = await dbCmd.ExecLongScalarAsync(sql, token); + return result > 0; } - protected bool _useDateTime2; - public void UseDatetime2(bool shouldUseDatetime2) + public override string ToCreateSchemaStatement(string schemaName) { - _useDateTime2 = shouldUseDatetime2; - DateTimeColumnDefinition = shouldUseDatetime2 ? "datetime2" : "datetime"; - base.DbTypeMap.Set(shouldUseDatetime2 ? DbType.DateTime2 : DbType.DateTime, DateTimeColumnDefinition); - base.DbTypeMap.Set(shouldUseDatetime2 ? DbType.DateTime2 : DbType.DateTime, DateTimeColumnDefinition); + var sql = $"CREATE SCHEMA [{GetSchemaName(schemaName)}]"; + return sql; } - protected bool _ensureUtc; - public void EnsureUtc(bool shouldEnsureUtc) + public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) { - _ensureUtc = shouldEnsureUtc; + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = {0}" + .SqlFmt(this, tableName); + + if (schema != null) + sql += " AND TABLE_SCHEMA = {0}".SqlFmt(this, schema); + else + sql += " AND TABLE_SCHEMA <> 'Security'"; + + var result = dbCmd.ExecLongScalar(sql); + + return result > 0; } - public override SqlExpression SqlExpression() + public override async Task DoesTableExistAsync(IDbCommand dbCmd, string tableName, string schema = null, CancellationToken token = default) { - return new SqlServerExpression(this); + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = {0}" + .SqlFmt(this, tableName); + + if (schema != null) + sql += " AND TABLE_SCHEMA = {0}".SqlFmt(this, schema); + else + sql += " AND TABLE_SCHEMA <> 'Security'"; + + var result = await dbCmd.ExecLongScalarAsync(sql, token); + + return result > 0; } - public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) + public override bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null) { - var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = {0}" - .SqlFmt(tableName); + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = @columnName" + .SqlFmt(this, tableName, columnName); if (schema != null) - sql += " AND TABLE_SCHEMA = {0}".SqlFmt(schema); + sql += " AND TABLE_SCHEMA = @schema"; - dbCmd.CommandText = sql; - var result = dbCmd.LongScalar(); + var result = db.SqlScalar(sql, new { tableName, columnName, schema }); return result > 0; } - public override bool UseUnicode + public override async Task DoesColumnExistAsync(IDbConnection db, string columnName, string tableName, string schema = null, + CancellationToken token = default) { - get - { - return useUnicode; - } - set - { - useUnicode = value; - if (useUnicode && this.DefaultStringLength > 4000) - { - this.DefaultStringLength = 4000; - } - } + var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = @columnName" + .SqlFmt(this, tableName, columnName); + + if (schema != null) + sql += " AND TABLE_SCHEMA = @schema"; + + var result = await db.SqlScalarAsync(sql, new { tableName, columnName, schema }, token: token); + + return result > 0; } public override string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignKey) @@ -256,7 +210,7 @@ public override string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignK public override string GetForeignKeyOnUpdateClause(ForeignKeyConstraint foreignKey) { - return "RESTRICT" == (foreignKey.OnDelete ?? "").ToUpper() + return "RESTRICT" == (foreignKey.OnUpdate ?? "").ToUpper() ? "" : base.GetForeignKeyOnUpdateClause(foreignKey); } @@ -265,7 +219,7 @@ public override string GetDropForeignKeyConstraints(ModelDefinition modelDef) { //TODO: find out if this should go in base class? - var sb = new StringBuilder(); + var sb = StringBuilderCache.Allocate(); foreach (var fieldDef in modelDef.FieldDefinitions) { if (fieldDef.ForeignKey != null) @@ -277,120 +231,365 @@ public override string GetDropForeignKeyConstraints(ModelDefinition modelDef) fieldDef); var tableName = GetQuotedTableName(modelDef); - sb.AppendLine("IF EXISTS (SELECT name FROM sys.foreign_keys WHERE name = '{0}')".Fmt(foreignKeyName)); + sb.AppendLine($"IF EXISTS (SELECT name FROM sys.foreign_keys WHERE name = '{foreignKeyName}')"); sb.AppendLine("BEGIN"); - sb.AppendLine(" ALTER TABLE {0} DROP {1};".Fmt(tableName, foreignKeyName)); + sb.AppendLine($" ALTER TABLE {tableName} DROP {foreignKeyName};"); sb.AppendLine("END"); } } - return sb.ToString(); + return StringBuilderCache.ReturnAndFree(sb); } public override string ToAddColumnStatement(Type modelType, FieldDefinition fieldDef) { - var column = GetColumnDefinition(fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); + var column = GetColumnDefinition(fieldDef); + var modelName = GetQuotedTableName(GetModel(modelType)); - return string.Format("ALTER TABLE {0} ADD {1};", - GetQuotedTableName(GetModel(modelType).ModelName), - column); + return $"ALTER TABLE {modelName} ADD {column};"; } public override string ToAlterColumnStatement(Type modelType, FieldDefinition fieldDef) { - var column = GetColumnDefinition(fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); + var column = GetColumnDefinition(fieldDef); + var modelName = GetQuotedTableName(GetModel(modelType)); - return string.Format("ALTER TABLE {0} ALTER COLUMN {1};", - GetQuotedTableName(GetModel(modelType).ModelName), - column); + return $"ALTER TABLE {modelName} ALTER COLUMN {column};"; } public override string ToChangeColumnNameStatement(Type modelType, FieldDefinition fieldDef, string oldColumnName) { - var objectName = string.Format("{0}.{1}", - NamingStrategy.GetTableName(GetModel(modelType).ModelName), - oldColumnName); + var modelName = NamingStrategy.GetTableName(GetModel(modelType)); + var objectName = $"{modelName}.{oldColumnName}"; - return string.Format("EXEC sp_rename {0}, {1}, {2};", - GetQuotedValue(objectName), - GetQuotedValue(fieldDef.FieldName), - GetQuotedValue("COLUMN")); + return $"EXEC sp_rename {GetQuotedValue(objectName)}, {GetQuotedValue(fieldDef.FieldName)}, {GetQuotedValue("COLUMN")};"; } - public override string GetColumnDefinition(string fieldName, Type fieldType, bool isPrimaryKey, bool autoIncrement, - bool isNullable, bool isRowVersion, int? fieldLength, int? scale, string defaultValue, string customFieldDefinition) + protected virtual string GetAutoIncrementDefinition(FieldDefinition fieldDef) { - if (isRowVersion) - return "{0} rowversion NOT NULL".Fmt(fieldName); + return AutoIncrementDefinition; + } - var definition = base.GetColumnDefinition(fieldName, fieldType, isPrimaryKey, autoIncrement, - isNullable, isRowVersion, fieldLength, scale, defaultValue, customFieldDefinition); + public override string GetAutoIdDefaultValue(FieldDefinition fieldDef) + { + return fieldDef.FieldType == typeof(Guid) + ? "newid()" + : null; + } + + public override string GetColumnDefinition(FieldDefinition fieldDef) + { + // https://msdn.microsoft.com/en-us/library/ms182776.aspx + if (fieldDef.IsRowVersion) + return $"{fieldDef.FieldName} rowversion NOT NULL"; - if (fieldType == typeof(Decimal) - && (fieldLength != DefaultDecimalPrecision || scale != DefaultDecimalScale)) + var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) ?? + GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale); + + var sql = StringBuilderCache.Allocate(); + sql.Append($"{GetQuotedColumnName(fieldDef.FieldName)} {fieldDefinition}"); + + if (fieldDef.FieldType == typeof(string)) { - string validDecimal = String.Format("DECIMAL({0},{1})", - fieldLength.GetValueOrDefault(DefaultDecimalPrecision), - scale.GetValueOrDefault(DefaultDecimalScale)); - definition = definition.Replace(DecimalColumnDefinition, validDecimal); + // https://msdn.microsoft.com/en-us/library/ms184391.aspx + var collation = fieldDef.PropertyInfo?.FirstAttribute()?.Collation; + if (!string.IsNullOrEmpty(collation)) + { + sql.Append($" COLLATE {collation}"); + } } - return definition; + if (fieldDef.IsPrimaryKey) + { + sql.Append(" PRIMARY KEY"); + + if (fieldDef.IsNonClustered) + sql.Append(" NONCLUSTERED"); + + if (fieldDef.AutoIncrement) + { + sql.Append(" ").Append(GetAutoIncrementDefinition(fieldDef)); + } + } + else + { + sql.Append(fieldDef.IsNullable ? " NULL" : " NOT NULL"); + } + + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } + + var defaultValue = GetDefaultValue(fieldDef); + if (!string.IsNullOrEmpty(defaultValue)) + { + sql.AppendFormat(DefaultValueFormat, defaultValue); + } + + return StringBuilderCache.ReturnAndFree(sql); } - public override string ToSelectStatement(ModelDefinition modelDef, + public override string ToInsertRowStatement(IDbCommand cmd, object objWithProperties, ICollection insertFields = null) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var sbReturningColumns = StringBuilderCacheAlt.Allocate(); + var tableType = objWithProperties.GetType(); + var modelDef = GetModel(tableType); + + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) + { + if (ShouldReturnOnInsert(modelDef, fieldDef)) + { + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName)); + } + + if (ShouldSkipInsert(fieldDef) && !fieldDef.AutoId) + continue; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); + + AddParameter(cmd, fieldDef); + } + catch (Exception ex) + { + Log.Error("ERROR in ToInsertRowStatement(): " + ex.Message, ex); + throw; + } + } + + foreach (var fieldDef in modelDef.AutoIdFields) // need to include any AutoId fields that weren't included + { + if (fieldDefs.Contains(fieldDef)) + continue; + + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName)); + } + + var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns); + strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : ""; + var sql = sbColumnNames.Length > 0 + ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) " + + strReturning + + $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})" + : $"INSERT INTO {GetQuotedTableName(modelDef)} {strReturning} DEFAULT VALUES"; + + return sql; + } + + protected string Sequence(string schema, string sequence) + { + if (schema == null) + return GetQuotedName(sequence); + + var escapedSchema = NamingStrategy.GetSchemaName(schema) + .Replace(".", "\".\""); + + return GetQuotedName(escapedSchema) + + "." + + GetQuotedName(sequence); + } + + protected override bool ShouldSkipInsert(FieldDefinition fieldDef) => + fieldDef.ShouldSkipInsert() || fieldDef.AutoId; + + protected virtual bool ShouldReturnOnInsert(ModelDefinition modelDef, FieldDefinition fieldDef) => + fieldDef.ReturnOnInsert || (fieldDef.IsPrimaryKey && fieldDef.AutoIncrement && HasInsertReturnValues(modelDef)) || fieldDef.AutoId; + + public override bool HasInsertReturnValues(ModelDefinition modelDef) => + modelDef.FieldDefinitions.Any(x => x.ReturnOnInsert || (x.AutoId && x.FieldType == typeof(Guid))); + + protected virtual bool SupportsSequences(FieldDefinition fieldDef) => false; + + public override void EnableIdentityInsert(IDbCommand cmd) + { + var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition); + cmd.ExecNonQuery($"SET IDENTITY_INSERT {tableName} ON"); + } + + public override Task EnableIdentityInsertAsync(IDbCommand cmd, CancellationToken token=default) + { + var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition); + return cmd.ExecNonQueryAsync($"SET IDENTITY_INSERT {tableName} ON", null, token); + } + + public override void DisableIdentityInsert(IDbCommand cmd) + { + var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition); + cmd.ExecNonQuery($"SET IDENTITY_INSERT {tableName} OFF"); + } + + public override Task DisableIdentityInsertAsync(IDbCommand cmd, CancellationToken token=default) + { + var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition); + return cmd.ExecNonQueryAsync($"SET IDENTITY_INSERT {tableName} OFF", null, token); + } + + public override void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null, + Func shouldInclude=null) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var sbReturningColumns = StringBuilderCacheAlt.Allocate(); + var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T)); + + cmd.Parameters.Clear(); + + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) + { + if (ShouldReturnOnInsert(modelDef, fieldDef)) + { + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName)); + } + + if ((ShouldSkipInsert(fieldDef) && !fieldDef.AutoId) + && shouldInclude?.Invoke(fieldDef) != true) + continue; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + + if (SupportsSequences(fieldDef)) + { + sbColumnValues.Append("NEXT VALUE FOR " + Sequence(NamingStrategy.GetSchemaName(modelDef), fieldDef.Sequence)); + } + else + { + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName),fieldDef.CustomInsert)); + AddParameter(cmd, fieldDef); + } + } + catch (Exception ex) + { + Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex); + throw; + } + } + + foreach (var fieldDef in modelDef.AutoIdFields) // need to include any AutoId fields that weren't included + { + if (fieldDefs.Contains(fieldDef)) + continue; + + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName)); + } + + var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns); + strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : ""; + cmd.CommandText = sbColumnNames.Length > 0 + ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) {strReturning}" + + $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})" + : $"INSERT INTO {GetQuotedTableName(modelDef)}{strReturning} DEFAULT VALUES"; + } + + public override void PrepareInsertRowStatement(IDbCommand dbCmd, Dictionary args) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var sbReturningColumns = StringBuilderCacheAlt.Allocate(); + var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T)); + + dbCmd.Parameters.Clear(); + + foreach (var entry in args) + { + var fieldDef = modelDef.AssertFieldDefinition(entry.Key); + + if (ShouldReturnOnInsert(modelDef, fieldDef)) + { + if (sbReturningColumns.Length > 0) + sbReturningColumns.Append(","); + sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName)); + } + + if (ShouldSkipInsert(fieldDef) && !fieldDef.AutoId) + continue; + + var value = entry.Value; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + sbColumnValues.Append(this.GetInsertParam(dbCmd, value, fieldDef)); + } + catch (Exception ex) + { + Log.Error("ERROR in PrepareInsertRowStatement(): " + ex.Message, ex); + throw; + } + } + + var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns); + strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : ""; + dbCmd.CommandText = sbColumnNames.Length > 0 + ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) {strReturning}" + + $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})" + : $"INSERT INTO {GetQuotedTableName(modelDef)} {strReturning}DEFAULT VALUES"; + } + + public override string ToSelectStatement(QueryType queryType, ModelDefinition modelDef, string selectExpression, string bodyExpression, string orderByExpression = null, int? offset = null, - int? rows = null) + int? rows = null, + ISet tags=null) { - var sb = new StringBuilder(selectExpression); - sb.Append(bodyExpression); + var sb = StringBuilderCache.Allocate(); + ApplyTags(sb, tags); - if (!offset.HasValue && !rows.HasValue) - return sb + orderByExpression; + sb.Append(selectExpression) + .Append(bodyExpression); - if (offset.HasValue && offset.Value < 0) - throw new ArgumentException(string.Format("Skip value:'{0}' must be>=0", offset.Value)); + if (!offset.HasValue && !rows.HasValue || (queryType != QueryType.Select && rows != 1)) + return StringBuilderCache.ReturnAndFree(sb) + orderByExpression; - if (rows.HasValue && rows.Value < 0) - throw new ArgumentException(string.Format("Rows value:'{0}' must be>=0", rows.Value)); + if (offset is < 0) + throw new ArgumentException($"Skip value:'{offset.Value}' must be>=0"); - var skip = offset.HasValue ? offset.Value : 0; - var take = rows.HasValue ? rows.Value : int.MaxValue; + if (rows is < 0) + throw new ArgumentException($"Rows value:'{rows.Value}' must be>=0"); + + var skip = offset ?? 0; + var take = rows ?? int.MaxValue; var selectType = selectExpression.StartsWithIgnoreCase("SELECT DISTINCT") ? "SELECT DISTINCT" : "SELECT"; - //Temporary hack till we come up with a more robust paging sln for SqlServer + //avoid Windowing function if unnecessary if (skip == 0) { - var sql = sb + orderByExpression; - - if (take == int.MaxValue) - return sql; - - if (sql.Length < "SELECT".Length) return sql; - sql = selectType + " TOP " + take + sql.Substring(selectType.Length); - return sql; + var sql = StringBuilderCache.ReturnAndFree(sb) + orderByExpression; + return SqlTop(sql, take, selectType); } // Required because ordering is done by Windowing function @@ -399,29 +598,36 @@ public override string ToSelectStatement(ModelDefinition modelDef, if (modelDef.PrimaryKey == null) throw new ApplicationException("Malformed model, no PrimaryKey defined"); - orderByExpression = string.Format("ORDER BY {0}", - this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey)); + orderByExpression = $"ORDER BY {this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey)}"; } - var ret = string.Format( - "{0} FROM (SELECT ROW_NUMBER() OVER ({2}) As RowNum, {1} {3}) AS RowConstrainedResult WHERE RowNum > {4} AND RowNum <= {5}", - UseAliasesOrStripTablePrefixes(selectExpression), - selectExpression.Substring(selectType.Length), - orderByExpression, - bodyExpression, - skip, - take == int.MaxValue ? take : skip + take); + var row = take == int.MaxValue ? take : skip + take; + + var ret = $"SELECT * FROM (SELECT {selectExpression.Substring(selectType.Length)}, ROW_NUMBER() OVER ({orderByExpression}) As RowNum {bodyExpression}) AS RowConstrainedResult WHERE RowNum > {skip} AND RowNum <= {row}"; return ret; } + protected static string SqlTop(string sql, int take, string selectType = null) + { + selectType ??= sql.StartsWithIgnoreCase("SELECT DISTINCT") ? "SELECT DISTINCT" : "SELECT"; + + if (take == int.MaxValue) + return sql; + + if (sql.Length < "SELECT".Length) + return sql; + + return selectType + " TOP " + take + sql.Substring(selectType.Length); + } + //SELECT without RowNum and prefer aliases to be able to use in SELECT IN () Reference Queries public static string UseAliasesOrStripTablePrefixes(string selectExpression) { if (selectExpression.IndexOf('.') < 0) return selectExpression; - var sb = new StringBuilder(); + var sb = StringBuilderCache.Allocate(); var selectToken = selectExpression.SplitOnFirst(' '); var tokens = selectToken[1].Split(','); foreach (var token in tokens) @@ -449,14 +655,15 @@ public static string UseAliasesOrStripTablePrefixes(string selectExpression) } } - var sqlSelect = selectToken[0] + " " + sb.ToString().Trim(); + var sqlSelect = selectToken[0] + " " + StringBuilderCache.ReturnAndFree(sb).Trim(); return sqlSelect; } - public override string GetLoadChildrenSubSelect(ModelDefinition modelDef, SqlExpression expr) + public override string GetLoadChildrenSubSelect(SqlExpression expr) { if (!expr.OrderByExpression.IsNullOrEmpty() && expr.Rows == null) { + var modelDef = expr.ModelDef; expr.Select(this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey)) .ClearLimits() .OrderBy(""); //Invalid in Sub Selects @@ -465,52 +672,58 @@ public override string GetLoadChildrenSubSelect(ModelDefinition modelDef, return subSql; } - - return base.GetLoadChildrenSubSelect(modelDef, expr); - } - protected SqlConnection Unwrap(IDbConnection db) - { - return (SqlConnection)db.ToDbConnection(); + return base.GetLoadChildrenSubSelect(expr); } - protected SqlCommand Unwrap(IDbCommand cmd) - { - return (SqlCommand) cmd.ToDbCommand(); - } + public override string SqlCurrency(string fieldOrValue, string currencySymbol) => + SqlConcat(new[] { "'" + currencySymbol + "'", $"CONVERT(VARCHAR, CONVERT(MONEY, {fieldOrValue}), 1)" }); - protected SqlDataReader Unwrap(IDataReader reader) - { - return (SqlDataReader)reader; - } + public override string SqlBool(bool value) => value ? "1" : "0"; -#if NET45 - public override Task OpenAsync(IDbConnection db, CancellationToken token) - { - return Unwrap(db).OpenAsync(token); - } + public override string SqlLimit(int? offset = null, int? rows = null) => rows == null && offset == null + ? "" + : rows != null + ? "OFFSET " + offset.GetValueOrDefault() + " ROWS FETCH NEXT " + rows + " ROWS ONLY" + : "OFFSET " + offset.GetValueOrDefault(int.MaxValue) + " ROWS"; - public override Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token) - { - return Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x); - } + public override string SqlCast(object fieldOrValue, string castAs) => + castAs == Sql.VARCHAR + ? $"CAST({fieldOrValue} AS VARCHAR(MAX))" + : $"CAST({fieldOrValue} AS {castAs})"; - public override Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token) - { - return Unwrap(cmd).ExecuteNonQueryAsync(token); - } + public override string SqlRandom => "NEWID()"; - public override Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token) - { - return Unwrap(cmd).ExecuteScalarAsync(token); - } + public override void EnableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("EXEC sp_msforeachtable \"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all\""); + public override Task EnableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) => + cmd.ExecNonQueryAsync("EXEC sp_msforeachtable \"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all\"", null, token); + public override void DisableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("EXEC sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\""); + public override Task DisableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) => + cmd.ExecNonQueryAsync("EXEC sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\"", null, token); + + protected SqlConnection Unwrap(IDbConnection db) => (SqlConnection)db.ToDbConnection(); - public override Task ReadAsync(IDataReader reader, CancellationToken token) - { - return Unwrap(reader).ReadAsync(token); - } + protected SqlCommand Unwrap(IDbCommand cmd) => (SqlCommand)cmd.ToDbCommand(); + + protected SqlDataReader Unwrap(IDataReader reader) => (SqlDataReader)reader; + +#if ASYNC + public override Task OpenAsync(IDbConnection db, CancellationToken token = default) + => Unwrap(db).OpenAsync(token); + + public override Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default) + => Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x); + + public override Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default) + => Unwrap(cmd).ExecuteNonQueryAsync(token); + + public override Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default) + => Unwrap(cmd).ExecuteScalarAsync(token); + + public override Task ReadAsync(IDataReader reader, CancellationToken token = default) + => Unwrap(reader).ReadAsync(token); - public override async Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token) + public override async Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = default) { try { @@ -528,7 +741,7 @@ public override async Task> ReaderEach(IDataReader reader, Func fn } } - public override async Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token) + public override async Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = default) { try { @@ -544,7 +757,7 @@ public override async Task ReaderEach(IDataReader reader, Action } } - public override async Task ReaderRead(IDataReader reader, Func fn, CancellationToken token) + public override async Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = default) { try { diff --git a/src/ServiceStack.OrmLite.SqlServer/SqlServerTableHint.cs b/src/ServiceStack.OrmLite.SqlServer/SqlServerTableHint.cs new file mode 100644 index 000000000..abbbe5109 --- /dev/null +++ b/src/ServiceStack.OrmLite.SqlServer/SqlServerTableHint.cs @@ -0,0 +1,12 @@ +namespace ServiceStack.OrmLite.SqlServer +{ + public class SqlServerTableHint + { + public static JoinFormatDelegate ReadUncommitted = (dialect, tableDef, expr) => $"{dialect.GetQuotedTableName(tableDef)} WITH (READUNCOMMITTED) {expr}"; + public static JoinFormatDelegate ReadCommitted = (dialect, tableDef, expr) => $"{dialect.GetQuotedTableName(tableDef)} WITH (READCOMMITTED) {expr}"; + public static JoinFormatDelegate ReadPast = (dialect, tableDef, expr) => $"{dialect.GetQuotedTableName(tableDef)} WITH (READPAST) {expr}"; + public static JoinFormatDelegate Serializable = (dialect, tableDef, expr) => $"{dialect.GetQuotedTableName(tableDef)} WITH (SERIALIZABLE) {expr}"; + public static JoinFormatDelegate RepeatableRead = (dialect, tableDef, expr) => $"{dialect.GetQuotedTableName(tableDef)} WITH (REPEATABLEREAD) {expr}"; + public static JoinFormatDelegate NoLock = (dialect, tableDef, expr) => $"{dialect.GetQuotedTableName(tableDef)} WITH (NOLOCK) {expr}"; + } +} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/CustomSqlTests.cs b/src/ServiceStack.OrmLite.SqlServerTests/CustomSqlTests.cs deleted file mode 100644 index 7bcfd0925..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/CustomSqlTests.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Data; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - public class LetterFrequency - { - [AutoIncrement] - public int Id { get; set; } - - public string Letter { get; set; } - } - - [TestFixture] - public class CustomSqlTests : OrmLiteTestBase - { - private const string DropProcedureSql = @" - IF OBJECT_ID('spSearchLetters') IS NOT NULL - DROP PROCEDURE spSearchLetters"; - - private const string CreateProcedureSql = @" - CREATE PROCEDURE spSearchLetters - ( - @pLetter varchar(10), - @pTotal int OUT - ) - AS - BEGIN - SELECT @pTotal = COUNT(*) FROM LetterFrequency WHERE Letter = @pLetter - SELECT * FROM LetterFrequency WHERE Letter = @pLetter - END"; - - [Test] - public void Can_execute_stored_procedure_using_SqlList_with_out_params() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); - db.InsertAll(rows); - - db.ExecuteSql(DropProcedureSql); - db.ExecuteSql(CreateProcedureSql); - - IDbDataParameter pTotal = null; - var results = db.SqlList("spSearchLetters", - cmd => - { - cmd.CommandType = CommandType.StoredProcedure; - cmd.AddParam("pLetter", "C"); - pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); - }); - - Assert.That(results.Count, Is.EqualTo(3)); - Assert.That(pTotal.Value, Is.EqualTo("3")); - } - } - - [Test] - public void Can_execute_stored_procedure_using_SqlProc_with_out_params() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); - db.InsertAll(rows); - - db.ExecuteSql(DropProcedureSql); - db.ExecuteSql(CreateProcedureSql); - - var cmd = db.SqlProc("spSearchLetters", new { pLetter = "C" }); - - Assert.That(((OrmLiteCommand)cmd).IsDisposed, Is.False); - - var pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); - var results = cmd.ConvertToList(); - - Assert.That(results.Count, Is.EqualTo(3)); - Assert.That(pTotal.Value, Is.EqualTo("3")); - } - } - - [Test] - public void Can_execute_stored_proceduce_returning_scalars() - { - using (var db = OpenDbConnection()) - { - using (var cmd = db.SqlProc( - "GetUserIdsFromEmailAddresses", new { EmailAddresses = "as@if.com" })) - { - var userIds = cmd.ConvertToList(); - - Assert.That(userIds.Count, Is.GreaterThan(0)); - } - } - } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Datetime2Tests.cs b/src/ServiceStack.OrmLite.SqlServerTests/Datetime2Tests.cs deleted file mode 100644 index c3bbd7c42..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/Datetime2Tests.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Data.SqlClient; -using System.Data.SqlTypes; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.SqlServer; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - public class Datetime2Tests : SqlServerTests.OrmLiteTestBase - { - [Test] - public void datetime_tests__can_use_datetime2() - { - var dbFactory = new OrmLiteConnectionFactory(base.ConnectionString, SqlServerOrmLiteDialectProvider.Instance); - - //change to datetime2 - check for higher range and precision - SqlServerOrmLiteDialectProvider.Instance.UseDatetime2(true); - - using(var conn = dbFactory.OpenDbConnection()) { - var test_object_ValidForDatetime2 = Table_for_datetime2_tests.get_test_object_ValidForDatetime2(); - var test_object_ValidForNormalDatetime = Table_for_datetime2_tests.get_test_object_ValidForNormalDatetime(); - - conn.CreateTable(true); - - //normal insert - var insertedId = conn.Insert(test_object_ValidForDatetime2, selectIdentity:true); - - //read back, and verify precision - var fromDb = conn.SingleById(insertedId); - Assert.AreEqual(test_object_ValidForDatetime2.ToVerifyPrecision, fromDb.ToVerifyPrecision); - - //update - fromDb.ToVerifyPrecision = test_object_ValidForDatetime2.ToVerifyPrecision.Value.AddYears(1); - conn.Update(fromDb); - var fromDb2 = conn.SingleById(insertedId); - Assert.AreEqual(test_object_ValidForDatetime2.ToVerifyPrecision.Value.AddYears(1), fromDb2.ToVerifyPrecision); - - - //check InsertParam - conn.Insert(test_object_ValidForDatetime2); - } - } - [Test] - public void datetime_tests__check_default_behaviour() - { - var dbFactory = new OrmLiteConnectionFactory(base.ConnectionString, SqlServerOrmLiteDialectProvider.Instance); - - //default behaviour: normal datetime can't hold DateTime values of year 1. - (SqlServerOrmLiteDialectProvider.Instance as SqlServerOrmLiteDialectProvider).UseDatetime2(false); - - using(var conn = dbFactory.OpenDbConnection()) { - var test_object_ValidForDatetime2 = Table_for_datetime2_tests.get_test_object_ValidForDatetime2(); - var test_object_ValidForNormalDatetime = Table_for_datetime2_tests.get_test_object_ValidForNormalDatetime(); - - conn.CreateTable(true); - - //normal insert - var insertedId = conn.Insert(test_object_ValidForNormalDatetime, selectIdentity:true); - - //insert works, but can't regular datetime's precision is not great enough. - var fromDb = conn.SingleById(insertedId); - Assert.AreNotEqual(test_object_ValidForNormalDatetime.ToVerifyPrecision, fromDb.ToVerifyPrecision); - - var thrown = Assert.Throws(() => { - conn.Insert(test_object_ValidForDatetime2); - }); - Assert.That(thrown.Message.Contains("SqlDateTime overflow")); - - - //check InsertParam - conn.Insert(test_object_ValidForNormalDatetime); - //InsertParam fails differently: - var insertParamException = Assert.Throws(() => { - conn.Insert(test_object_ValidForDatetime2); - }); - Assert.That(insertParamException.Message.Contains("SqlDateTime overflow")); - } - } - - private class Table_for_datetime2_tests - { - [AutoIncrement] - public int Id { get; set; } - public DateTime SomeDateTime { get; set; } - public DateTime? ToVerifyPrecision { get; set; } - public DateTime? NullableDateTimeLeaveItNull { get; set; } - - /// - /// to check datetime(2)'s precision. A regular 'datetime' is not precise enough - /// - public static readonly DateTime regular_datetime_field_cant_hold_this_exact_moment = new DateTime(2013, 3, 17, 21, 29, 1, 678); - - public static Table_for_datetime2_tests get_test_object_ValidForDatetime2() { return new Table_for_datetime2_tests { SomeDateTime = new DateTime(1, 1, 1), ToVerifyPrecision = regular_datetime_field_cant_hold_this_exact_moment }; } - - public static Table_for_datetime2_tests get_test_object_ValidForNormalDatetime() { return new Table_for_datetime2_tests { SomeDateTime = new DateTime(2001, 1, 1), ToVerifyPrecision = regular_datetime_field_cant_hold_this_exact_moment }; } - - } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/EnsureUtcTest.cs b/src/ServiceStack.OrmLite.SqlServerTests/EnsureUtcTest.cs deleted file mode 100644 index 8da110f9f..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/EnsureUtcTest.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Data; -using System.Linq; -using NUnit.Framework; -using ServiceStack.OrmLite.SqlServer; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - internal class EnsureUtcTests : OrmLiteTestBase - { - [Test] - public void SaveDateTimeToDatabase() - { - var dbFactory = new OrmLiteConnectionFactory(base.ConnectionString, SqlServerOrmLiteDialectProvider.Instance); - SqlServerOrmLiteDialectProvider.Instance.EnsureUtc(true); - - using (var db = dbFactory.OpenDbConnection()) - { - var dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Local); - var x = InsertAndSelectDateTime(db, dateTime); - Assert.AreEqual(DateTimeKind.Utc, x.Test.Kind); - Assert.AreEqual(x.Test.ToUniversalTime(), dateTime.ToUniversalTime()); - Assert.AreEqual(x.Test.ToLocalTime(), dateTime.ToLocalTime()); - - dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Utc); - x = InsertAndSelectDateTime(db, dateTime); - Assert.AreEqual(DateTimeKind.Utc, x.Test.Kind); - Assert.AreEqual(x.Test.ToUniversalTime(), dateTime.ToUniversalTime()); - Assert.AreEqual(x.Test.ToLocalTime(), dateTime.ToLocalTime()); - - dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Unspecified); - x = InsertAndSelectDateTime(db, dateTime); - Assert.AreEqual(DateTimeKind.Utc, x.Test.Kind); - Assert.AreEqual(x.Test.ToUniversalTime(), dateTime); - Assert.AreEqual(x.Test.ToLocalTime(), dateTime.ToLocalTime()); - } - } - - private static DateTimeObject InsertAndSelectDateTime(IDbConnection db, DateTime dateTime) - { - db.DropAndCreateTable(); - db.Insert(new DateTimeObject { Test = dateTime }); - var x = db.Select().First(); - return x; - } - - private class DateTimeObject - { - public DateTime Test { get; set; } - } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/EnumTests.cs b/src/ServiceStack.OrmLite.SqlServerTests/EnumTests.cs deleted file mode 100644 index 9e252eb6d..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/EnumTests.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - public class EnumTests : OrmLiteTestBase - { - [Test] - public void CanCreateTable() - { - OpenDbConnection().CreateTable(true); - } - - [Test] - public void CanStoreEnumValue() - { - using(var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum {Id = 1, EnumValue = SomeEnum.Value1}); - } - } - - [Test] - public void CanGetEnumValue() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; - con.Save(obj); - var target = con.SingleById(obj.Id); - Assert.AreEqual(obj.Id, target.Id); - Assert.AreEqual(obj.EnumValue, target.EnumValue); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_expression() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Select(q => q.EnumValue == SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_string() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.SelectFmt("EnumValue = {0}", SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Test] - public void CanQueryByEnumValue_using_where_with_AnonType() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Where(new { EnumValue = SomeEnum.Value1 }); - - Assert.AreEqual(2, target.Count()); - } - } - } - - public enum SomeEnum - { - Value1, - Value2, - Value3 - } - - public class TypeWithEnum - { - public int Id { get; set; } - public SomeEnum EnumValue { get; set; } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/AuthorUseCase.cs b/src/ServiceStack.OrmLite.SqlServerTests/Expressions/AuthorUseCase.cs deleted file mode 100644 index 6ff74c2ef..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/AuthorUseCase.cs +++ /dev/null @@ -1,380 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.SqlServerTests.Expressions -{ - public class AuthorUseCase : OrmLiteTestBase - { - private List authors; - - public AuthorUseCase() - { - authors = new List(); - authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); - authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); - authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); - authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); - authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); - authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); - authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); - authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); - authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); - authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); - authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); - authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico", LastActivity = DateTime.Today }); - } - - [SetUp] - public void Setup() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.SaveAll(authors); - } - } - - [Test] - public void AuthorUsesCases() - { - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (var db = OpenDbConnection()) - { - int year = DateTime.Today.AddYears(-20).Year; - var lastDay = new DateTime(year, 12, 31); - int expected = 5; - - ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - List result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - Assert.AreEqual(expected, result.Count); - Author a = new Author() { Birthday = lastDay }; - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); - Assert.AreEqual(expected, result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected = 6; - //Sql.In can take params object[] - var city = "Berlin"; - ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); - Assert.AreEqual(expected, result.Count); - - // select authors from Bogota and Cartagena : 7 - expected = 7; - //... or Sql.In can take List - city = "Bogota"; - List cities = new List(); - cities.Add(city); - cities.Add("Cartagena"); - ev.Where().Where(rn => Sql.In(rn.City, cities)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name starts with A - expected = 3; - ev.Where().Where(rn => rn.Name.StartsWith("A")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.StartsWith("A")); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected = 3; - var name = "GARZON"; - ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected = 3; - ev.Where().Where(rn => rn.Name.EndsWith("garzon")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name contains Benedict - expected = 2; - name = "Benedict"; - ev.Where().Where(rn => rn.Name.Contains(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Assert.AreEqual(expected, result.Count); - a.Name = name; - result = db.Select(rn => rn.Name.Contains(a.Name)); - Assert.AreEqual(expected, result.Count); - - - // select authors with Earnings <= 50 - expected = 3; - var earnings = 50; - ev.Where().Where(rn => rn.Earnings <= earnings); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Earnings <= 50); - Assert.AreEqual(expected, result.Count); - - // select authors with Rate = 10 and city=Mexio - expected = 1; - city = "Mexico"; - ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Assert.AreEqual(expected, result.Count); - - a.City = city; - result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); - Assert.AreEqual(expected, result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected = 2; - var rate = 0; - ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); - Assert.AreEqual(expected, rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected = 4; - ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); - ev.Where().Where(rn => !rn.Active); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - //update comment for City == null - expected = 2; - ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); - Assert.AreEqual(expected, rows); - - // delete where City is null - expected = 2; - rows = db.Delete(ev); - Assert.AreEqual(expected, rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected = 14; - ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - var author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel", author.Name); - - // select only first 5 rows .... - expected = 5; - ev.Limit(5); // note: order is the same as in the last sentence - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - //paging : - ev.Limit(0, 4);// first page, page size=4; - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Limit(4, 4);// second page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Jorge Garzon".ToUpper(), author.Name); - - ev.Limit(8, 4);// third page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Rodger Contreras".ToUpper(), author.Name); - - // select distinct.. - ev.Limit().OrderBy(); // clear limit, clear orde - ev.SelectDistinct(r => r.City); - expected = 6; - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - // select distinct with limit - ev.Limit(0, 4); - ev.SelectDistinct(r => r.City); - expected = 4; - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); - result = db.Select(ev); - var expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - var r1 = db.Single(ev); - Assert.AreEqual(expectedResult, r1.Birthday); - - var r2 = db.Scalar(e => Sql.Max(e.Birthday)); - Assert.AreEqual(expectedResult, r2); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - var expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - r1 = db.Single(ev); - Assert.AreEqual(expectedStringResult, r1.City); - - var expectedDecimal = authors.Max(e => e.Earnings); - Decimal? r3 = db.Scalar(e => Sql.Max(e.Earnings)); - Assert.AreEqual(expectedDecimal, r3.Value); - - var expectedString = authors.Max(e => e.Name); - string r4 = db.Scalar(e => Sql.Max(e.Name)); - Assert.AreEqual(expectedString, r4); - - var expectedDate = authors.Max(e => e.LastActivity); - DateTime? r5 = db.Scalar(e => Sql.Max(e.LastActivity)); - Assert.AreEqual(expectedDate, r5); - - var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); - DateTime? r51 = db.Scalar( - e => Sql.Max(e.LastActivity), - e => e.City == "Bogota"); - Assert.AreEqual(expectedDate51, r51); - - try - { - var expectedBool = authors.Max(e => e.Active); - bool r6 = db.Scalar(e => Sql.Max(e.Active)); - Assert.AreEqual(expectedBool, r6); - } - catch (Exception e) - { - //???? - //if (dialect.Name == "PostgreSQL") - // Console.WriteLine("OK PostgreSQL: " + e.Message); - //else - // Console.WriteLine("************** FAILED *************** " + e.Message); - } - - - - // Tests for predicate overloads that make use of the expression visitor - author = db.Single(q => q.Name == "Jorge Garzon"); - - try - { - author = db.Single(q => q.Name == "Does not exist"); - Assert.Fail(); - } - catch - { - //"Expected exception thrown, OK? True" - } - - author = db.Single(q => q.Name == "Does not exist"); - Assert.IsNull(author); - - author = db.Single(q => q.City == "Bogota"); - Assert.AreEqual("Angel Colmenares", author.Name); - - a.City = "Bogota"; - author = db.Single(q => q.City == a.City); - Assert.AreEqual("Angel Colmenares", author.Name); - - // count test - - var expectedCount = authors.Count(); - long r7 = db.Scalar(e => Sql.Count(e.Id)); - Assert.AreEqual(expectedCount, r7); - - expectedCount = authors.Count(e => e.City == "Bogota"); - r7 = db.Scalar( - e => Sql.Count(e.Id), - e => e.City == "Bogota"); - Assert.AreEqual(expectedCount, r7); - - ev.Update();// all fields will be updated - // select and update - expected = 1; - var rr = db.Single(rn => rn.Name == "Luis garzon"); - rr.City = "Madrid"; - rr.Comments = "Updated"; - ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated - rows = db.UpdateOnly(rr, ev); // == dbCmd.Update(rr) but it returns void - Assert.AreEqual(expected, rows); - - expected = 0; - ev.Where().Where(r => r.City == "Ciudad Gotica"); - rows = db.UpdateOnly(rr, ev); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.City == "Madrid").Count; - author = new Author() { Active = false }; - rows = db.UpdateOnly(author, x => x.Active, x => x.City == "Madrid"); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.Active == false).Count; - rows = db.Delete(x => x.Active == false); - Assert.AreEqual(expected, rows); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/EqualityExpressionsTest.cs b/src/ServiceStack.OrmLite.SqlServerTests/Expressions/EqualityExpressionsTest.cs deleted file mode 100644 index a8dcef0fe..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/EqualityExpressionsTest.cs +++ /dev/null @@ -1,262 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.SqlServerTests.Expressions -{ - public class EqualityExpressionsTest : ExpressionsTestBase - { - #region int tests - - [Test] - public void Can_select_equals_constant_int_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_variable_int_expression() - { -// ReSharper disable ConvertToConstant.Local - var columnValue = 3; -// ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = columnValue, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == columnValue); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_not_equals_constant_int_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn != 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - - [Test] - public void Can_select_not_equals_variable_int_expression() - { - // ReSharper disable ConvertToConstant.Local - var columnValue = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = columnValue, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn != columnValue); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - - [Test] - public void Can_select_not_equals_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn != GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - - #endregion - - #region bool test - - [Test] - public void Can_select_equals_constant_bool_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - -// ReSharper disable RedundantBoolCompare - var actual = OpenDbConnection().Select(q => q.BoolColumn == true); -// ReSharper restore RedundantBoolCompare - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_constant_bool_expression2() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - // ReSharper disable RedundantBoolCompare - var actual = OpenDbConnection().Select(q => q.BoolColumn); - // ReSharper restore RedundantBoolCompare - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_variable_bool_expression() - { - // ReSharper disable ConvertToConstant.Local - var columnValue = true; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == columnValue); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_bool_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == GetValue(true)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_null_espression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test", - NullableCol = new TestType { StringColumn = "sometext" } - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.NullableCol == null); - - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 10); - CollectionAssert.DoesNotContain(actual, expected); - } - - [Test] - public void Can_select_not_equals_null_espression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test", - NullableCol = new TestType { StringColumn = "sometext" } - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.NullableCol != null); - - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - // Assume not equal works ;-) - #endregion - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/ExpressionsTestBase.cs b/src/ServiceStack.OrmLite.SqlServerTests/Expressions/ExpressionsTestBase.cs deleted file mode 100644 index 4332dcea4..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/ExpressionsTestBase.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Data; -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.SqlServerTests.Expressions -{ - public class ExpressionsTestBase : OrmLiteTestBase - { - [SetUp] - public void Setup() - { - OpenDbConnection().CreateTable(true); - } - - //Avoid painful refactor to change all tests to use a using pattern - private IDbConnection db; - - public override IDbConnection OpenDbConnection(string connString = null) - { - if (db != null && db.State != ConnectionState.Open) - db = null; - - return db ?? (db = base.OpenDbConnection(connString)); - } - - [TearDown] - public void TearDown() - { - if (db == null) - return; - db.Dispose(); - db = null; - } - - public T GetValue(T item) - { - return item; - } - - protected void EstablishContext(int numberOfRandomObjects) - { - EstablishContext(numberOfRandomObjects, null); - } - - protected void EstablishContext(int numberOfRandomObjects, params TestType[] obj) - { - if (obj == null) - obj = new TestType[0]; - - using (var con = OpenDbConnection()) - { - foreach (var t in obj) - { - con.Insert(t); - } - - var random = new Random((int)(DateTime.UtcNow.Ticks ^ (DateTime.UtcNow.Ticks >> 4))); - for (var i = 0; i < numberOfRandomObjects; i++) - { - TestType o = null; - - while (o == null) - { - int intVal = random.Next(); - - o = new TestType - { - BoolColumn = random.Next()%2 == 0, - IntColumn = intVal, - StringColumn = Guid.NewGuid().ToString() - }; - - if (obj.Any(x => x.IntColumn == intVal)) - o = null; - } - - con.Insert(o); - } - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerTests/ForeignKeyAttributeTests.cs b/src/ServiceStack.OrmLite.SqlServerTests/ForeignKeyAttributeTests.cs deleted file mode 100644 index f5e3f78f9..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/ForeignKeyAttributeTests.cs +++ /dev/null @@ -1,180 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - [TestFixture] - public class ForeignKeyAttributeTests : OrmLiteTestBase - { - [TestFixtureSetUp] - public void Setup() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateSimpleForeignKey() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascade() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CascadesOnDelete() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - - dbConn.Save(new ReferencedType { Id = 1 }); - dbConn.Save(new TypeWithOnDeleteCascade { RefId = 1 }); - - Assert.AreEqual(1, dbConn.Select().Count); - Assert.AreEqual(1, dbConn.Select().Count); - - dbConn.Delete(r => r.Id == 1); - - Assert.AreEqual(0, dbConn.Select().Count); - Assert.AreEqual(0, dbConn.Select().Count); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteNoAction() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [NUnit.Framework.Ignore("Not supported in SQL Server")] - [Test] - public void CanCreateForeignWithOnDeleteRestrict() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteSetDefault() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteSetNull() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - } - - public class ReferencedType - { - public int Id { get; set; } - } - - - public class TypeWithSimpleForeignKey - { - [AutoIncrement] - public int Id { get; set; } - [References(typeof(ReferencedType))] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteAndUpdateCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteNoAction - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteRestrict - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteSetDefault - { - [AutoIncrement] - public int Id { get; set; } - - [Default(typeof(int), "17")] - [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT")] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteSetNull - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL")] - public int? RefId { get; set; } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerTests/InsertParam_GetLastInsertId.cs b/src/ServiceStack.OrmLite.SqlServerTests/InsertParam_GetLastInsertId.cs deleted file mode 100644 index 1daaa86f9..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/InsertParam_GetLastInsertId.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - public class InsertParam_GetLastInsertId : OrmLiteTestBase - { - [Test] - public void Can_GetLastInsertedId_using_InsertParam() - { - var testObject = new SimpleType { Name = "test" }; - - //verify that "normal" Insert works as expected - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - - con.Save(testObject); - Assert.That(testObject.Id, Is.GreaterThan(0), "normal Insert"); - } - - //test with InsertParam - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - - var lastInsertId = con.Insert(testObject, selectIdentity:true); - Assert.That(lastInsertId, Is.GreaterThan(0), "with InsertParam"); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/OrmLiteTestBase.cs b/src/ServiceStack.OrmLite.SqlServerTests/OrmLiteTestBase.cs deleted file mode 100644 index 8705d11ef..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/OrmLiteTestBase.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Configuration; -using System.Data; -using NUnit.Framework; -using ServiceStack.Logging; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - public class OrmLiteTestBase - { - protected virtual string ConnectionString { get; set; } - - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - LogManager.LogFactory = new ConsoleLogFactory(); - - OrmLiteConfig.DialectProvider = SqlServerDialect.Provider; - ConnectionString = ConfigurationManager.ConnectionStrings["testDb"].ConnectionString; - } - - public void Log(string text) - { - Console.WriteLine(text); - } - - public virtual IDbConnection OpenDbConnection(string connString = null) - { - connString = connString ?? ConnectionString; - return connString.OpenDbConnection(); - } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.SqlServerTests/Properties/AssemblyInfo.cs deleted file mode 100644 index 9beb7c987..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.SqlServerTests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.SqlServerTests")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b31d406b-57e0-4fe8-bd91-f601e47d641d")] - diff --git a/src/ServiceStack.OrmLite.SqlServerTests/ServiceStack.OrmLite.SqlServerTests.csproj b/src/ServiceStack.OrmLite.SqlServerTests/ServiceStack.OrmLite.SqlServerTests.csproj deleted file mode 100644 index d7909fde3..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/ServiceStack.OrmLite.SqlServerTests.csproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {96793C11-2A99-4217-8946-3E0DB9534A4D} - Library - Properties - ServiceStack.OrmLite.SqlServerTests - ServiceStack.OrmLite.SqlServerTests - 512 - v4.5 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\ServiceStack.Client.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {1887DC99-9139-43E3-A7AA-6D74714B3A5D} - ServiceStack.OrmLite.SqlServer - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - Designer - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerTests/SqlServerExpressionVisitorQueryTest.cs b/src/ServiceStack.OrmLite.SqlServerTests/SqlServerExpressionVisitorQueryTest.cs deleted file mode 100644 index 5aac4876c..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/SqlServerExpressionVisitorQueryTest.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.OrmLite.SqlServerTests.UseCase; -using System.Data; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - [TestFixture] - public class SqlServerExpressionVisitorQueryTest : OrmLiteTestBase - { - [Test] - public void Skip_Take_works_with_injected_Visitor() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var result = db.Select(q => q.Limit(10, 100)); - - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.Less(10, result[0].Id); - Assert.Greater(111, result[99].Id); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.Less(10, result[0].Id); - Assert.Greater(111, result[99].Id); - } - } - - [Test] - public void test_if_limit_works_with_rows() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(100); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.Less(0, result[0].Id); - Assert.Greater(101, result[99].Id); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip_and_orderby() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - ev.OrderBy(e => e.Baz); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.LessOrEqual(result[10].Baz, result[11].Baz); - } - } - - [Test] - public void test_if_ev_still_works_without_limit_and_orderby() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.OrderBy(e => e.Baz); - ev.Where(e => e.Baz < 0.1m); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.IsTrue(result.Count > 0); - } - } - - [Test] - public void test_if_and_works_with_nullable_parameter() - { - using(var db = OpenDbConnection()) - { - db.CreateTable(true); - var id = db.Insert(new TestEntity - { - Foo = this.RandomString(16), - Bar = this.RandomString(16), - Baz = this.RandomDecimal() - }, selectIdentity: true); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Where(e => e.Id == id); - int? i = null; - ev.And(e => e.NullInt == i); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.IsTrue(result.Count > 0); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip_if_pk_columnname_has_space() - { - using (var db = OpenDbConnection()) - { - FillAliasedTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip_and_orderby_if_pk_columnname_has_space() - { - using (var db = OpenDbConnection()) - { - FillAliasedTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - ev.OrderBy(e => e.Baz); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.LessOrEqual(result[10].Baz, result[11].Baz); - } - } - - protected void FillTestEntityTableWithTestData(IDbConnection db) - { - db.CreateTable(true); - - for (int i = 1; i < 1000; i++) - { - db.Insert(new TestEntity() - { - Foo = RandomString(16), - Bar = RandomString(16), - Baz = RandomDecimal(i) - }); - } - } - - protected void FillAliasedTestEntityTableWithTestData(IDbConnection db) - { - db.CreateTable(true); - - for (int i = 1; i < 1000; i++) - { - db.Insert(new TestEntityWithAliases() - { - Foo = RandomString(16), - Bar = RandomString(16), - Baz = RandomDecimal(i) - }); - } - } - - protected string RandomString(int length) - { - var rnd = new System.Random(); - var buffer = new StringBuilder(); - - for (var i = 0; i < length; i++) - { - buffer.Append(Convert.ToChar(((byte)rnd.Next(254))) - .ToString(CultureInfo.InvariantCulture)); - } - - return buffer.ToString(); - } - - protected decimal RandomDecimal(int seed = 0) - { - var rnd = new Random(seed); - return new decimal(rnd.NextDouble()); - } - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/UnicodeTests.cs b/src/ServiceStack.OrmLite.SqlServerTests/UnicodeTests.cs deleted file mode 100644 index f9bcc4915..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/UnicodeTests.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - /// - /// test for issue #69 - /// - class UnicodeTests : OrmLiteTestBase - { - [Test] - public void can_insert_and_retrieve_unicode_values() - { - //save and restore state, so it doesn't mess with other tests - bool prevUnicodestate = OrmLiteConfig.DialectProvider.UseUnicode; - try { - OrmLiteConfig.DialectProvider.UseUnicode = true; - - var testData = new[]{ - "árvíztűrő tükörfúrógép", - "ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP", //these are the Hungarian "special" characters, they work fine out of the box. At least on Hungarian_Technical_CI_AS - "♪♪♫", //this one comes back as 'ddd' - //greek alphabet - @" -Letter Name Sound value -Ancient[5] Modern[6] -Α α alpha [a] [aː] [a] -Β β beta [b] [v] -Γ γ gamma [ɡ] [ɣ] ~ [ʝ] -Δ δ delta [d] [ð] -Ε ε epsilon [e] [e] -Ζ ζ zeta [zd] (or [dz][7]) [z] -Η η eta [ɛː] [i] -Θ θ theta [tʰ] [θ] -Ι ι iota [i] [iː] [i] -Κ κ kappa [k] [k] ~ [c] -Λ λ lambda [l] [l] -Μ μ mu [m] [m] -Letter Name Sound value -Ancient Modern -Ν ν nu [n] [n] -Ξ ξ xi [ks] [ks] -Ο ο omicron [o] [o] -Π π pi [p] [p] -Ρ ρ rho [r] [r] -Σ σς sigma [s] [s] -Τ τ tau [t] [t] -Υ υ upsilon [y] [yː] [i] -Φ φ phi [pʰ] [f] -Χ χ chi [kʰ] [x] ~ [ç] -Ψ ψ psi [ps] [ps] -Ω ω omega [ɔː] [o] -" - }; - - using(var con = OpenDbConnection()) { - con.ExecuteSql(table_re_creation_script); - - foreach(var item in testData) { con.Insert(new Unicode_poco { Text = item }); } - - var fromDb = con.Select().Select(x => x.Text).ToArray(); - - CollectionAssert.AreEquivalent(testData, fromDb); - } - } - finally { OrmLiteConfig.DialectProvider.UseUnicode = prevUnicodestate; } - } - - - /* * ---if you run this in SSMS, it produces 'ddd' -INSERT INTO [Unicode_poco] ([Text]) VALUES ('hai ♪♪♫') - ---if you run this in SSMS, it works fine -INSERT INTO [Unicode_poco] ([Text]) VALUES (N'hai ♪♪♫') - -select * from Unicode_poco - * */ - - - private class Unicode_poco - { - [PrimaryKey, AutoIncrement] - public int Id { get; set; } - - public string Text { get; set; } - } - - /// - /// because OrmLite does not create nvarchar columns - /// - private string table_re_creation_script = @" -IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Unicode_poco]') AND type in (N'U')) -DROP TABLE [dbo].[Unicode_poco]; - - -CREATE TABLE [dbo].[Unicode_poco]( - [Id] [int] IDENTITY(1,1) NOT NULL, - [Text] [nvarchar](4000) NULL, - CONSTRAINT [PK_Unicode_poco] PRIMARY KEY CLUSTERED -( - [Id] ASC -)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY]"; - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/UpdateTests.cs b/src/ServiceStack.OrmLite.SqlServerTests/UpdateTests.cs deleted file mode 100644 index 677f5772e..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/UpdateTests.cs +++ /dev/null @@ -1,161 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.SqlServerTests -{ - public class UpdateTests : OrmLiteTestBase - { - [Test] - public void Can_execute_update_using_expression() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(obj.Id); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj, q => q.Id == storedObj.Id); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_update_only() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(obj.Id); - - Assert.AreEqual(obj.Name, storedObj.Name); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Update(); - ev.Where(q => q.Id == storedObj.Id); - storedObj.Name = "Someothername"; - - con.UpdateOnly(storedObj, ev); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual("Someothername", target.Name); - } - } - - - [Test] - public void Can_execute_update() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(obj.Id); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_update_using_aliased_columns() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleAliasedType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(obj.Id); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_updateParam() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(obj.Id); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_updateParam_using_aliased_columns() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleAliasedType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(obj.Id); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - } - - - public class SimpleType - { - [AutoIncrement] - public int Id { get; set; } - public string Name { get; set; } - } - - public class SimpleAliasedType - { - [AutoIncrement] - public int Id { get; set; } - [Alias("NewName")] - public string Name { get; set; } - - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/UseCase/SimpleUseCase.cs b/src/ServiceStack.OrmLite.SqlServerTests/UseCase/SimpleUseCase.cs deleted file mode 100644 index 59576fccc..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/UseCase/SimpleUseCase.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using NUnit.Framework; -using ServiceStack.OrmLite.SqlServer; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.SqlServerTests.UseCase -{ - [TestFixture, NUnit.Framework.Ignore] - public class SimpleUseCase - { - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - //Inject your database provider here - OrmLiteConfig.DialectProvider = new SqlServerOrmLiteDialectProvider(); - } - - public class User - { - public long Id { get; set; } - - [Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - - public bool IsAdmin { get; set; } - } - - public class Dual - { - [AutoIncrement] - public int Id { get; set; } - - public string Name { get; set; } - } - - [Test] - public void Simple_CRUD_example() - { - //using (IDbConnection db = ":memory:".OpenDbConnection()) - - var connStr = ConfigurationManager.ConnectionStrings["TestDb"].ConnectionString; - var sqlServerFactory = new OrmLiteConnectionFactory(connStr, SqlServerOrmLiteDialectProvider.Instance); - - using (IDbConnection db = sqlServerFactory.OpenDbConnection()) - { - db.CreateTable(true); - db.CreateTable(true); - - db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now }); - db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); - db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now, IsAdmin = true}); - - db.Insert(new Dual { Name = "Dual" }); - var lastInsertId = db.LastInsertId(); - Assert.That(lastInsertId, Is.GreaterThan(0)); - - var rowsB = db.SelectFmt("Name = {0}", "B"); - - Assert.That(rowsB, Has.Count.EqualTo(2)); - - var admin = db.SelectFmt("IsAdmin = {0}", true); - Assert.That(admin[0].Id, Is.EqualTo(3)); - - var rowIds = rowsB.ConvertAll(x => x.Id); - Assert.That(rowIds, Is.EquivalentTo(new List { 2, 3 })); - - rowsB.ForEach(x => db.Delete(x)); - - rowsB = db.SelectFmt("Name = {0}", "B"); - Assert.That(rowsB, Has.Count.EqualTo(0)); - - var rowsLeft = db.Select(); - Assert.That(rowsLeft, Has.Count.EqualTo(1)); - - Assert.That(rowsLeft[0].Name, Is.EqualTo("A")); - } - } - - } - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerTests/UseCase/TestEntityWithAliases.cs b/src/ServiceStack.OrmLite.SqlServerTests/UseCase/TestEntityWithAliases.cs deleted file mode 100644 index ccae518b3..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/UseCase/TestEntityWithAliases.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.SqlServerTests.UseCase -{ - public class TestEntityWithAliases - { - #region Properties - - [AutoIncrement] - [Alias("Id Column")] - public int Id { get; set; } - - [Alias("Foo Column")] - public String Foo { get; set; } - - [Alias("Bar Column")] - public String Bar { get; set; } - - //[Index] - [Alias("Baz Column")] - public Decimal Baz { get; set; } - - #endregion - } -} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/app.config b/src/ServiceStack.OrmLite.SqlServerTests/app.config deleted file mode 100644 index 0fee621f4..000000000 --- a/src/ServiceStack.OrmLite.SqlServerTests/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/ServiceStack.OrmLite.SqlServerV45/ServiceStack.OrmLite.SqlServerV45.Signed.csproj b/src/ServiceStack.OrmLite.SqlServerV45/ServiceStack.OrmLite.SqlServerV45.Signed.csproj deleted file mode 100644 index db295869a..000000000 --- a/src/ServiceStack.OrmLite.SqlServerV45/ServiceStack.OrmLite.SqlServerV45.Signed.csproj +++ /dev/null @@ -1,96 +0,0 @@ - - - - - Debug - AnyCPU - {6F851563-08F6-4692-89F8-F1D6C86F0069} - Library - Properties - ServiceStack.OrmLite.SqlServer - ServiceStack.OrmLite.SqlServer - v4.5 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET45 - prompt - 4 - - - bin\Signed\ - TRACE;NET45 - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - true - - - servicestack-sn.pfx - - - - ..\..\lib\signed\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\signed\ServiceStack.Text.dll - - - - - - - - - - - - AssemblyInfo.cs - - - SqlServerDialect.cs - - - SqlServerExpression.cs - - - SqlServerOrmLiteDialectProvider.cs - - - - - - - - {fdc37335-9ecc-413b-bec5-16b466b0e689} - ServiceStack.OrmLiteV45 - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerV45/ServiceStack.OrmLite.SqlServerV45.csproj b/src/ServiceStack.OrmLite.SqlServerV45/ServiceStack.OrmLite.SqlServerV45.csproj deleted file mode 100644 index c289a9ef3..000000000 --- a/src/ServiceStack.OrmLite.SqlServerV45/ServiceStack.OrmLite.SqlServerV45.csproj +++ /dev/null @@ -1,90 +0,0 @@ - - - - - Debug - AnyCPU - {6F851563-08F6-4692-89F8-F1D6C86F0069} - Library - Properties - ServiceStack.OrmLite.SqlServer - ServiceStack.OrmLite.SqlServer - v4.5 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET45 - prompt - 4 - - - bin\Signed\ - TRACE;NET45 - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - AssemblyInfo.cs - - - SqlServerDialect.cs - - - SqlServerExpression.cs - - - SqlServerOrmLiteDialectProvider.cs - - - - - - - - {fdc37335-9ecc-413b-bec5-16b466b0e689} - ServiceStack.OrmLiteV45 - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite.Cil/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Sqlite.Cil/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..22ae012d6 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite.Cil/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.Sqlite.Cil/ServiceStack.OrmLite.Sqlite.Cil.csproj b/src/ServiceStack.OrmLite.Sqlite.Cil/ServiceStack.OrmLite.Sqlite.Cil.csproj new file mode 100644 index 000000000..554acfa92 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite.Cil/ServiceStack.OrmLite.Sqlite.Cil.csproj @@ -0,0 +1,56 @@ + + + + net6.0 + ServiceStack.OrmLite.Sqlite + ServiceStack.OrmLite.Sqlite.Cil + OrmLite.Sqlite with SQLitePCLRaw CIL + + Light, simple and fast convention-based code-first POCO ORM for SQLite. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLite. + + SQLite;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + + + + Converters\SqliteBoolConverter.cs + + + Converters\SqliteByteArrayConverter.cs + + + Converters\SqliteCharConverter.cs + + + Converters\SqliteDateTimeConverter.cs + + + Converters\SqliteDateTimeOffsetConverter.cs + + + Converters\SqliteGuidConverter.cs + + + Converters\SqliteStringConverters.cs + + + SqliteDialect.cs + + + SqliteExpression.cs + + + SqliteOrmLiteDialectProviderBase.cs + + + + diff --git a/src/ServiceStack.OrmLite.Sqlite.Cil/SqliteOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Sqlite.Cil/SqliteOrmLiteDialectProvider.cs new file mode 100644 index 000000000..8f7234456 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite.Cil/SqliteOrmLiteDialectProvider.cs @@ -0,0 +1,33 @@ +using System; +using System.Data; +using Microsoft.Data.Sqlite; +using ServiceStack.OrmLite.Sqlite.Converters; + +namespace ServiceStack.OrmLite.Sqlite +{ + public class SqliteOrmLiteDialectProvider : SqliteOrmLiteDialectProviderBase + { + public static SqliteOrmLiteDialectProvider Instance = new(); + + public SqliteOrmLiteDialectProvider() + { + base.RegisterConverter(new SqliteDataDateTimeConverter()); + base.RegisterConverter(new SqliteDataGuidConverter()); + } + + protected override IDbConnection CreateConnection(string connectionString) + { + // Microsoft.Data.Sqlite no like + connectionString = connectionString + .Replace(";Version=3", "") + .Replace(";New=True", "") + .Replace(";Compress=True", ""); + return new SqliteConnection(connectionString); + } + + public override IDbDataParameter CreateParam() + { + return new SqliteParameter(); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite.Data/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Sqlite.Data/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..22ae012d6 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite.Data/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.Sqlite.Data/ServiceStack.OrmLite.Sqlite.Data.Source.csproj b/src/ServiceStack.OrmLite.Sqlite.Data/ServiceStack.OrmLite.Sqlite.Data.Source.csproj new file mode 100644 index 000000000..6201b98e8 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite.Data/ServiceStack.OrmLite.Sqlite.Data.Source.csproj @@ -0,0 +1,56 @@ + + + + netstandard2.0;net6.0 + ServiceStack.OrmLite.Sqlite + ServiceStack.OrmLite.Sqlite.Data + ServiceStack.OrmLite.Sqlite + OrmLite.Sqlite with Microsoft.Data.SQLite + + Uses Microsoft.Data.SQLite. + .NET Standard 2.0 version of ServiceStack.OrmLite.Sqlite that uses Microsoft.Data.SQLite + + SQLite;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + + + Converters\SqliteBoolConverter.cs + + + Converters\SqliteByteArrayConverter.cs + + + Converters\SqliteCharConverter.cs + + + Converters\SqliteDateTimeConverter.cs + + + Converters\SqliteDateTimeOffsetConverter.cs + + + Converters\SqliteGuidConverter.cs + + + Converters\SqliteStringConverters.cs + + + SqliteDialect.cs + + + SqliteExpression.cs + + + SqliteOrmLiteDialectProviderBase.cs + + + + diff --git a/src/ServiceStack.OrmLite.Sqlite.Data/ServiceStack.OrmLite.Sqlite.Data.csproj b/src/ServiceStack.OrmLite.Sqlite.Data/ServiceStack.OrmLite.Sqlite.Data.csproj new file mode 100644 index 000000000..987e1c429 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite.Data/ServiceStack.OrmLite.Sqlite.Data.csproj @@ -0,0 +1,56 @@ + + + + netstandard2.0;net6.0 + ServiceStack.OrmLite.Sqlite + ServiceStack.OrmLite.Sqlite.Data + ServiceStack.OrmLite.Sqlite + OrmLite.Sqlite with Microsoft.Data.SQLite + + Uses Microsoft.Data.SQLite. + .NET Standard 2.0 version of ServiceStack.OrmLite.Sqlite that uses Microsoft.Data.SQLite + + SQLite;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + + + Converters\SqliteBoolConverter.cs + + + Converters\SqliteByteArrayConverter.cs + + + Converters\SqliteCharConverter.cs + + + Converters\SqliteDateTimeConverter.cs + + + Converters\SqliteDateTimeOffsetConverter.cs + + + Converters\SqliteGuidConverter.cs + + + Converters\SqliteStringConverters.cs + + + SqliteDialect.cs + + + SqliteExpression.cs + + + SqliteOrmLiteDialectProviderBase.cs + + + + diff --git a/src/ServiceStack.OrmLite.Sqlite.Data/SqliteOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Sqlite.Data/SqliteOrmLiteDialectProvider.cs new file mode 100644 index 000000000..17a5545f9 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite.Data/SqliteOrmLiteDialectProvider.cs @@ -0,0 +1,28 @@ +using System; +using System.Data; +using Microsoft.Data.Sqlite; +using ServiceStack.OrmLite.Sqlite.Converters; + +namespace ServiceStack.OrmLite.Sqlite +{ + public class SqliteOrmLiteDialectProvider : SqliteOrmLiteDialectProviderBase + { + public static SqliteOrmLiteDialectProvider Instance = new(); + + public SqliteOrmLiteDialectProvider() + { + base.RegisterConverter(new SqliteDataDateTimeConverter()); + base.RegisterConverter(new SqliteDataGuidConverter()); + } + + protected override IDbConnection CreateConnection(string connectionString) + { + return new SqliteConnection(connectionString); + } + + public override IDbDataParameter CreateParam() + { + return new SqliteParameter(); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite.Windows/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Sqlite.Windows/Properties/AssemblyInfo.cs index e69ead6d8..22ae012d6 100644 --- a/src/ServiceStack.OrmLite.Sqlite.Windows/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite.Sqlite.Windows/Properties/AssemblyInfo.cs @@ -1,36 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.SqliteNet")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.SqliteNet")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("3689058a-4b26-4130-a135-bdc6eff071d5")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.Sqlite.Windows/ServiceStack.OrmLite.Sqlite.Windows.Signed.csproj b/src/ServiceStack.OrmLite.Sqlite.Windows/ServiceStack.OrmLite.Sqlite.Windows.Signed.csproj deleted file mode 100644 index 56d453193..000000000 --- a/src/ServiceStack.OrmLite.Sqlite.Windows/ServiceStack.OrmLite.Sqlite.Windows.Signed.csproj +++ /dev/null @@ -1,106 +0,0 @@ - - - - - Debug - AnyCPU - {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE} - Library - Properties - ServiceStack.OrmLite.Sqlite.Windows - ServiceStack.OrmLite.Sqlite.Windows - v4.0 - 512 - ..\ - true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\signed\ServiceStack.Text.dll - - - - - False - ..\packages\System.Data.SQLite.Core.1.0.94.0\lib\net40\System.Data.SQLite.dll - - - - - - - - - - SqliteExpression.cs - - - SqliteOrmLiteDialectProviderBase.cs - - - - - - - - {96179ac6-f6f1-40c3-9fdd-4f6582f54c5c} - ServiceStack.OrmLite - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - true - - - servicestack-sn.pfx - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite.Windows/ServiceStack.OrmLite.Sqlite.Windows.csproj b/src/ServiceStack.OrmLite.Sqlite.Windows/ServiceStack.OrmLite.Sqlite.Windows.csproj index c7f2fbecb..59acdec80 100644 --- a/src/ServiceStack.OrmLite.Sqlite.Windows/ServiceStack.OrmLite.Sqlite.Windows.csproj +++ b/src/ServiceStack.OrmLite.Sqlite.Windows/ServiceStack.OrmLite.Sqlite.Windows.csproj @@ -1,100 +1,52 @@ - - - + - Debug - AnyCPU - {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE} - Library - Properties - ServiceStack.OrmLite.Sqlite.Windows + net472 ServiceStack.OrmLite.Sqlite.Windows - v4.0 - 512 - ..\ - true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false + ServiceStack.OrmLite.Sqlite.Windows + OrmLite.Sqlite - Fast, code-first, config-free POCO ORM + + For cross-platform Sqlite use ServiceStack.OrmLite.Sqlite instead. + Light, simple and fast convention-based code-first POCO ORM for SQLite. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLite. + + SQLite;Windows;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - False - ..\packages\System.Data.SQLite.Core.1.0.94.0\lib\net40\System.Data.SQLite.dll - - - - - - + + + + + + Converters\SqliteBoolConverter.cs + + + Converters\SqliteByteArrayConverter.cs + + + Converters\SqliteCharConverter.cs + + + Converters\SqliteDateTimeConverter.cs + + + Converters\SqliteDateTimeOffsetConverter.cs + + + Converters\SqliteGuidConverter.cs + + + Converters\SqliteStringConverters.cs + SqliteExpression.cs SqliteOrmLiteDialectProviderBase.cs - - - - - - - {96179ac6-f6f1-40c3-9fdd-4f6582f54c5c} - ServiceStack.OrmLite - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - + \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteDialect.cs b/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteDialect.cs index e8daea4b1..028c6bf1b 100644 --- a/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteDialect.cs +++ b/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteDialect.cs @@ -4,6 +4,7 @@ namespace ServiceStack.OrmLite { public static class SqliteDialect { - public static IOrmLiteDialectProvider Provider { get { return SqliteOrmLiteDialectProvider.Instance; } } + public static IOrmLiteDialectProvider Provider => SqliteOrmLiteDialectProvider.Instance; + public static SqliteOrmLiteDialectProvider Instance => SqliteOrmLiteDialectProvider.Instance; } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteOrmLiteDialectProvider.cs index 354c7d788..8a0ee73de 100644 --- a/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteOrmLiteDialectProvider.cs +++ b/src/ServiceStack.OrmLite.Sqlite.Windows/SqliteOrmLiteDialectProvider.cs @@ -1,16 +1,31 @@ +using System; using System.Data; using System.Data.SQLite; +using ServiceStack.OrmLite.Sqlite.Converters; namespace ServiceStack.OrmLite.Sqlite { + //Alias + public class SqliteWindowsOrmLiteDialectProvider : SqliteOrmLiteDialectProvider {} + public class SqliteOrmLiteDialectProvider : SqliteOrmLiteDialectProviderBase { - // what's the purpose of this Instance field? (It's like a pseudo-wanna-be singleton?) public static SqliteOrmLiteDialectProvider Instance = new SqliteOrmLiteDialectProvider(); + public SqliteOrmLiteDialectProvider() : base() + { + OrmLiteConfig.DeoptimizeReader = true; + base.RegisterConverter(new SqliteWindowsDateTimeConverter()); + } + protected override IDbConnection CreateConnection(string connectionString) { return new SQLiteConnection(connectionString, parseViaFramework: ParseViaFramework); } + + public override IDbDataParameter CreateParam() + { + return new SQLiteParameter(); + } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite.Windows/packages.config b/src/ServiceStack.OrmLite.Sqlite.Windows/packages.config deleted file mode 100644 index 338e3b759..000000000 --- a/src/ServiceStack.OrmLite.Sqlite.Windows/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteBoolConverter.cs b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteBoolConverter.cs new file mode 100644 index 000000000..6c8b9bd36 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteBoolConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Sqlite.Converters +{ + public class SqliteBoolConverter : OrmLiteConverter + { + public override string ColumnDefinition => "INTEGER"; + + public override DbType DbType => DbType.Int32; + + public override string ToQuotedString(Type fieldType, object value) + { + var boolValue = (bool)value; + return base.DialectProvider.GetQuotedValue(boolValue ? 1 : 0, typeof(int)); + } + + public override object ToDbValue(Type fieldType, object value) + { + return (bool)value ? 1 : 0; + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is bool b) + return b; + + var intVal = int.Parse(value.ToString()); + return intVal != 0; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteByteArrayConverter.cs b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteByteArrayConverter.cs new file mode 100644 index 000000000..90678a1ff --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteByteArrayConverter.cs @@ -0,0 +1,13 @@ +using System; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Sqlite.Converters +{ + public class SqliteByteArrayConverter : ByteArrayConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + return "x'" + BitConverter.ToString((byte[])value).Replace("-", "") + "'"; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteCharConverter.cs b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteCharConverter.cs new file mode 100644 index 000000000..99369ab8d --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteCharConverter.cs @@ -0,0 +1,24 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Sqlite.Converters +{ + public class SqliteCharConverter : OrmLiteConverter + { + public override string ColumnDefinition + { + get { return "CHAR(1)"; } + } + + public override object ToDbValue(Type fieldType, object value) + { + return value.ToString(); + } + + public override object FromDbValue(Type fieldType, object value) + { + return ((string)value)[0]; + } + + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteDateTimeConverter.cs b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteDateTimeConverter.cs new file mode 100644 index 000000000..7f5074fc7 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteDateTimeConverter.cs @@ -0,0 +1,187 @@ +using System; +using System.Data; +using System.Globalization; +using ServiceStack.OrmLite.Converters; +using ServiceStack.Text.Common; + +namespace ServiceStack.OrmLite.Sqlite.Converters +{ + public class SqliteNativeDateTimeConverter : DateTimeConverter + { + public override string ColumnDefinition => "VARCHAR(8000)"; + + public override DbType DbType => DbType.DateTime; + + public override string ToQuotedString(Type fieldType, object value) + { + var dateTime = (DateTime)value; + if (DateStyle == DateTimeKind.Unspecified) + { + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + } + else if (DateStyle == DateTimeKind.Local && dateTime.Kind == DateTimeKind.Unspecified) + { + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime(); + } + else if (DateStyle == DateTimeKind.Utc) + { + dateTime = dateTime.Kind == DateTimeKind.Local + ? DateTime.SpecifyKind(dateTime, DateTimeKind.Local).ToUniversalTime() + : DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); + + return DialectProvider.GetQuotedValue(dateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), typeof(string)); + } + + var dateStr = DateTimeSerializer.ToLocalXsdDateTimeString(dateTime); + dateStr = dateStr.Replace("T", " "); + const int tzPos = 6; //"-00:00".Length; + var timeZoneMod = dateStr.Substring(dateStr.Length - tzPos, 1); + if (timeZoneMod == "+" || timeZoneMod == "-") + { + dateStr = dateStr.Substring(0, dateStr.Length - tzPos); + } + + return DialectProvider.GetQuotedValue(dateStr, typeof(string)); + } + + public override object FromDbValue(Type fieldType, object value) + { + var dateTime = (DateTime)value; + + if (DateStyle == DateTimeKind.Unspecified) + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + + return base.FromDbValue(dateTime); + } + + public override object GetValue(IDataReader reader, int columnIndex, object[] values) + { + try + { + if (values != null && values[columnIndex] == DBNull.Value) + return null; + + return reader.GetDateTime(columnIndex); + } + catch (Exception ex) + { + var value = base.GetValue(reader, columnIndex, values); + if (value == null) + return null; + + if (!(value is string dateStr)) + throw new Exception($"Converting from {value.GetType().Name} to DateTime is not supported"); + + Log.Warn("Error reading string as DateTime in Sqlite: " + dateStr, ex); + return DateTime.Parse(dateStr); + } + } + } + + /// + /// New behavior from using System.Data.SQLite.Core + /// + public class SqliteCoreDateTimeConverter : SqliteNativeDateTimeConverter + { + public override object ToDbValue(Type fieldType, object value) + { + var dateTime = (DateTime)value; + if (DateStyle == DateTimeKind.Utc) + { + if (dateTime.Kind == DateTimeKind.Local) + { + dateTime = dateTime.ToUniversalTime(); + } + else if (dateTime.Kind == DateTimeKind.Unspecified) + { + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); + } + } + else if (DateStyle == DateTimeKind.Local && dateTime.Kind != DateTimeKind.Local) + { + dateTime = dateTime.Kind == DateTimeKind.Utc + ? dateTime.ToLocalTime() + : DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime(); + } + else if (DateStyle == DateTimeKind.Unspecified && dateTime.Kind == DateTimeKind.Utc) + { + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified); + } + + return dateTime; + } + + public override object FromDbValue(Type fieldType, object value) + { + var dateTime = (DateTime)value; + + if (DateStyle == DateTimeKind.Utc) + { +#if NETCORE + //.NET Core returns correct Local time but as Unspecified so change to Local and Convert to UTC + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local).ToUniversalTime(); +#else + dateTime = dateTime.ToUniversalTime(); +#endif + } + + if (DateStyle == DateTimeKind.Local && dateTime.Kind != DateTimeKind.Local) + { + dateTime = dateTime.Kind == DateTimeKind.Utc + ? dateTime.ToLocalTime() + : DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + } + + return dateTime; + } + + public override object GetValue(IDataReader reader, int columnIndex, object[] values) + { + var ret = base.GetValue(reader, columnIndex, values); + return ret; + } + } + + public class SqliteDataDateTimeConverter : SqliteCoreDateTimeConverter + { + public override object FromDbValue(Type fieldType, object value) + { + var dateTime = (DateTime)value; + + if (DateStyle == DateTimeKind.Utc) + { + //.NET Core returns correct Local time but as Unspecified so change to Local and Convert to UTC + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); // don't convert + } + + if (DateStyle == DateTimeKind.Local && dateTime.Kind != DateTimeKind.Local) + { + dateTime = dateTime.Kind == DateTimeKind.Utc + ? dateTime.ToLocalTime() + : DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + } + + return dateTime; + } + } + + public class SqliteWindowsDateTimeConverter : SqliteNativeDateTimeConverter + { + public override object FromDbValue(Type fieldType, object value) + { + var dateTime = (DateTime)value; + + if (DateStyle == DateTimeKind.Utc) + dateTime = dateTime.ToUniversalTime(); + + if (DateStyle == DateTimeKind.Local && dateTime.Kind != DateTimeKind.Local) + { + dateTime = dateTime.Kind == DateTimeKind.Utc + ? dateTime.ToLocalTime() + : DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + } + + return dateTime; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteDateTimeOffsetConverter.cs b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteDateTimeOffsetConverter.cs new file mode 100644 index 000000000..b6b287e69 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteDateTimeOffsetConverter.cs @@ -0,0 +1,26 @@ +using System; +using System.Data; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Sqlite.Converters +{ + public class SqliteDateTimeOffsetConverter : DateTimeOffsetConverter + { + public override string ColumnDefinition + { + get { return "VARCHAR(8000)"; } + } + + public override string ToQuotedString(Type fieldType, object value) + { + var dateTimeOffsetValue = (DateTimeOffset)value; + return base.DialectProvider.GetQuotedValue(dateTimeOffsetValue.ToString("o"), typeof(string)); + } + + public override object ToDbValue(Type fieldType, object value) + { + var dateTimeOffsetValue = (DateTimeOffset)value; + return dateTimeOffsetValue.ToString("o"); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteGuidConverter.cs b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteGuidConverter.cs new file mode 100644 index 000000000..94e00e47e --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteGuidConverter.cs @@ -0,0 +1,87 @@ +using System; +using System.Data; +using System.Linq; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Sqlite.Converters +{ + public class SqliteGuidConverter : GuidConverter + { + public override string ColumnDefinition => "CHAR(36)"; + + public override string ToQuotedString(Type fieldType, object value) + { + var guid = (Guid)value; + var bytes = guid.ToByteArray(); + var fmt = "x'" + BitConverter.ToString(bytes).Replace("-", "") + "'"; + return fmt; + } + + public override object GetValue(IDataReader reader, int columnIndex, object[] values) + { + if (values != null) + { + if (values[columnIndex] == DBNull.Value) + return null; + } + else + { + if (reader.IsDBNull(columnIndex)) + return null; + } + + return reader.GetGuid(columnIndex); + } + } + + public class SqliteDataGuidConverter : GuidConverter + { + public override string ColumnDefinition => "CHAR(36)"; + + public override string ToQuotedString(Type fieldType, object value) + { + var guid = (Guid)value; + var bytes = guid.ToByteArray(); + SwapEndian(bytes); + var p = BitConverter.ToString(bytes).Replace("-",""); + var fmt = "'" + p.Substring(0,8) + "-" + + p.Substring(8,4) + "-" + + p.Substring(12,4) + "-" + + p.Substring(16,4) + "-" + + p.Substring(20) + "'"; + return fmt; + } + + public static void SwapEndian(byte[] guid) + { + _ = guid ?? throw new ArgumentNullException(nameof(guid)); + Swap(guid, 0, 3); + Swap(guid, 1, 2); + Swap(guid, 4, 5); + Swap(guid, 6, 7); + } + + private static void Swap(byte[] array, int index1, int index2) + { + var temp = array[index1]; + array[index1] = array[index2]; + array[index2] = temp; + } + public override object GetValue(IDataReader reader, int columnIndex, object[] values) + { + if (values != null) + { + if (values[columnIndex] == DBNull.Value) + return null; + } + else + { + if (reader.IsDBNull(columnIndex)) + return null; + } + + return reader.GetGuid(columnIndex); + } + } + +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteStringConverters.cs b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteStringConverters.cs new file mode 100644 index 000000000..7ec9fb7db --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/Converters/SqliteStringConverters.cs @@ -0,0 +1,11 @@ +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Sqlite.Converters +{ + public class SqliteStringConverter : StringConverter + { + public override string MaxColumnDefinition => UseUnicode ? "NVARCHAR(1000000)" : "VARCHAR(1000000)"; + + public override int MaxVarCharLength => 1000000; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Sqlite/Properties/AssemblyInfo.cs index 2419a0d2d..22ae012d6 100644 --- a/src/ServiceStack.OrmLite.Sqlite/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite.Sqlite/Properties/AssemblyInfo.cs @@ -1,29 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.Sqlite")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -#if NET35 -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite CLI 3.5")] -#elif NET40 -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite CLI 4.0")] -#endif -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ac105634-e91a-4fcc-a4f9-36aacd9fd47c")] - -[assembly: AssemblyVersion("4.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Android.csproj b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Android.csproj deleted file mode 100644 index c35477554..000000000 --- a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Android.csproj +++ /dev/null @@ -1,69 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {85DC23CC-BB59-4775-AA9C-552FF2BBEB22} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{F278D4AB-4730-4720-B08E-FE5E31564D9E};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Library - ServiceStack.OrmLite.Sqlite.Android - Resources\Resource.designer.cs - Resource - Resources - Assets - ServiceStack.OrmLite.Sqlite.Android - v2.3 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - None - false - - - full - true - bin\Release - prompt - 4 - false - false - - - - - - - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - {42BF9D4F-100D-4577-8538-5FD309D2CBEB} - ServiceStack.OrmLite.Android - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Core.csproj b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Core.csproj new file mode 100644 index 000000000..0bff5c925 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Core.csproj @@ -0,0 +1,22 @@ + + + + ServiceStack.OrmLite.Sqlite.Core + ServiceStack.OrmLite.Sqlite + ServiceStack.OrmLite.Sqlite + netstandard2.0;net6.0 + ServiceStack.OrmLite.Sqlite .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite.Sqlite + + SQLite;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Source.csproj b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Source.csproj new file mode 100644 index 000000000..a49af3600 --- /dev/null +++ b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.Source.csproj @@ -0,0 +1,23 @@ + + + + netstandard2.0;net6.0 + ServiceStack.OrmLite.Sqlite + ServiceStack.OrmLite.Sqlite + OrmLite.Sqlite - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for SQLite. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLite. + + SQLite;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + false + $(DefineConstants);ASYNC + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.csproj b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.csproj index 3a07b7ac5..de97a4b5c 100644 --- a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.csproj +++ b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.csproj @@ -1,149 +1,22 @@ - - + + - Debug - AnyCPU - 9.0.30729 - 2.0 - {CF68A37D-D071-469D-AE04-68594CB95382} - Library - Properties - ServiceStack.OrmLite.Sqlite + net472;netstandard2.0;net6.0 ServiceStack.OrmLite.Sqlite - v4.0 - 512 - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - + ServiceStack.OrmLite.Sqlite + OrmLite.Sqlite - Fast, code-first, config-free POCO ORM + + Light, simple and fast convention-based code-first POCO ORM for SQLite. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs in SQLite. + + SQLite;OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - x86 - - - true - bin\STATIC_ONLY NO_EXPRESSIONS\ - DEBUG;TRACE - full - x86 - prompt - 4 - false - AllRules.ruleset - - - true - bin\MonoTouch\ - DEBUG;TRACE - full - x86 - prompt - 4 - false - AllRules.ruleset - - - bin\Signed\ - TRACE - true - pdbonly - x86 - prompt - AllRules.ruleset - - - - ..\..\lib\Mono.Data.Sqlite.dll - - - False - ..\..\lib\ServiceStack.Interfaces.dll - - - - 3.5 - - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - + - - sqlite3.dll - PreserveNewest - + + + - - - \ No newline at end of file + + diff --git a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.csproj.user b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.csproj.user deleted file mode 100644 index daa64de00..000000000 --- a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.csproj.user +++ /dev/null @@ -1,14 +0,0 @@ - - - - ProjectFiles - - - - - - - en-US - false - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.iOS.csproj b/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.iOS.csproj deleted file mode 100644 index 4758e5709..000000000 --- a/src/ServiceStack.OrmLite.Sqlite/ServiceStack.OrmLite.Sqlite.iOS.csproj +++ /dev/null @@ -1,61 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85} - {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Library - ServiceStack.OrmLite.Sqlite.iOS - Resources - ServiceStack.OrmLite.Sqlite.iOS - - - true - full - false - bin\iPhone\Debug - DEBUG - prompt - 4 - false - true - iPhone Developer - - - none - true - bin\iPhone\Release - prompt - 4 - false - iPhone Developer - - - - - - - - - - - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07} - ServiceStack.OrmLite.iOS - - - - - - ..\..\lib\ServiceStack.Text.MonoTouch.dll - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/SqliteDialect.cs b/src/ServiceStack.OrmLite.Sqlite/SqliteDialect.cs index d3c7dc79d..30f5b2ef5 100644 --- a/src/ServiceStack.OrmLite.Sqlite/SqliteDialect.cs +++ b/src/ServiceStack.OrmLite.Sqlite/SqliteDialect.cs @@ -4,6 +4,7 @@ namespace ServiceStack.OrmLite { public static class SqliteDialect { - public static IOrmLiteDialectProvider Provider { get { return SqliteOrmLiteDialectProvider.Instance; } } + public static IOrmLiteDialectProvider Provider => SqliteOrmLiteDialectProvider.Instance; + public static SqliteOrmLiteDialectProvider Instance => SqliteOrmLiteDialectProvider.Instance; } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/SqliteExpression.cs b/src/ServiceStack.OrmLite.Sqlite/SqliteExpression.cs index 0ceb819c1..059b234d8 100644 --- a/src/ServiceStack.OrmLite.Sqlite/SqliteExpression.cs +++ b/src/ServiceStack.OrmLite.Sqlite/SqliteExpression.cs @@ -1,36 +1,29 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.Linq.Expressions; +using System.Linq.Expressions; namespace ServiceStack.OrmLite.Sqlite { - /// - /// Description of SqliteExpressionVisitor. - /// public class SqliteExpression : SqlExpression { - public SqliteExpression(IOrmLiteDialectProvider dialectProvider) + public SqliteExpression(IOrmLiteDialectProvider dialectProvider) : base(dialectProvider) {} protected override object VisitColumnAccessMethod(MethodCallExpression m) { - List args = this.VisitExpressionList(m.Arguments); + var args = this.VisitExpressionList(m.Arguments); var quotedColName = Visit(m.Object); string statement; switch (m.Method.Name) { case "Substring": - var startIndex = Int32.Parse(args[0].ToString()) + 1; + var startIndex = int.Parse(args[0].ToString()) + 1; if (args.Count == 2) { - var length = Int32.Parse(args[1].ToString()); - statement = string.Format("substr({0}, {1}, {2})", quotedColName, startIndex, length); + var length = int.Parse(args[1].ToString()); + statement = $"substr({quotedColName}, {startIndex}, {length})"; } else - statement = string.Format("substr({0}, {1})", quotedColName, startIndex); + statement = $"substr({quotedColName}, {startIndex})"; break; default: return base.VisitColumnAccessMethod(m); @@ -40,7 +33,7 @@ protected override object VisitColumnAccessMethod(MethodCallExpression m) protected override object VisitSqlMethodCall(MethodCallExpression m) { - List args = this.VisitExpressionList(m.Arguments); + var args = this.VisitInSqlExpressionList(m.Arguments); object quotedColName = args[0]; args.RemoveAt(0); @@ -49,27 +42,13 @@ protected override object VisitSqlMethodCall(MethodCallExpression m) switch (m.Method.Name) { case "In": - var member = Expression.Convert(m.Arguments[1], typeof(object)); - var lambda = Expression.Lambda>(member); - var getter = lambda.Compile(); - - var inArgs = Sql.Flatten(getter() as IEnumerable); - - var sIn = new StringBuilder(); - foreach (var e in inArgs) - { - sIn.AppendFormat("{0}{1}", - sIn.Length > 0 ? "," : "", - base.DialectProvider.GetQuotedValue(e, e.GetType())); - } - statement = string.Format("{0} {1} ({2})", quotedColName, m.Method.Name, sIn); + statement = ConvertInExpressionToSql(m, quotedColName); break; case "Desc": - statement = string.Format("{0} DESC", quotedColName); + statement = $"{quotedColName} DESC"; break; case "As": - statement = string.Format("{0} As {1}", quotedColName, - base.DialectProvider.GetQuotedColumnName(RemoveQuoteFromAlias(args[0].ToString()))); + statement = $"{quotedColName} AS {base.DialectProvider.GetQuotedColumnName(RemoveQuoteFromAlias(args[0].ToString()))}"; break; case "Sum": case "Count": @@ -79,13 +58,21 @@ protected override object VisitSqlMethodCall(MethodCallExpression m) statement = string.Format("{0}({1}{2})", m.Method.Name, quotedColName, - args.Count == 1 ? string.Format(",{0}", args[0]) : ""); + args.Count == 1 ? $",{args[0]}" : ""); + break; + case "CountDistinct": + statement = $"COUNT(DISTINCT {quotedColName})"; break; default: - throw new NotSupportedException(); + return base.VisitSqlMethodCall(m); } return new PartialSqlString(statement); } + + protected override PartialSqlString ToLengthPartialString(object arg) + { + return new PartialSqlString($"LENGTH({arg})"); + } } } diff --git a/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProvider.cs index b8ddd97ee..bd7339cbb 100644 --- a/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProvider.cs +++ b/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProvider.cs @@ -1,5 +1,5 @@ using System.Data; -using Mono.Data.Sqlite; +using System.Data.SQLite; namespace ServiceStack.OrmLite.Sqlite { @@ -9,7 +9,12 @@ public class SqliteOrmLiteDialectProvider : SqliteOrmLiteDialectProviderBase protected override IDbConnection CreateConnection(string connectionString) { - return new SqliteConnection(connectionString); + return new SQLiteConnection(connectionString); + } + + public override IDbDataParameter CreateParam() + { + return new SQLiteParameter(); } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProviderBase.cs b/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProviderBase.cs index 91a2891e2..817d20931 100644 --- a/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProviderBase.cs +++ b/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProviderBase.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; using System.Data; -using System.Globalization; using System.IO; using System.Reflection; -using System.Text; -using ServiceStack.Text.Common; +using System.Threading; +using System.Threading.Tasks; +using ServiceStack.OrmLite.Sqlite.Converters; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Sqlite { @@ -13,21 +14,31 @@ public abstract class SqliteOrmLiteDialectProviderBase : OrmLiteDialectProviderB { protected SqliteOrmLiteDialectProviderBase() { - base.MaxStringColumnDefinition = "VARCHAR(1000000)"; //Default Max is really 1B - base.DateTimeColumnDefinition = base.StringColumnDefinition; - base.BoolColumnDefinition = base.IntColumnDefinition; - base.GuidColumnDefinition = "CHAR(36)"; base.SelectIdentitySql = "SELECT last_insert_rowid()"; base.InitColumnTypeMap(); - } - public override void OnAfterInitColumnTypeMap() - { - DbTypeMap.Set(DbType.String, GuidColumnDefinition); - DbTypeMap.Set(DbType.String, GuidColumnDefinition); - DbTypeMap.Set(DbType.DateTimeOffset, StringColumnDefinition); - DbTypeMap.Set(DbType.DateTimeOffset, StringColumnDefinition); + OrmLiteConfig.DeoptimizeReader = true; + base.RegisterConverter(new SqliteCoreDateTimeConverter()); + //Old behavior using native sqlite3.dll + //base.RegisterConverter(new SqliteNativeDateTimeConverter()); + + base.RegisterConverter(new SqliteStringConverter()); + base.RegisterConverter(new SqliteDateTimeOffsetConverter()); + base.RegisterConverter(new SqliteGuidConverter()); + base.RegisterConverter(new SqliteBoolConverter()); + base.RegisterConverter(new SqliteByteArrayConverter()); +#if NETCORE + base.RegisterConverter(new SqliteCharConverter()); +#endif + this.Variables = new Dictionary + { + { OrmLiteVariables.SystemUtc, "CURRENT_TIMESTAMP" }, + { OrmLiteVariables.MaxText, "VARCHAR(1000000)" }, + { OrmLiteVariables.MaxTextUnicode, "NVARCHAR(1000000)" }, + { OrmLiteVariables.True, SqlBool(true) }, + { OrmLiteVariables.False, SqlBool(false) }, + }; } public static string Password { get; set; } @@ -41,7 +52,7 @@ public override string ToPostDropTableStatement(ModelDefinition modelDef) if (modelDef.RowVersion != null) { var triggerName = GetTriggerName(modelDef); - return "DROP TRIGGER IF EXISTS {0}".Fmt(GetQuotedName(triggerName)); + return $"DROP TRIGGER IF EXISTS {GetQuotedName(triggerName)}"; } return null; @@ -58,13 +69,12 @@ public override string ToPostCreateTableStatement(ModelDefinition modelDef) { var triggerName = GetTriggerName(modelDef); var tableName = GetTableName(modelDef); - var triggerBody = "UPDATE {0} SET {1} = OLD.{1} + 1 WHERE {2} = NEW.{2};".Fmt( + var triggerBody = string.Format("UPDATE {0} SET {1} = OLD.{1} + 1 WHERE {2} = NEW.{2};", tableName, modelDef.RowVersion.FieldName.SqlColumn(this), modelDef.PrimaryKey.FieldName.SqlColumn(this)); - var sql = "CREATE TRIGGER {0} BEFORE UPDATE ON {1} FOR EACH ROW BEGIN {2} END;".Fmt( - triggerName, tableName, triggerBody); + var sql = $"CREATE TRIGGER {triggerName} BEFORE UPDATE ON {tableName} FOR EACH ROW BEGIN {triggerBody} END;"; return sql; } @@ -74,26 +84,29 @@ public override string ToPostCreateTableStatement(ModelDefinition modelDef) public static string CreateFullTextCreateTableStatement(object objectWithProperties) { - var sbColumns = new StringBuilder(); + var sbColumns = StringBuilderCache.Allocate(); foreach (var propertyInfo in objectWithProperties.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var columnDefinition = (sbColumns.Length == 0) - ? string.Format("{0} TEXT PRIMARY KEY", propertyInfo.Name) - : string.Format(", {0} TEXT", propertyInfo.Name); + ? $"{propertyInfo.Name} TEXT PRIMARY KEY" + : $", {propertyInfo.Name} TEXT"; sbColumns.AppendLine(columnDefinition); } var tableName = objectWithProperties.GetType().Name; - var sql = string.Format("CREATE VIRTUAL TABLE \"{0}\" USING FTS3 ({1});", tableName, sbColumns); + var sql = $"CREATE VIRTUAL TABLE \"{tableName}\" USING FTS3 ({StringBuilderCache.ReturnAndFree(sbColumns)});"; return sql; } public override IDbConnection CreateConnection(string connectionString, Dictionary options) { + if (connectionString == "DataSource=:memory:") + connectionString = ":memory:"; + var isFullConnectionString = connectionString.Contains(";"); - var connString = new StringBuilder(); + var connString = StringBuilderCache.Allocate(); if (!isFullConnectionString) { if (connectionString != ":memory:") @@ -104,8 +117,11 @@ public override IDbConnection CreateConnection(string connectionString, Dictiona Directory.CreateDirectory(existingDir); } } +#if NETCORE + connString.AppendFormat(@"Data Source={0};", connectionString.Trim()); +#else connString.AppendFormat(@"Data Source={0};Version=3;New=True;Compress=True;", connectionString.Trim()); - +#endif } else { @@ -128,119 +144,59 @@ public override IDbConnection CreateConnection(string connectionString, Dictiona } } - return CreateConnection(connString.ToString()); + return CreateConnection(StringBuilderCache.ReturnAndFree(connString)); } - protected abstract IDbConnection CreateConnection(string connectionString); - public override string GetTableName(string table, string schema=null) - { - return schema != null - ? string.Format("{0}_{1}", - NamingStrategy.GetSchemaName(schema), - NamingStrategy.GetTableName(table)) - : NamingStrategy.GetTableName(table); - } + public override string GetQuotedName(string name, string schema) => GetQuotedName(name); //schema name is embedded in table name in MySql - public override string GetQuotedTableName(string tableName, string schema = null) + public override string ToTableNamesStatement(string schema) { - return GetQuotedName(GetTableName(tableName, schema)); + return schema == null + ? "SELECT name FROM sqlite_master WHERE type ='table' AND name NOT LIKE 'sqlite_%'" + : "SELECT name FROM sqlite_master WHERE type ='table' AND name LIKE {0}".SqlFmt(this, GetTableName("",schema) + "%"); } - public override object ConvertDbValue(object value, Type type) + public override string GetSchemaName(string schema) { - if (value == null || value is DBNull) return null; - - if (type == typeof(bool) && !(value is bool)) - { - var intVal = int.Parse(value.ToString()); - return intVal != 0; - } - - return base.ConvertDbValue(value, type); + return schema != null + ? NamingStrategy.GetSchemaName(schema).Replace(".", "_") + : NamingStrategy.GetSchemaName(schema); } - public override void SetDbValue(FieldDefinition fieldDef, IDataReader reader, int colIndex, object instance) - { - if (OrmLiteUtils.HandledDbNullValue(fieldDef, reader, colIndex, instance)) return; + public override string GetTableName(string table, string schema = null) => GetTableName(table, schema, useStrategy: true); - var fieldType = Nullable.GetUnderlyingType(fieldDef.FieldType) ?? fieldDef.FieldType; - if (fieldType == typeof(Guid)) - { - var guidStr = reader.GetString(colIndex); - var guidValue = new Guid(guidStr); - - fieldDef.SetValueFn(instance, guidValue); - } - else if (fieldType == typeof(DateTime)) - { - try - { - var dbValue = reader.GetDateTime(colIndex); - - fieldDef.SetValueFn(instance, dbValue); - } - catch (Exception) - { - var dateStr = reader.GetString(colIndex); - var dateValue = DateTimeSerializer.ParseShortestXsdDateTime(dateStr); - fieldDef.SetValueFn(instance, dateValue); - } - } - else - { - base.SetDbValue(fieldDef, reader, colIndex, instance); - } - } - - public override string GetQuotedValue(object value, Type fieldType) + public override string GetTableName(string table, string schema, bool useStrategy) { - if (value == null) return "NULL"; - - if (fieldType == typeof(DateTime)) - { - var dateValue = (DateTime)value; - var dateStr = dateValue.ToSqliteDateString(); - return base.GetQuotedValue(dateStr, typeof(string)); - } - - if (fieldType == typeof(bool)) + if (useStrategy) { - var boolValue = (bool)value; - return base.GetQuotedValue(boolValue ? 1 : 0, typeof(int)); - } - - // output datetimeoffset as a string formatted for roundtripping. - if (fieldType == typeof (DateTimeOffset)) - { - var dateTimeOffsetValue = (DateTimeOffset) value; - return base.GetQuotedValue(dateTimeOffsetValue.ToString("o"), typeof (string)); + return schema != null && !table.StartsWithIgnoreCase(schema + "_") + ? $"{NamingStrategy.GetSchemaName(schema)}_{NamingStrategy.GetTableName(table)}" + : NamingStrategy.GetTableName(table); } + + return schema != null && !table.StartsWithIgnoreCase(schema + "_") + ? $"{schema}_{table}" + : table; + } - if (fieldType == typeof(byte[])) - { - return "x'" + BitConverter.ToString((byte[])value).Replace("-", "") + "'"; - } + public override string GetQuotedTableName(string tableName, string schema = null) => + GetQuotedName(GetTableName(tableName, schema)); - return base.GetQuotedValue(value, fieldType); + public override SqlExpression SqlExpression() + { + return new SqliteExpression(this); } - protected override object GetValueOrDbNull(FieldDefinition fieldDef, object obj) + public override bool DoesSchemaExist(IDbCommand dbCmd, string schemaName) { - var value = GetValue(fieldDef, obj); - if (fieldDef.FieldType == typeof(DateTimeOffset) && value != null) - { - var dateTimeOffsetValue = (DateTimeOffset)value; - return dateTimeOffsetValue.ToString("o"); - } - - return value ?? DBNull.Value; + throw new NotImplementedException("Schemas are not supported by sqlite"); } - public override SqlExpression SqlExpression() + public override string ToCreateSchemaStatement(string schemaName) { - return new SqliteExpression(this); + throw new NotImplementedException("Schemas are not supported by sqlite"); } public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) @@ -254,18 +210,54 @@ public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string s return result > 0; } - public override string GetColumnDefinition(string fieldName, Type fieldType, bool isPrimaryKey, bool autoIncrement, - bool isNullable, bool isRowVersion, int? fieldLength, int? scale, string defaultValue, string customFieldDefinition) + public override bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null) + { + var sql = "PRAGMA table_info({0})" + .SqlFmt(GetTableName(tableName, schema)); + + var columns = db.SqlList>(sql); + foreach (var column in columns) + { + if (column.TryGetValue("name", out var name) && name.ToString().EqualsIgnoreCase(columnName)) + return true; + } + return false; + } + + public override string GetColumnDefinition(FieldDefinition fieldDef) { // http://www.sqlite.org/lang_createtable.html#rowid - var ret = base.GetColumnDefinition(fieldName, fieldType, isPrimaryKey, autoIncrement, isNullable, isRowVersion, fieldLength, scale, defaultValue, customFieldDefinition); - if (isPrimaryKey) + var ret = base.GetColumnDefinition(fieldDef); + if (fieldDef.IsPrimaryKey) return ret.Replace(" BIGINT ", " INTEGER "); - if (isRowVersion) + if (fieldDef.IsRowVersion) return ret + " DEFAULT 1"; return ret; } + + public override string SqlConflict(string sql, string conflictResolution) + { + // http://www.sqlite.org/lang_conflict.html + var parts = sql.SplitOnFirst(' '); + return parts[0] + " OR " + conflictResolution + " " + parts[1]; + } + + public override string SqlConcat(IEnumerable args) => string.Join(" || ", args); + + public override string SqlCurrency(string fieldOrValue, string currencySymbol) => SqlConcat(new []{ "'" + currencySymbol + "'", "printf(\"%.2f\", " + fieldOrValue + ")" }); + + public override string SqlBool(bool value) => value ? "1" : "0"; + + public override string SqlRandom => "random()"; + + public override void EnableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("PRAGMA foreign_keys = ON;"); + public override Task EnableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) => + cmd.ExecNonQueryAsync("PRAGMA foreign_keys = ON;", null, token); + + public override void DisableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("PRAGMA foreign_keys = OFF;"); + public override Task DisableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) => + cmd.ExecNonQueryAsync("PRAGMA foreign_keys = OFF;", null, token); } public static class SqliteExtensions @@ -282,20 +274,5 @@ public static IOrmLiteDialectProvider Configure(this IOrmLiteDialectProvider pro return provider; } - - public static string ToSqliteDateString(this DateTime dateTime) - { - //Not forcing co-ercsion into UTC for Sqlite - var dateStr = DateTimeSerializer.ToLocalXsdDateTimeString(dateTime); - dateStr = dateStr.Replace("T", " "); - const int tzPos = 6; //"-00:00".Length; - var timeZoneMod = dateStr.Substring(dateStr.Length - tzPos, 1); - if (timeZoneMod == "+" || timeZoneMod == "-") - { - dateStr = dateStr.Substring(0, dateStr.Length - tzPos); - } - - return dateStr; - } } } diff --git a/src/ServiceStack.OrmLite.Sqlite32/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Sqlite32/Properties/AssemblyInfo.cs deleted file mode 100644 index 14f89576f..000000000 --- a/src/ServiceStack.OrmLite.Sqlite32/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.Sqlite32")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -#if NET35 -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite32 .NET 3.5")] -#elif NET40 -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite32 .NET 4.0")] -#endif -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("81b2eb97-03e7-4e80-9cb8-9c4e1fe414cc")] - diff --git a/src/ServiceStack.OrmLite.Sqlite32/ServiceStack.OrmLite.Sqlite32.csproj b/src/ServiceStack.OrmLite.Sqlite32/ServiceStack.OrmLite.Sqlite32.csproj deleted file mode 100644 index d66a47e20..000000000 --- a/src/ServiceStack.OrmLite.Sqlite32/ServiceStack.OrmLite.Sqlite32.csproj +++ /dev/null @@ -1,95 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {EAA0F35E-66CD-4B3D-BB17-7CE8EDE83AE7} - Library - Properties - ServiceStack.OrmLite.Sqlite - ServiceStack.OrmLite.SqliteNET - v4.0 - 512 - - ..\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\Release\ - TRACE;NET35 - prompt - 4 - x86 - - - bin\Signed\ - TRACE;NET35 - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\ServiceStack.Text.dll - - - - - - False - ..\packages\System.Data.SQLite.x86.1.0.91.0\lib\net40\System.Data.SQLite.dll - - - - - - - - - Properties\GlobalAssemblyInfo.cs - - - SqliteExpression.cs - - - SqliteOrmLiteDialectProviderBase.cs - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite32/SqliteDialect.cs b/src/ServiceStack.OrmLite.Sqlite32/SqliteDialect.cs deleted file mode 100644 index d3c7dc79d..000000000 --- a/src/ServiceStack.OrmLite.Sqlite32/SqliteDialect.cs +++ /dev/null @@ -1,9 +0,0 @@ -using ServiceStack.OrmLite.Sqlite; - -namespace ServiceStack.OrmLite -{ - public static class SqliteDialect - { - public static IOrmLiteDialectProvider Provider { get { return SqliteOrmLiteDialectProvider.Instance; } } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite32/SqliteOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Sqlite32/SqliteOrmLiteDialectProvider.cs deleted file mode 100644 index cb5bd5c2a..000000000 --- a/src/ServiceStack.OrmLite.Sqlite32/SqliteOrmLiteDialectProvider.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Data; -using System.Data.SQLite; - -namespace ServiceStack.OrmLite.Sqlite -{ - public class SqliteOrmLiteDialectProvider : SqliteOrmLiteDialectProviderBase - { - // what's the purpose of this Instance field? (It's like a pseudo-wanna-be singleton?) - public static SqliteOrmLiteDialectProvider Instance = new SqliteOrmLiteDialectProvider(); - - protected override IDbConnection CreateConnection(string connectionString) - { - return new SQLiteConnection(connectionString, parseViaFramework: ParseViaFramework); - } - - public SqliteOrmLiteDialectProvider WithPassword(string password) - { - Password = password; - return Instance; - } - - public SqliteOrmLiteDialectProvider WithUTFEncoding() - { - UTF8Encoded = true; - return Instance; - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite32/packages.config b/src/ServiceStack.OrmLite.Sqlite32/packages.config deleted file mode 100644 index 2f4722374..000000000 --- a/src/ServiceStack.OrmLite.Sqlite32/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite64/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.Sqlite64/Properties/AssemblyInfo.cs deleted file mode 100644 index d84ca1335..000000000 --- a/src/ServiceStack.OrmLite.Sqlite64/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.Sqlite64")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -#if NET35 -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite64 .NET 3.5")] -#elif NET40 -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite64 .NET 4.0")] -#endif -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("540d6e0c-97cd-42a8-9bed-89a7a887928b")] - -[assembly: AssemblyVersion("4.0.0.0")] diff --git a/src/ServiceStack.OrmLite.Sqlite64/ServiceStack.OrmLite.Sqlite64.csproj b/src/ServiceStack.OrmLite.Sqlite64/ServiceStack.OrmLite.Sqlite64.csproj deleted file mode 100644 index 83a475cdd..000000000 --- a/src/ServiceStack.OrmLite.Sqlite64/ServiceStack.OrmLite.Sqlite64.csproj +++ /dev/null @@ -1,93 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {59E6B217-24AD-4F55-B032-FCD0090CD300} - Library - Properties - ServiceStack.OrmLite.Sqlite - ServiceStack.OrmLite.SqliteNET - v4.0 - 512 - ..\ - true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x64 - - - bin\Signed\ - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\ServiceStack.Text.dll - - - - - - False - ..\packages\System.Data.SQLite.x64.1.0.91.0\lib\net40\System.Data.SQLite.dll - - - - - - - - - SqliteExpression.cs - - - SqliteOrmLiteDialectProviderBase.cs - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - Designer - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite64/SqliteDialect.cs b/src/ServiceStack.OrmLite.Sqlite64/SqliteDialect.cs deleted file mode 100644 index d3c7dc79d..000000000 --- a/src/ServiceStack.OrmLite.Sqlite64/SqliteDialect.cs +++ /dev/null @@ -1,9 +0,0 @@ -using ServiceStack.OrmLite.Sqlite; - -namespace ServiceStack.OrmLite -{ - public static class SqliteDialect - { - public static IOrmLiteDialectProvider Provider { get { return SqliteOrmLiteDialectProvider.Instance; } } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite64/SqliteOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite.Sqlite64/SqliteOrmLiteDialectProvider.cs deleted file mode 100644 index 6b359a6ae..000000000 --- a/src/ServiceStack.OrmLite.Sqlite64/SqliteOrmLiteDialectProvider.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Data; -using System.Data.SQLite; - -namespace ServiceStack.OrmLite.Sqlite -{ - public class SqliteOrmLiteDialectProvider : SqliteOrmLiteDialectProviderBase - { - // what's the purpose of this Instance field? (It's like a pseudo-wanna-be singleton?) - public static SqliteOrmLiteDialectProvider Instance = new SqliteOrmLiteDialectProvider(); - - protected override IDbConnection CreateConnection(string connectionString) - { - return new SQLiteConnection(connectionString, parseViaFramework: ParseViaFramework); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.Sqlite64/packages.config b/src/ServiceStack.OrmLite.Sqlite64/packages.config deleted file mode 100644 index 3511b14ce..000000000 --- a/src/ServiceStack.OrmLite.Sqlite64/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqliteV45/ServiceStack.OrmLite.SqliteV45.csproj b/src/ServiceStack.OrmLite.SqliteV45/ServiceStack.OrmLite.SqliteV45.csproj deleted file mode 100644 index 98c9fbc1b..000000000 --- a/src/ServiceStack.OrmLite.SqliteV45/ServiceStack.OrmLite.SqliteV45.csproj +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Debug - AnyCPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54} - Library - Properties - ServiceStack.OrmLite.Sqlite - ServiceStack.OrmLite.Sqlite - v4.5 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET45 - prompt - 4 - - - - False - ..\..\lib\Mono.Data.Sqlite.dll - - - False - ..\..\lib\ServiceStack.Interfaces.dll - - - False - ..\..\lib\ServiceStack.Text.dll - - - - - - - - AssemblyInfo.cs - - - SqliteDialect.cs - - - SqliteExpression.cs - - - SqliteOrmLiteDialectProvider.cs - - - SqliteOrmLiteDialectProviderBase.cs - - - - - - - - sqlite3.dll - PreserveNewest - - - - - {fdc37335-9ecc-413b-bec5-16b466b0e689} - ServiceStack.OrmLiteV45 - - - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Core.ttinclude b/src/ServiceStack.OrmLite.T4/OrmLite.Core.ttinclude similarity index 88% rename from tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Core.ttinclude rename to src/ServiceStack.OrmLite.T4/OrmLite.Core.ttinclude index 5cf67a3a8..81b08223e 100644 --- a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Core.ttinclude +++ b/src/ServiceStack.OrmLite.T4/OrmLite.Core.ttinclude @@ -1,3 +1,4 @@ + <#@ template language="C#" hostspecific="True" #> <#@ assembly name="EnvDTE" #> <#@ assembly name="System.Core.dll" #> @@ -16,12 +17,12 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Text.RegularExpressions" #> <#@ import namespace="System.Configuration" #> -<#@ import namespace="System.Windows.Forms" #> +<#@ import namespace="System.Windows.Forms" #> <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> <#+ /* - This is code is based on the T4 template from the PetaPoco project which in turn is based on the subsonic project. + This code is based on the T4 template from the PetaPoco project which in turn is based on the subsonic project. ----------------------------------------------------------------------------------------- @@ -86,6 +87,8 @@ string ClassPrefix = ""; string ClassSuffix = ""; string SchemaName = null; bool IncludeViews = false; +bool IncludeFunctions = false; +bool IncludeSPReturnTypes = false; //Will create {StoredProcName}_Result classes for any SPs with output results public class Table { @@ -95,6 +98,7 @@ public class Table public string Name; public string Schema; public bool IsView; + public bool IsFunction; public string CleanName; public string ClassName; public string SequenceName; @@ -196,6 +200,7 @@ public class TableIndex public class FKey { public string ToTable; + public string ToTableSingular; public string FromColumn; public string ToColumn; } @@ -208,9 +213,11 @@ public class SP public string Schema; public string SchemaQualifiedName {get{return Schema+"."+Name;}} public List Parameters; + public List SPOutputColumns; public SP() { Parameters=new List(); + SPOutputColumns = new List(); } public string ArgList { @@ -230,6 +237,12 @@ public class SP } } +public class SPOutputColumn +{ + public string Name ; + public string DotNetType ; +} + public enum SPParamDir { OutDirection, @@ -264,8 +277,14 @@ static Func CleanUp = (str) => { str = rxCleanUp.Replace(str, "_"); - if (char.IsDigit(str[0]) || cs_keywords.Contains(str)) + if (char.IsDigit(str[0])) + { + str = "_" + str; + } + else if (cs_keywords.Contains(str)) + { str = "@" + str; + } return str; }; @@ -283,6 +302,8 @@ static string CheckNullable(Column col) return result; } + + string GetConnectionString(ref string connectionStringName, out string providerName) { var _CurrentProject = GetCurrentProject(); @@ -520,7 +541,7 @@ Tables LoadTables(bool makeSingular) else { // Assume SQL Server - reader=new SqlServerSchemaReader(); + reader=new SqlServerSchemaReader(IncludeSPReturnTypes); } reader.outer=this; @@ -534,11 +555,11 @@ Tables LoadTables(bool makeSingular) result.RemoveAt(i); continue; } - if (!IncludeViews && result[i].IsView) + if ((!IncludeViews && result[i].IsView) ||(!IncludeFunctions && result[i].IsFunction)) { result.RemoveAt(i); continue; - } + } } } @@ -589,6 +610,21 @@ List SPsNotSupported(string providerName) return new List(); } +string GetParamDirection(SPParamDir direction) + { + switch(direction) + { + case SPParamDir.InAndOutDirection: + return "ParameterDirection.InputOutput"; + case SPParamDir.OutDirection: + return "ParameterDirection.Output"; + case SPParamDir.InDirection: + default: + return "ParameterDirection.Input"; + } + } + + List LoadSPs() { InitConnectionString(); @@ -666,7 +702,7 @@ List LoadSPs() else { // Assume SQL Server - reader=new SqlServerSchemaReader(); + reader=new SqlServerSchemaReader(IncludeSPReturnTypes); } reader.outer=this; @@ -781,17 +817,25 @@ static int GetDatatypeSize(string type) return -1; } +// Edit here to get a method to read the proc class SqlServerSchemaReader : SchemaReader { + private bool IncludeSPReturnTypes; + public SqlServerSchemaReader(bool includeSPReturnTypes) + { + IncludeSPReturnTypes = includeSPReturnTypes; + } // SchemaReader.ReadSchema + + public override Tables ReadSchema(DbConnection connection, DbProviderFactory factory) { - var result=new Tables(); + var result = new Tables(); _connection=connection; _factory=factory; - var cmd=_factory.CreateCommand(); + var cmd = _factory.CreateCommand(); cmd.Connection=connection; cmd.CommandText=TABLE_SQL; @@ -807,13 +851,41 @@ class SqlServerSchemaReader : SchemaReader tbl.Name=rdr["TABLE_NAME"].ToString(); tbl.Schema=rdr["TABLE_SCHEMA"].ToString(); tbl.IsView=string.Compare(rdr["TABLE_TYPE"].ToString(), "View", true)==0; + tbl.IsFunction=string.Compare(rdr["TABLE_TYPE"].ToString(), "TVF", true)==0; tbl.CleanName=CleanUp(tbl.Name); tbl.ClassName=Inflector.MakeSingular(tbl.CleanName); - + result.Add(tbl); } } } + + var cmdFks = _factory.CreateCommand(); + cmdFks.Connection=connection; + cmdFks.CommandText=FOREIGN_KEYS_SQL; + //get all the foreign keys and add them to the tables. + using(cmdFks) + { + using (var rdr=cmdFks.ExecuteReader()) + { + while(rdr.Read()) + { + var tableName = rdr["TableWithForeignKey"].ToString(); + var table = result.FirstOrDefault(x => x.Name == tableName); + if (table != null) { + if (table.FKeys == null) { + table.FKeys = new List(); + } + var newForeignKey = new FKey(); + newForeignKey.ToTable = rdr["TargetTable"].ToString(); + newForeignKey.ToTableSingular = Inflector.MakeSingular(CleanUp(newForeignKey.ToTable)); + newForeignKey.FromColumn = rdr["ForeignKeyColumn"].ToString(); + newForeignKey.ToColumn = rdr["TargetTableKey"].ToString(); + table.FKeys.Add(newForeignKey); + } + } + } + } foreach (var tbl in result) { @@ -862,6 +934,7 @@ class SqlServerSchemaReader : SchemaReader foreach (var sp in result) { sp.Parameters=LoadSPParams(sp); + if (IncludeSPReturnTypes) sp.SPOutputColumns = LoadSPOutputColumns(sp); } return result; } @@ -947,6 +1020,43 @@ class SqlServerSchemaReader : SchemaReader } } + List LoadSPOutputColumns(SP sp) + { + var result=new List(); + using (var cmd=_factory.CreateCommand()) + { + cmd.Connection=_connection; + cmd.CommandText=string.Format(@"SELECT name,CAST(is_nullable as VARCHAR(1)) is_nullable,system_type_name FROM sys.dm_exec_describe_first_result_set_for_object(OBJECT_ID('{0}'), 1) WHERE is_hidden = 0",sp.SchemaQualifiedName); + using (IDataReader rdr=cmd.ExecuteReader()) + { + while(rdr.Read()) + { + if (!rdr.IsDBNull(0)) + { + SPOutputColumn param=new SPOutputColumn(); + param.Name = rdr["name"].ToString(); + + var sqlType = rdr["system_type_name"].ToString(); + var index = sqlType.IndexOf('('); //Trim off size data + if (index > 0) sqlType = sqlType.Substring(0,index); + + var nullable = rdr["is_nullable"].ToString() ; + if (nullable == "0") + { + param.DotNetType = GetPropertyType(sqlType); + } + else + { + param.DotNetType = GetNullablePropertyType(sqlType); + } + if (!result.Any(t=>t.Name == param.Name)) result.Add(param); + } + } + } + } + return result; + } + string GetPK(string table){ @@ -1156,25 +1266,67 @@ class SqlServerSchemaReader : SchemaReader } - const string TABLE_SQL=@"SELECT * - FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW'"; - - const string COLUMN_SQL=@"SELECT - TABLE_CATALOG AS [Database], - TABLE_SCHEMA AS Owner, - TABLE_NAME AS TableName, - COLUMN_NAME AS ColumnName, - ORDINAL_POSITION AS OrdinalPosition, - COLUMN_DEFAULT AS DefaultSetting, - IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, - CHARACTER_MAXIMUM_LENGTH AS MaxLength, - DATETIME_PRECISION AS DatePrecision, - COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity, - COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_NAME=@tableName AND TABLE_SCHEMA=@schemaName - ORDER BY OrdinalPosition ASC"; + const string TABLE_SQL=@"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW' + UNION + SELECT SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME, 'TVF' FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'FUNCTION' AND DATA_TYPE = 'TABLE'"; + + const string COLUMN_SQL=@"SELECT T.[Database] , + T.Owner , + T.TableName , + T.ColumnName , + T.OrdinalPosition , + T.DefaultSetting , + T.IsNullable , + T.DataType , + T.MaxLength , + T.DatePrecision , + T.IsIdentity , + T.IsComputed FROM ( + SELECT + TABLE_CATALOG AS [Database], + TABLE_SCHEMA AS Owner, + TABLE_NAME AS TableName, + COLUMN_NAME AS ColumnName, + ORDINAL_POSITION AS OrdinalPosition, + COLUMN_DEFAULT AS DefaultSetting, + IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, + CHARACTER_MAXIMUM_LENGTH AS MaxLength, + DATETIME_PRECISION AS DatePrecision, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME=@tableName AND TABLE_SCHEMA=@schemaName + --ORDER BY OrdinalPosition ASC + UNION + SELECT TABLE_CATALOG AS [Database], + TABLE_SCHEMA AS Owner, + TABLE_NAME AS TableName, + COLUMN_NAME AS ColumnName, + ORDINAL_POSITION AS OrdinalPosition, + COLUMN_DEFAULT AS DefaultSetting, + IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, + CHARACTER_MAXIMUM_LENGTH AS MaxLength, + DATETIME_PRECISION AS DatePrecision, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed + FROM INFORMATION_SCHEMA.ROUTINE_COLUMNS + WHERE TABLE_NAME=@tableName AND TABLE_SCHEMA=@schemaName + ) T + ORDER BY T.OrdinalPosition ASC"; + + const string FOREIGN_KEYS_SQL= +@"SELECT DISTINCT + tableWithForeignKey.name AS TableWithForeignKey, + columnWithForeignKey.name AS ForeignKeyColumn, + referencedTable.name AS TargetTable, + referencedColumn.name AS TargetTableKey +FROM sys.foreign_key_columns foreignKeyColumn +INNER JOIN sys.tables tableWithForeignKey ON tableWithForeignKey.object_id = foreignKeyColumn.parent_object_id +INNER JOIN sys.columns columnWithForeignKey ON columnWithForeignKey.object_id = foreignKeyColumn.parent_object_id + AND columnWithForeignKey.column_id = foreignKeyColumn.parent_column_id +INNER JOIN sys.tables referencedTable ON referencedTable.object_id = foreignKeyColumn.referenced_object_id +INNER JOIN sys.columns referencedColumn ON referencedColumn.object_id = foreignKeyColumn.referenced_object_id + AND referencedColumn.column_id = foreignKeyColumn.referenced_column_id"; const string SP_NAMES_SQL=@"SELECT o.name AS sp_name, s.name AS schema_name FROM sys.objects o @@ -1187,7 +1339,7 @@ WHERE o.type = 'P' 'sysdiagrams' )"; - const string SP_PARAMETERS_SQL=@"SELECT * from information_schema.PARAMETERS + const string SP_PARAMETERS_SQL=@"SELECT * from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME = @spname order by ORDINAL_POSITION"; @@ -1431,6 +1583,33 @@ class PostGreSqlSchemaReader : SchemaReader } } + var cmdFks = _factory.CreateCommand(); + cmdFks.Connection=connection; + cmdFks.CommandText=FOREIGN_KEYS_SQL; + //get all the foreign keys and add them to the tables. + using(cmdFks) + { + using (var rdr=cmdFks.ExecuteReader()) + { + while(rdr.Read()) + { + var tableName = rdr["TableWithForeignKey"].ToString(); + var table = result.FirstOrDefault(x => x.Name == tableName); + if (table != null) { + if (table.FKeys == null) { + table.FKeys = new List(); + } + var newForeignKey = new FKey(); + newForeignKey.ToTable = rdr["TargetTable"].ToString(); + newForeignKey.ToTableSingular = Inflector.MakeSingular(CleanUp(newForeignKey.ToTable)); + newForeignKey.FromColumn = rdr["ForeignKeyColumn"].ToString(); + newForeignKey.ToColumn = rdr["TargetTableKey"].ToString(); + table.FKeys.Add(newForeignKey); + } + } + } + } + foreach (var tbl in result) { tbl.Columns=LoadColumns(tbl); @@ -1492,11 +1671,11 @@ class PostGreSqlSchemaReader : SchemaReader string GetPK(string table){ string sql=@"SELECT kcu.column_name - FROM information_schema.key_column_usage kcu - JOIN information_schema.table_constraints tc - ON kcu.constraint_name=tc.constraint_name - WHERE lower(tc.constraint_type)='primary key' - AND kcu.table_name=@tablename"; + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu + JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc + ON kcu.CONSTRAINT_NAME=tc.CONSTRAINT_NAME + WHERE lower(tc.CONSTRAINT_TYPE)='primary key' + AND kcu.TABLE_NAME=@tablename"; using (var cmd=_factory.CreateCommand()) { @@ -1578,16 +1757,33 @@ class PostGreSqlSchemaReader : SchemaReader const string TABLE_SQL=@" - SELECT table_name, table_schema, table_type - FROM information_schema.tables - WHERE (table_type='BASE TABLE' OR table_type='VIEW') - AND table_schema NOT IN ('pg_catalog', 'information_schema'); + SELECT TABLE_NAME, TABLE_SCHEMA, TABLE_TYPE + FROM INFORMATION_SCHEMA.TABLES + WHERE (TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW') + AND TABLE_SCHEMA NOT IN ('pg_catalog', 'INFORMATION_SCHEMA'); "; const string COLUMN_SQL=@" - SELECT column_name, is_nullable, udt_name, column_default - FROM information_schema.columns - WHERE table_name=@tableName; + SELECT COLUMN_NAME, IS_NULLABLE, UDT_NAME, COLUMN_DEFAULT + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME=@tableName; + "; + + const string FOREIGN_KEYS_SQL=@" + SELECT + R.TABLE_NAME AS TableWithForeignKey, + R.COLUMN_NAME AS ForeignKeyColumn, + U.TABLE_NAME AS TargetTable, + U.COLUMN_NAME AS TargetTableKey + FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE U + INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS FK + ON U.CONSTRAINT_CATALOG = FK.UNIQUE_CONSTRAINT_CATALOG + AND U.CONSTRAINT_SCHEMA = FK.UNIQUE_CONSTRAINT_SCHEMA + AND U.CONSTRAINT_NAME = FK.UNIQUE_CONSTRAINT_NAME + INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE R + ON R.CONSTRAINT_CATALOG = FK.CONSTRAINT_CATALOG + AND R.CONSTRAINT_SCHEMA = FK.CONSTRAINT_SCHEMA + AND R.CONSTRAINT_NAME = FK.CONSTRAINT_NAME "; } @@ -1717,8 +1913,8 @@ class MySqlSchemaReader : SchemaReader const string TABLE_SQL=@" SELECT * - FROM information_schema.tables - WHERE (table_type='BASE TABLE' OR table_type='VIEW') + FROM INFORMATION_SCHEMA.TABLES + WHERE (TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW') "; } @@ -2457,12 +2653,12 @@ class Manager { CurrentBlock = new Block { Name = name }; } - public void StartFooter(bool includeInDefault = true) { + public void StartFooter(bool includeInDefault) { CurrentBlock = footer; footer.IncludeInDefault = includeInDefault; } - public void StartHeader(bool includeInDefault = true) { + public void StartHeader(bool includeInDefault) { CurrentBlock = header; header.IncludeInDefault = includeInDefault; } @@ -2476,7 +2672,7 @@ class Manager { currentBlock = null; } - public virtual void Process(bool split, bool sync = true) { + public virtual void Process(bool split, bool sync) { if (split) { EndBlock(); String headerText = template.ToString(header.Start, header.Length); @@ -2597,10 +2793,12 @@ class Manager { if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName)) checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); } + + } } /* End of Manager.tt */ -#> \ No newline at end of file +#> diff --git a/src/ServiceStack.OrmLite.T4/OrmLite.Poco.tt b/src/ServiceStack.OrmLite.T4/OrmLite.Poco.tt new file mode 100644 index 000000000..474fbfbf1 --- /dev/null +++ b/src/ServiceStack.OrmLite.T4/OrmLite.Poco.tt @@ -0,0 +1,158 @@ +<#@ include file="OrmLite.Core.ttinclude" #> +<# + // Settings + ConnectionStringName = ""; // Uses last connection string in config if not specified + Namespace = ""; + ClassPrefix = ""; + ClassSuffix = ""; + bool SplitIntoMultipleFiles = false; // if true: Generates one file for every class + bool MakeSingular = true; // if true: Changes the classname to singular if tablename is not singular + bool UseIdAsPK = true; // if true: Changes the primary key property name to Id + bool GenerateConstructor = false; // if true: Generates the default empty constructor + bool UseSchemaAttribute = true; // if true: Adds explicit '[Schema]' attribute + bool CreateAutoQueryTypes = false; //if true: Will create Query types with all possible search fields explicitly typed + bool AddNamedConnection = false; //if true: Adds NamedConnection attribute so AutoQuery will override default IDbConnection + bool IncludeReferences = false; //if true: Addes References(typeof(ReferenceTableType)) to FKs + string UseSpecificNamedConnection = ""; //if not null: Will use name provided as NamedConnection and AddNamedConnection = true, else ConnectionStringName is used as default NamedConnection + // Read schema + var tables = LoadTables(MakeSingular); + + +/* + // Tweak Schema + tables["tablename"].Ignore = true; // To ignore a table + tables["tablename"].ClassName = "newname"; // To change the class name of a table + tables["tablename"]["columnname"].Ignore = true; // To ignore a column + tables["tablename"]["columnname"].PropertyName="newname"; // To change the property name of a column + tables["tablename"]["columnname"].PropertyType="bool"; // To change the property type of a column +*/ + + // Generate output + if (tables.Count>0) + { +#> +<# +if (string.IsNullOrEmpty(Namespace)) Namespace=ConnectionStringName; +if (string.IsNullOrEmpty(Namespace)) Namespace="OrmLitePoco"; +var manager = Manager.Create(Host, GenerationEnvironment); +manager.StartHeader(true); +#> +// +// This file was generated by a T4 template. +// Don't change it directly as your change would get overwritten. Instead, make changes +// to the .tt file (i.e. the T4 template) and save it to regenerate this file. + +// Make sure the compiler doesn't complain about missing Xml comments +#pragma warning disable 1591 + +using System; + +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack; + +namespace <#=Namespace #> +{ +<#manager.EndBlock(); #> +<# +foreach(Table tbl in from t in tables where !t.Ignore select t) +{ +manager.StartNewFile(tbl.Name + ".cs"); +#> +<#if (CreateAutoQueryTypes && AddNamedConnection) {#> + [NamedConnection("<#=!string.IsNullOrEmpty(UseSpecificNamedConnection) ? UseSpecificNamedConnection : ConnectionStringName#>")] + <#}#> +<# if (MakeSingular) {#> + [Alias("<#=tbl.Name#>")] +<#}#> +<# if (UseSchemaAttribute && !string.IsNullOrEmpty(tbl.Schema) && tbl.Schema != "dbo") {#> + [Schema("<#=tbl.Schema#>")] +<#}#> + public partial class <#=tbl.ClassName#><#if (tbl.HasPK() && UseIdAsPK) { #> : IHasId<<#=tbl.PK.PropertyType#>><#}#> + { +<# if (GenerateConstructor) { #> + public <#=tbl.ClassName#>() + { + } + +<# } +var priorProperyNames = new List(); +foreach(Column col in from c in tbl.Columns where !c.Ignore select c) +{ +if (priorProperyNames.Contains(col.PropertyName)) //Change duplicate style names +{ + col.PropertyName = "_" + col.PropertyName; +} +priorProperyNames.Add(col.PropertyName); + if ((col.Name!=col.PropertyName) || (col.IsPK && UseIdAsPK)) { #> + [Alias("<#=col.Name#>")] +<# } if (col.PropertyType == "string" && col.Size > 0) { #> + [StringLength(<#=col.Size#>)] +<# } if (col.IsAutoIncrement) { #> + [AutoIncrement] +<# } if (col.IsComputed) { #> + [Compute] + <# } if (IncludeReferences && tbl.FKeys != null && tbl.FKeys.Any(x => x.FromColumn == col.PropertyName)) { + var toTable = MakeSingular ? tbl.FKeys.First(x => x.FromColumn == col.PropertyName).ToTableSingular : tbl.FKeys.First(x => x.FromColumn == col.PropertyName).ToTable;#> + [References(typeof(<#=ClassPrefix + toTable + ClassSuffix#>))] +<# } if (col.IsNullable != true && col.IsAutoIncrement != true) { #> + [Required] +<# } if (!col.IsPK){#> + public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set; } +<# } if (col.IsPK && UseIdAsPK) { #> + public <#=col.ProperPropertyType#> Id { get; set; } +<# } if (col.IsPK && !UseIdAsPK) { #> + [PrimaryKey] + public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set; } +<# } #> +<# } #> + } + +<#if (CreateAutoQueryTypes) {#> + public partial class <#=tbl.ClassName#>Query: QueryDb<<#=tbl.ClassName#>> + { +<#foreach(Column col in from c in tbl.Columns where !c.Ignore select c) +{ +var ormName = (col.IsPK && UseIdAsPK) ? "Id" : col.PropertyName; +var isString = col.ProperPropertyType == "string"; +var nullablePropType = col.ProperPropertyType.Replace("?","") + "?"; +var isArray = col.ProperPropertyType.Contains("[]"); +var isBool = col.ProperPropertyType.Contains("bool"); +var isGuid = col.ProperPropertyType.Contains("Guid"); + if (!col.IsPK){#> + public <#=!isArray && !isString ? nullablePropType : col.ProperPropertyType#> <#=ormName#> { get; set; } +<# } if (col.IsPK && UseIdAsPK) { #> + public <#=isString ? "string" : nullablePropType#> Id { get; set;} +<# } if (col.IsPK && !UseIdAsPK) { #> + public <#=isString ? "string" : nullablePropType#> <#=col.PropertyName#> { get; set; }<# } + +if (isString){ #> + public <#=col.ProperPropertyType#> <#=ormName#>StartsWith { get; set; } + public <#=col.ProperPropertyType#> <#=ormName#>EndsWith { get; set; } + public <#=col.ProperPropertyType#> <#=ormName#>Contains { get; set; } + public <#=col.ProperPropertyType#> <#=ormName#>Like { get; set; } + public <#=col.ProperPropertyType#>[] <#=ormName#>Between { get; set; } + public <#=col.ProperPropertyType#>[] <#=ormName#>In { get; set; } +<#} +else if (!isArray && !isBool) { if (!isGuid) {#> + public <#=nullablePropType#> <#=ormName#>GreaterThanOrEqualTo { get; set; } + public <#=nullablePropType#> <#=ormName#>GreaterThan { get; set; } + public <#=nullablePropType#> <#=ormName#>LessThan { get; set; } + public <#=nullablePropType#> <#=ormName#>LessThanOrEqualTo { get; set; } + public <#=nullablePropType#> <#=ormName#>NotEqualTo { get; set; } + public <#=col.ProperPropertyType#>[] <#=ormName#>Between { get; set; } +<#}#> + public <#=col.ProperPropertyType#>[] <#=ormName#>In { get; set; } +<#}#> + +<# } #> +} + <#}#> +<# manager.EndBlock(); #> +<# } #> +<#manager.StartFooter(true); #> +} +#pragma warning restore 1591 +<#manager.EndBlock(); #> +<#manager.Process(SplitIntoMultipleFiles, true); #> +<# } #> diff --git a/src/ServiceStack.OrmLite.T4/OrmLite.SP.tt b/src/ServiceStack.OrmLite.T4/OrmLite.SP.tt new file mode 100644 index 000000000..a573669bf --- /dev/null +++ b/src/ServiceStack.OrmLite.T4/OrmLite.SP.tt @@ -0,0 +1,73 @@ +<#@ include file="OrmLite.Core.ttinclude" #> +<# + // Settings + ConnectionStringName = ""; // Uses last connection string in config if not specified + var SPNamespace = "StoredProcedures"; + ClassPrefix = ""; + ClassSuffix = ""; + + // Read schema + var sps = LoadSPs(); + + // Generate output + if (sps.Count>0) + { +#> +<# +if (string.IsNullOrEmpty(SPNamespace)) SPNamespace=ConnectionStringName; +if (string.IsNullOrEmpty(SPNamespace)) SPNamespace="StoredProcedures"; +#> +using System; +using System.Data.Common; +using System.Data; +using System.Collections.Generic; +using ServiceStack.OrmLite; +using ServiceStack.DataAnnotations; + +namespace <#=SPNamespace#> +{ + public static class SPList + { + private static DbParameter CreateNewParameter(DbCommand dbCommand, string paramName, object paramValue, ParameterDirection paramDirection, DbType paramType) + { + DbParameter param = dbCommand.CreateParameter(); + param.Direction = paramDirection; + param.DbType = paramType; + param.ParameterName = paramName; + param.Value = paramValue ?? DBNull.Value; + return param; + } + +<#foreach(var sp in sps){#> + public static OrmLiteSPStatement <#=sp.CleanName#>(this IDbConnection db<#foreach(var param in sp.Parameters){#>, <#=param.NullableSysType#> @<#=Inflector.MakeInitialLowerCase(param.Name)#> = null<#}#>) + { + var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); + dbCmd.CommandText = "<#=sp.Name#>"; + dbCmd.CommandType = CommandType.StoredProcedure; +<#if (sp.Parameters.Count > 0) { foreach(var param in sp.Parameters){#> + dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"<#=param.Name#>",@<#=Inflector.MakeInitialLowerCase(param.Name)#>,<#=GetParamDirection(param.Direction)#>,<#=param.DbType#>)); +<#}#> <#}#> + dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"__ReturnValue",0,ParameterDirection.ReturnValue,DbType.Int32)); + return new OrmLiteSPStatement(db, dbCmd); + } + +<#}#> + } + + <#if (IncludeSPReturnTypes) foreach(var sp in sps) + { + if (!sp.SPOutputColumns.Any()) continue; #> + public class <#=sp.CleanName#>_Result + { + <# foreach(var prop in sp.SPOutputColumns) { var _alias = false; var propName = prop.Name; if (propName.Contains(' ') || propName.Contains('$') || propName.Contains('+') || propName.Contains('%')) { propName = propName.Replace(' ','_').Replace("$","_Dollar").Replace("+","_Plus").Replace("%","_Percent"); _alias = true; }; if (char.IsDigit(propName[0])) { propName = "_" + propName; _alias = true; }; + + if (_alias) {#> [Alias("<#=prop.Name#>")] + <#}#> + public <#=prop.DotNetType#> <#=propName#> { get; set; } + <#} + #> +} +<#}#> + +} +<#}#> diff --git a/src/ServiceStack.OrmLite.T4/ServiceStack.OrmLite.T4.csproj b/src/ServiceStack.OrmLite.T4/ServiceStack.OrmLite.T4.csproj new file mode 100644 index 000000000..7d8b9264c --- /dev/null +++ b/src/ServiceStack.OrmLite.T4/ServiceStack.OrmLite.T4.csproj @@ -0,0 +1,41 @@ + + + + + + netstandard1.0 + ServiceStack.OrmLite.T4 + OrmLite.T4 - T4 schema-generation templates for OrmLite + + Generate POCO models for all existing tables and stored procedures in a database for use with OrmLite. + + T4;SQL;Templates;CodeGen;OrmLite;RDBMS;POCO;Code-First;ORM;Schema-less;Blobs + true + false + contentFiles + true + false + false + CS8021 + + + + + + + true + $(ContentTargetFolders)\any\any\%(RecursiveDir)%(Filename)%(Extension) + + + + + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/App.config b/src/ServiceStack.OrmLite.VistaDB.Tests/App.config deleted file mode 100644 index c5d0ab6ac..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/App.config +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/DateTimeOffsetTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/DateTimeOffsetTests.cs deleted file mode 100644 index 4ddfbb52e..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/DateTimeOffsetTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Data; -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - internal class DateTimeOffsetTests : OrmLiteTestBase - { - /// - /// Generic way to create our test tables. - /// - /// - /// - /// - /// - /// - private static TTable InsertAndSelectDateTimeOffset(IDbConnection db, TProp value) where TTable : IDateTimeOffsetObject, new() - { - db.DropAndCreateTable(); - db.Insert(new TTable - { - Test = value - }); - var result = db.Select().First(); - return result; - } - - [Test] - public void EnsureDateTimeOffsetSaves() - { - var dbFactory = new OrmLiteConnectionFactory(base.ConnectionString, VistaDbDialect.Provider); - - using (var db = dbFactory.OpenDbConnection()) - { - var dateTime = new DateTimeOffset(2012, 1, 30, 1, 1, 1, new TimeSpan(5, 0, 0)); - var x = InsertAndSelectDateTimeOffset(db, dateTime); - Assert.AreEqual(x.Test, dateTime); - } - } - - [Test] - public void EnsureNullableDateTimeOffsetSaves() - { - var dbFactory = new OrmLiteConnectionFactory(base.ConnectionString, VistaDbDialect.Provider); - - using (var db = dbFactory.OpenDbConnection()) - { - DateTimeOffset? dateTime = new DateTimeOffset(2012, 1, 30, 1, 1, 1, new TimeSpan(5, 0, 0)); - var x = InsertAndSelectDateTimeOffset(db, dateTime); - Assert.AreEqual(x.Test, dateTime); - } - } - - private class DateTimeOffsetObject : IDateTimeOffsetObject - { - public DateTimeOffset Test { get; set; } - } - - private class NullableDateTimeOffsetObject : IDateTimeOffsetObject - { - public DateTimeOffset? Test { get; set; } - } - - private interface IDateTimeOffsetObject - { - T Test { get; set; } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/EnumTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/EnumTests.cs deleted file mode 100644 index 302a3be2c..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/EnumTests.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - public class EnumTests : OrmLiteTestBase - { - [Test] - public void CanCreateTable() - { - OpenDbConnection().CreateTable(true); - } - - [Test] - public void CanStoreEnumValue() - { - using(var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum {Id = 1, EnumValue = SomeEnum.Value1}); - } - } - - [Test] - public void CanGetEnumValue() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; - con.Save(obj); - var target = con.SingleById(obj.Id); - Assert.AreEqual(obj.Id, target.Id); - Assert.AreEqual(obj.EnumValue, target.EnumValue); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_expression() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Select(q => q.EnumValue == SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Test] - public void CanQueryByEnumValue_using_select_with_string() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.SelectFmt("EnumValue = {0}", SomeEnum.Value1); - - Assert.AreEqual(2, target.Count()); - } - } - - [Test] - public void CanQueryByEnumValue_using_where_with_AnonType() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var target = con.Where(new { EnumValue = SomeEnum.Value1 }); - - Assert.AreEqual(2, target.Count()); - } - } - } - - public enum SomeEnum - { - Value1, - Value2, - Value3 - } - - public class TypeWithEnum - { - public int Id { get; set; } - public SomeEnum EnumValue { get; set; } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/AdditiveExpressionsTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/AdditiveExpressionsTest.cs deleted file mode 100644 index eeb2acfa0..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/AdditiveExpressionsTest.cs +++ /dev/null @@ -1,131 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class AdditiveExpressionsTest : ExpressionsTestBase - { - [Test] - public void Can_select_constant_add_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 4 + 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_constant_subtract_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 10 - 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_variable_add_expression() - { -// ReSharper disable ConvertToConstant.Local - var a = 4; - var b = 3; -// ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == a + b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_variable_subtract_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 10; - var b = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == a - b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_method_add_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(4) + GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_method_subtract_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(10) - GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/Author.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/Author.cs deleted file mode 100644 index eb15fa0c7..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/Author.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class Author - { - public Author(){} - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - public DateTime Birthday { get; set;} - public DateTime ? LastActivity { get; set;} - public Decimal? Earnings { get; set;} - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - public Int16 Rate{ get; set;} - } -} - diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/AuthorUseCase.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/AuthorUseCase.cs deleted file mode 100644 index ac483fb8f..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/AuthorUseCase.cs +++ /dev/null @@ -1,380 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class AuthorUseCase : OrmLiteTestBase - { - private List authors; - - public AuthorUseCase() - { - authors = new List(); - authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); - authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); - authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); - authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); - authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); - authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); - authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); - authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); - authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); - authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); - authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); - authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico", LastActivity = DateTime.Today }); - } - - [SetUp] - public void Setup() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.SaveAll(authors); - } - } - - [Test] - public void AuthorUsesCases() - { - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (var db = OpenDbConnection()) - { - int year = DateTime.Today.AddYears(-20).Year; - var lastDay = new DateTime(year, 12, 31); - int expected = 5; - - ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - List result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); - Assert.AreEqual(expected, result.Count); - Author a = new Author() { Birthday = lastDay }; - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); - Assert.AreEqual(expected, result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected = 6; - //Sql.In can take params object[] - var city = "Berlin"; - ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); - Assert.AreEqual(expected, result.Count); - - // select authors from Bogota and Cartagena : 7 - expected = 7; - //... or Sql.In can take List - city = "Bogota"; - List cities = new List(); - cities.Add(city); - cities.Add("Cartagena"); - ev.Where().Where(rn => Sql.In(rn.City, cities)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name starts with A - expected = 3; - ev.Where().Where(rn => rn.Name.StartsWith("A")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.StartsWith("A")); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected = 3; - var name = "GARZON"; - ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); - Assert.AreEqual(expected, result.Count); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected = 3; - ev.Where().Where(rn => rn.Name.EndsWith("garzon")); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Assert.AreEqual(expected, result.Count); - - - // select authors which name contains Benedict - expected = 2; - name = "Benedict"; - ev.Where().Where(rn => rn.Name.Contains(name)); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Assert.AreEqual(expected, result.Count); - a.Name = name; - result = db.Select(rn => rn.Name.Contains(a.Name)); - Assert.AreEqual(expected, result.Count); - - - // select authors with Earnings <= 50 - expected = 3; - var earnings = 50; - ev.Where().Where(rn => rn.Earnings <= earnings); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Earnings <= 50); - Assert.AreEqual(expected, result.Count); - - // select authors with Rate = 10 and city=Mexio - expected = 1; - city = "Mexico"; - ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Assert.AreEqual(expected, result.Count); - - a.City = city; - result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); - Assert.AreEqual(expected, result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected = 2; - var rate = 0; - ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); - Assert.AreEqual(expected, rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected = 4; - ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); - ev.Where().Where(rn => !rn.Active); - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - //update comment for City == null - expected = 2; - ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); - Assert.AreEqual(expected, rows); - - // delete where City is null - expected = 2; - rows = db.Delete(ev); - Assert.AreEqual(expected, rows); - - - // lets select all records ordered by Rate Descending and Name Ascending - expected = 14; - ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - var author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel", author.Name); - - // select only first 5 rows .... - expected = 5; - ev.Limit(5); // note: order is the same as in the last sentence - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - //paging : - ev.Limit(0, 4);// first page, page size=4; - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); - - ev.Limit(4, 4);// second page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Jorge Garzon".ToUpper(), author.Name); - - ev.Limit(8, 4);// third page - result = db.Select(ev); - author = result.FirstOrDefault(); - Assert.AreEqual("Rodger Contreras".ToUpper(), author.Name); - - // select distinct.. - ev.Limit().OrderBy(); // clear limit, clear orde - ev.SelectDistinct(r => r.City); - expected = 6; - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - // select distinct with limit - ev.Limit(0, 4); - ev.SelectDistinct(r => r.City); - expected = 4; - result = db.Select(ev); - Assert.AreEqual(expected, result.Count); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); - result = db.Select(ev); - var expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Max(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - var r1 = db.Single(ev); - Assert.AreEqual(expectedResult, r1.Birthday); - - var r2 = db.Scalar(e => Sql.Max(e.Birthday)); - Assert.AreEqual(expectedResult, r2); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - ev.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); - result = db.Select(ev); - expectedResult = authors.Min(r => r.Birthday); - Assert.AreEqual(expectedResult, result[0].Birthday); - - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - var expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) - .GroupBy(r => r.City) - .OrderBy(r => r.City); - result = db.Select(ev); - expectedStringResult = "Berlin"; - Assert.AreEqual(expectedStringResult, result[0].City); - - r1 = db.Single(ev); - Assert.AreEqual(expectedStringResult, r1.City); - - var expectedDecimal = authors.Max(e => e.Earnings); - Decimal? r3 = db.Scalar(e => Sql.Max(e.Earnings)); - Assert.AreEqual(expectedDecimal, r3.Value); - - var expectedString = authors.Max(e => e.Name); - string r4 = db.Scalar(e => Sql.Max(e.Name)); - Assert.AreEqual(expectedString, r4); - - var expectedDate = authors.Max(e => e.LastActivity); - DateTime? r5 = db.Scalar(e => Sql.Max(e.LastActivity)); - Assert.AreEqual(expectedDate, r5); - - var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); - DateTime? r51 = db.Scalar( - e => Sql.Max(e.LastActivity), - e => e.City == "Bogota"); - Assert.AreEqual(expectedDate51, r51); - - try - { - var expectedBool = authors.Max(e => e.Active); - bool r6 = db.Scalar(e => Sql.Max(e.Active)); - Assert.AreEqual(expectedBool, r6); - } - catch (Exception e) - { - //???? - //if (dialect.Name == "PostgreSQL") - // Console.WriteLine("OK PostgreSQL: " + e.Message); - //else - // Console.WriteLine("************** FAILED *************** " + e.Message); - } - - - - // Tests for predicate overloads that make use of the expression visitor - author = db.Single(q => q.Name == "Jorge Garzon"); - - try - { - author = db.Single(q => q.Name == "Does not exist"); - Assert.Fail(); - } - catch - { - //"Expected exception thrown, OK? True" - } - - author = db.Single(q => q.Name == "Does not exist"); - Assert.IsNull(author); - - author = db.Single(q => q.City == "Bogota"); - Assert.AreEqual("Angel Colmenares", author.Name); - - a.City = "Bogota"; - author = db.Single(q => q.City == a.City); - Assert.AreEqual("Angel Colmenares", author.Name); - - // count test - - var expectedCount = authors.Count(); - long r7 = db.Scalar(e => Sql.Count(e.Id)); - Assert.AreEqual(expectedCount, r7); - - expectedCount = authors.Count(e => e.City == "Bogota"); - r7 = db.Scalar( - e => Sql.Count(e.Id), - e => e.City == "Bogota"); - Assert.AreEqual(expectedCount, r7); - - ev.Update();// all fields will be updated - // select and update - expected = 1; - var rr = db.Single(rn => rn.Name == "Luis garzon"); - rr.City = "Madrid"; - rr.Comments = "Updated"; - ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated - rows = db.UpdateOnly(rr, ev); // == dbCmd.Update(rr) but it returns void - Assert.AreEqual(expected, rows); - - expected = 0; - ev.Where().Where(r => r.City == "Ciudad Gotica"); - rows = db.UpdateOnly(rr, ev); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.City == "Madrid").Count; - author = new Author() { Active = false }; - rows = db.UpdateOnly(author, x => x.Active, x => x.City == "Madrid"); - Assert.AreEqual(expected, rows); - - expected = db.Select(x => x.Active == false).Count; - rows = db.Delete(x => x.Active == false); - Assert.AreEqual(expected, rows); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/ConditionalExpressionTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/ConditionalExpressionTest.cs deleted file mode 100644 index 1d1e45e3b..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/ConditionalExpressionTest.cs +++ /dev/null @@ -1,139 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class ConditionalExpressionTest : ExpressionsTestBase - { - [Test] - public void Can_select_conditional_and_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn > 2 && q.IntColumn < 4); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_conditional_or_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 3 || q.IntColumn < 0); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_evaluated_conditional_and_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 10; - var b = 5; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a >= b && a > 0)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_evaluated_conditional_or_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 10; - var b = 5; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 3 || a > b); - - Assert.IsNotNull(actual); - Assert.AreEqual(11, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_evaluated_invalid_conditional_or_valid_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => !q.BoolColumn || a); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - [Test] - public void Can_select_evaluated_conditional_and_valid_expression() - { - var model = new - { - StringValue = "4" - }; - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn && q.StringColumn == model.StringValue); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/EqualityExpressionsTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/EqualityExpressionsTest.cs deleted file mode 100644 index 2749d71f0..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/EqualityExpressionsTest.cs +++ /dev/null @@ -1,262 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class EqualityExpressionsTest : ExpressionsTestBase - { - #region int tests - - [Test] - public void Can_select_equals_constant_int_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_variable_int_expression() - { -// ReSharper disable ConvertToConstant.Local - var columnValue = 3; -// ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = columnValue, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == columnValue); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_not_equals_constant_int_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn != 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - - [Test] - public void Can_select_not_equals_variable_int_expression() - { - // ReSharper disable ConvertToConstant.Local - var columnValue = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = columnValue, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn != columnValue); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - - [Test] - public void Can_select_not_equals_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn != GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - - #endregion - - #region bool test - - [Test] - public void Can_select_equals_constant_bool_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - -// ReSharper disable RedundantBoolCompare - var actual = OpenDbConnection().Select(q => q.BoolColumn == true); -// ReSharper restore RedundantBoolCompare - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_constant_bool_expression2() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - // ReSharper disable RedundantBoolCompare - var actual = OpenDbConnection().Select(q => q.BoolColumn); - // ReSharper restore RedundantBoolCompare - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_variable_bool_expression() - { - // ReSharper disable ConvertToConstant.Local - var columnValue = true; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == columnValue); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_bool_method_expression() - { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == GetValue(true)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_equals_null_espression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test", - NullableCol = new TestType { StringColumn = "sometext" } - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.NullableCol == null); - - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 10); - CollectionAssert.DoesNotContain(actual, expected); - } - - [Test] - public void Can_select_not_equals_null_espression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test", - NullableCol = new TestType { StringColumn = "sometext" } - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.NullableCol != null); - - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - // Assume not equal works ;-) - #endregion - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/ExpressionsTestBase.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/ExpressionsTestBase.cs deleted file mode 100644 index 4486213d7..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/ExpressionsTestBase.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Linq; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class ExpressionsTestBase : OrmLiteTestBase - { - [SetUp] - public void Setup() - { - OpenDbConnection().CreateTable(true); - } - - public T GetValue(T item) - { - return item; - } - - protected void EstablishContext(int numberOfRandomObjects) - { - EstablishContext(numberOfRandomObjects, null); - } - - protected void EstablishContext(int numberOfRandomObjects, params TestType[] obj) - { - if (obj == null) - obj = new TestType[0]; - - using (var con = OpenDbConnection()) - { - foreach (var t in obj) - { - con.Insert(t); - } - - var random = new Random((int)(DateTime.UtcNow.Ticks ^ (DateTime.UtcNow.Ticks >> 4))); - for (var i = 0; i < numberOfRandomObjects; i++) - { - TestType o = null; - - while (o == null) - { - int intVal = random.Next(); - - o = new TestType - { - BoolColumn = random.Next()%2 == 0, - IntColumn = intVal, - StringColumn = Guid.NewGuid().ToString() - }; - - if (obj.Any(x => x.IntColumn == intVal)) - o = null; - } - - con.Insert(o); - } - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/LogicalExpressionsTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/LogicalExpressionsTest.cs deleted file mode 100644 index 169edd165..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/LogicalExpressionsTest.cs +++ /dev/null @@ -1,151 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class LogicalExpressionsTest : ExpressionsTestBase - { - #region constants - - // Unlikely - // OpenDbConnection().Select(q => q.BoolColumn == (true & false)); - - #endregion - - #region variables - - [Test] - public void Can_select_logical_and_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - var b = false; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a & b)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_logical_or_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - var b = false; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a | b)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_logical_xor_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = true; - var b = false; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a ^ b)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - #endregion - - #region method - - [Test] - public void Can_select_logical_and_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == (GetValue(true) & GetValue(false))); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_logical_or_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == (GetValue(true) | GetValue(false))); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_logical_xor_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == (GetValue(true) ^ GetValue(false))); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/MultiplicativeExpressionsTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/MultiplicativeExpressionsTest.cs deleted file mode 100644 index d8ab90659..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/MultiplicativeExpressionsTest.cs +++ /dev/null @@ -1,193 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class MultiplicativeExpressionsTest : ExpressionsTestBase - { - [Test] - public void Can_select_constant_multiply_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 4 * 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_constant_divide_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 36 / 3); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_constant_modulo_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == 37 % 10); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_variable_multiply_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 4; - var b = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == a * b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_variable_divide_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 36; - var b = 3; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == a / b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_variablemodulo_expression() - { - // ReSharper disable ConvertToConstant.Local - var a = 37; - var b = 10; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == a % b); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_method_multiply_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(4) * GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_method_divide_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(36) / GetValue(3)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_method_modulo_expression() - { - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(37) % GetValue(10)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/OrmLiteCountTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/OrmLiteCountTests.cs deleted file mode 100644 index 9490a8d42..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/OrmLiteCountTests.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Data; -using System.Linq.Expressions; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - [TestFixture] - public class OrmLiteCountTests : OrmLiteTestBase - { - [Test] - public void CanDoCountWithInterface() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - db.DeleteAll(); - - db.Insert(new CountTestTable { Id = 1, StringValue = "Your string value" }); - - var count = db.Scalar(e => Sql.Count(e.Id)); - - Assert.That(count, Is.EqualTo(1)); - - count = Count(db); - - Assert.That(count, Is.EqualTo(1)); - - count = CountByColumn(db); - - Assert.That(count, Is.EqualTo(0)); - - } - } - - [Test] - public void CanDoCountWithInterfaceAndPredicate() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - db.DeleteAll(); - db.Insert(new CountTestTable { Id = 1, StringValue = "Your string value" }); - - Expression> exp = q => q.Id == 2; - var count = Count(db, exp); - Assert.That(count, Is.EqualTo(0)); - - - exp = q => q.Id == 1; - count = Count(db, exp); - Assert.That(count, Is.EqualTo(1)); - - exp = q => q.CountColumn == null; - count = Count(db, exp); - Assert.That(count, Is.EqualTo(1)); - - exp = q => q.CountColumn == null; - count = CountByColumn(db, exp); - Assert.That(count, Is.EqualTo(0)); - } - } - - long Count(IDbConnection db) where T : IHasId, new() - { - T request = new T(); - return db.Scalar(e => Sql.Count(request.Id)); - } - - - long CountByColumn(IDbConnection db) where T : IHasCountColumn, new() - { - T request = new T(); - return db.Scalar(e => Sql.Count(request.CountColumn)).Value; - } - - - int Count(IDbConnection db, Expression> predicate) where T : IHasId, new() - { - return db.Scalar(e => Sql.Count(e.Id), predicate); - } - - int CountByColumn(IDbConnection db, Expression> predicate) where T : IHasCountColumn, new() - { - return db.Scalar(e => Sql.Count(e.CountColumn), predicate).Value; - } - - } - - public interface IHasCountColumn - { - int? CountColumn { get; set; } - } - - - public class CountTestTable : IHasId, IHasCountColumn - { - public CountTestTable() { } - #region IHasId implementation - public int Id { get; set; } - [StringLength(40)] - public string StringValue { get; set; } - #endregion - - #region IHasCountColumn implementation - public int? CountColumn { get; set; } - #endregion - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/PrimaryExpressionsTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/PrimaryExpressionsTest.cs deleted file mode 100644 index 066d9b488..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/PrimaryExpressionsTest.cs +++ /dev/null @@ -1,365 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class PrimaryExpressionsTest : ExpressionsTestBase - { - private static class TestClass - { - public static int StaticProperty { get { return 12; } } - public static int _staticField = 12; - } - - private class TestClass - { - public static T StaticMethod(T value) - { - return value; - } - - public T Property { get; set; } - - public T _field; - - public T Mehtod() - { - return _field; - } - - public TestClass(T value) - { - Property = value; - _field = value; - } - } - - private struct TestStruct - { - public T Property { get { return _field; } } - - public T _field; - - public T Mehtod() - { - return _field; - } - - public TestStruct(T value) - { - _field = value; - } - } - - #region int - - [Test] - public void Can_select_int_property_expression() - { - var tmp = new TestClass(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Property); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_int_field_expression() - { - var tmp = new TestClass(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp._field); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_int_method_expression() - { - var tmp = new TestClass(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Mehtod()); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_static_int_property_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass.StaticProperty); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_static_int_field_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass._staticField); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_static_int_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass.StaticMethod(12)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_int_new_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == new TestClass(12).Property); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_struct_int_field_expression() - { - var tmp = new TestStruct(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp._field); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_struct_int_property_expression() - { - var tmp = new TestStruct(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Property); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_struct_int_method_expression() - { - var tmp = new TestStruct(12); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Mehtod()); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - #endregion int - - - #region bool - - [Test] - public void Can_select_bool_property_expression() - { - var tmp = new TestClass(false); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == tmp.Property); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_bool_field_expression() - { - var tmp = new TestClass(false); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == tmp._field); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_bool_method_expression() - { - var tmp = new TestClass(false); - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == tmp.Mehtod()); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_static_bool_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == TestClass.StaticMethod(false)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_bool_new_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == new TestClass(false).Property); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); - } - - #endregion bool - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/RelationalExpressionsTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/RelationalExpressionsTest.cs deleted file mode 100644 index 5f80d44e3..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/RelationalExpressionsTest.cs +++ /dev/null @@ -1,82 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class RelationalExpressionsTest : ExpressionsTestBase - { - [Test] - public void Can_select_greater_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn > 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); - } - - [Test] - public void Can_select_greater_or_equal_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn >= 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(11, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_smaller_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn < 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(0, actual.Count); - } - - [Test] - public void Can_select_smaller_or_equal_than_expression() - { - var expected = new TestType() - { - IntColumn = 1, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn <= 1); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/StringFunctionTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/StringFunctionTests.cs deleted file mode 100644 index e9fe29163..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/StringFunctionTests.cs +++ /dev/null @@ -1,259 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class StringFunctionTests : ExpressionsTestBase - { - [Test] - public void Can_select_using_contains() - { - var stringVal = "stringValue"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_contains_with_quote_in_string() - { - var stringVal = "string'ContainingAQuote"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_contains_with_double_quote_in_string() - { - var stringVal = "string\"ContainingAQuote"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_contains_with_backtick_in_string() - { - var stringVal = "string`ContainingAQuote"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = stringVal - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith_with_quote_in_string() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "'asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith_with_double_quote_in_string() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "\"asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_startsWith_with_backtick_in_string() - { - var prefix = "prefix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = prefix + "`asdfasdfasdf" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasdfasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith_with_quote_in_string() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasd'fasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith_with_double_quote_in_string() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasd\"fasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_using_endsWith_with_backtick_in_string() - { - var postfix = "postfix"; - - var expected = new TestType() - { - IntColumn = 7, - BoolColumn = true, - StringColumn = "asdfasd`fasdf" + postfix - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/TestType.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/TestType.cs deleted file mode 100644 index 8d157e101..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/TestType.cs +++ /dev/null @@ -1,41 +0,0 @@ -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class TestType - { - public int IntColumn { get; set; } - public bool BoolColumn { get; set; } - public string StringColumn { get; set; } - public object NullableCol { get; set; } - - [AutoIncrement] - public int Id { get; set; } - - public bool Equals(TestType other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return other.IntColumn == IntColumn && other.BoolColumn.Equals(BoolColumn) && Equals(other.StringColumn, StringColumn); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != typeof (TestType)) return false; - return Equals((TestType) obj); - } - - public override int GetHashCode() - { - unchecked - { - int result = IntColumn; - result = (result*397) ^ BoolColumn.GetHashCode(); - result = (result*397) ^ (StringColumn != null ? StringColumn.GetHashCode() : 0); - return result; - } - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/UnaryExpressionsTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/UnaryExpressionsTest.cs deleted file mode 100644 index fb5395cf0..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Expressions/UnaryExpressionsTest.cs +++ /dev/null @@ -1,225 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests.Expressions -{ - public class UnaryExpressionsTest : ExpressionsTestBase - { - #region constants - - [Test] - public void Can_select_unary_plus_constant_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == +12); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_minus_constant_expression() - { - var expected = new TestType() - { - IntColumn = -12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == -12); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_not_constant_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == !true); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_not_constant_expression2() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => !q.BoolColumn); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - #endregion - - #region variables - - [Test] - public void Can_select_unary_plus_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var intVal = +12; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == intVal); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_minus_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var intVal = -12; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = -12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == intVal); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_not_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - var boolVal = true; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == !boolVal); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_cast_variable_expression() - { - // ReSharper disable ConvertToConstant.Local - object intVal = 12; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == (int)intVal); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - #endregion - - #region method - - [Test] - public void Can_select_unary_not_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = false, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.BoolColumn == !GetValue(true)); - - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_cast_method_expression() - { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == (int)GetValue((object)12)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/ForeignKeyAttributeTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/ForeignKeyAttributeTests.cs deleted file mode 100644 index 5d14927f3..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/ForeignKeyAttributeTests.cs +++ /dev/null @@ -1,180 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - [TestFixture] - public class ForeignKeyAttributeTests : OrmLiteTestBase - { - [TestFixtureSetUp] - public void Setup() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateSimpleForeignKey() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascade() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CascadesOnDelete() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - - dbConn.Save(new ReferencedType { Id = 1 }); - dbConn.Save(new TypeWithOnDeleteCascade { RefId = 1 }); - - Assert.AreEqual(1, dbConn.Select().Count); - Assert.AreEqual(1, dbConn.Select().Count); - - dbConn.Delete(r => r.Id == 1); - - Assert.AreEqual(0, dbConn.Select().Count); - Assert.AreEqual(0, dbConn.Select().Count); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteNoAction() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [NUnit.Framework.Ignore("Not supported in SQL Server")] - [Test] - public void CanCreateForeignWithOnDeleteRestrict() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteSetDefault() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - - [Test] - public void CanCreateForeignWithOnDeleteSetNull() - { - using (var dbConn = OpenDbConnection()) - { - dbConn.CreateTable(true); - } - } - } - - public class ReferencedType - { - public int Id { get; set; } - } - - - public class TypeWithSimpleForeignKey - { - [AutoIncrement] - public int Id { get; set; } - [References(typeof(ReferencedType))] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteAndUpdateCascade - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteNoAction - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteRestrict - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT")] - public int? RefId { get; set; } - } - - public class TypeWithOnDeleteSetDefault - { - [AutoIncrement] - public int Id { get; set; } - - [Default(typeof(int), "17")] - [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT")] - public int RefId { get; set; } - } - - public class TypeWithOnDeleteSetNull - { - [AutoIncrement] - public int Id { get; set; } - - [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL")] - public int? RefId { get; set; } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/InsertParam_GetLastInsertId.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/InsertParam_GetLastInsertId.cs deleted file mode 100644 index 8a5f00ecc..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/InsertParam_GetLastInsertId.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - public class InsertParam_GetLastInsertId : OrmLiteTestBase - { - [Test] - public void Can_GetLastInsertedId_using_InsertParam() - { - var testObject = new SimpleType { Name = "test" }; - - //verify that "normal" Insert works as expected - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - - con.Insert(testObject); - var normalLastInsertedId = con.LastInsertId(); - Assert.Greater(normalLastInsertedId, 0, "normal Insert"); - } - - //test with InsertParam - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - - var lastInsertId = con.Insert(testObject, selectIdentity:true); - Assert.Greater(lastInsertId, 0, "with InsertParam"); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/NestedTransactions.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/NestedTransactions.cs deleted file mode 100644 index a482853d0..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/NestedTransactions.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - public class NestedTransactions : OrmLiteTestBase - { - /// - /// A demostration, that the ThreadStatic Transaction property can cause problems - /// - [Test] - public void Can_use_nested_transactions() - { - //must use the factory, because that returns an OrmLiteConnection, that can saves the current transaction - var factory = new OrmLiteConnectionFactory(ConnectionString, VistaDbDialect.Provider); - //using(var outerConn = OpenDbConnection()) { - using(var outerConn = factory.OpenDbConnection()) { - //(re)create tables - outerConn.DropAndCreateTable(); - outerConn.DropAndCreateTable(); - - //using(var innerConn = OpenDbConnection()) {//use the factory to get the connections - using(var innerConn = factory.OpenDbConnection()) { - - using(var outerTran = outerConn.OpenTransaction()) { - outerConn.Insert(new Can_use_nested_transactions_Table1 { Dummy = DateTime.Now }); - - using(var innerTran = innerConn.OpenTransaction()) { - //The other transaction inserts into table1, Table2 is not locked - innerConn.Insert(new Can_use_nested_transactions_Table2 { Dummy = DateTime.Now }); - - //fails here, because innerTran has overwritten the ThreadStatic OrmLiteConfig.CurrentTransaction - outerConn.Insert(new Can_use_nested_transactions_Table1 { Dummy = DateTime.Now }); - - outerConn.Insert(new Can_use_nested_transactions_Table1 { Dummy = DateTime.Now }); - } - } - } - } - } - - //two separate tables, so they are not locked - public class Can_use_nested_transactions_Table1 - { - [AutoIncrement] - public int Id { get; set; } - public DateTime Dummy { get; set; } - } - - public class Can_use_nested_transactions_Table2 - { - [AutoIncrement] - public int Id { get; set; } - public DateTime Dummy { get; set; } - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/OrmLiteTestBase.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/OrmLiteTestBase.cs deleted file mode 100644 index 86775cb18..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/OrmLiteTestBase.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Data; -using System.IO; -using NUnit.Framework; -using ServiceStack.Logging; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - public class OrmLiteTestBase - { - protected virtual string ConnectionString { get; set; } - - protected virtual string DataFileName { get; private set; } - - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - LogManager.LogFactory = new ConsoleLogFactory(); - - VistaDbDialect.Provider.UseLibraryFromGac = true; - OrmLiteConfig.DialectProvider = VistaDbDialect.Provider; - - DataFileName = TestVistaDb.ExtractTestDatabaseFileToTempFile(); - - ConnectionString = "Data Source=" + DataFileName + ";"; - } - - [TestFixtureTearDown] - public void TestFixtureTearDown() - { - if (File.Exists(DataFileName)) - File.Delete(DataFileName); - } - - public void Log(string text) - { - Console.WriteLine(text); - } - - public IDbConnection OpenDbConnection(string connString = null) - { - connString = connString ?? ConnectionString; - return connString.OpenDbConnection(); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index d8b6f3d4c..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.VistaDB")] -[assembly: AssemblyDescription("VistaDB provider for ServiceStack.OrmLite micro ORM")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.VistaDB.Tests")] -[assembly: AssemblyCopyright("Copyright 2013 Ilya Lukyanov")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("0657ef05-1cef-458c-9ff9-06584f2def46")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -//[assembly: AssemblyVersion("0.5.0.0")] -//[assembly: AssemblyFileVersion("0.5.0.0")] diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/Resources/test.vdb5 b/src/ServiceStack.OrmLite.VistaDB.Tests/Resources/test.vdb5 deleted file mode 100644 index 7a8dde127..000000000 Binary files a/src/ServiceStack.OrmLite.VistaDB.Tests/Resources/test.vdb5 and /dev/null differ diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/ServiceStack.OrmLite.VistaDB.Tests.csproj b/src/ServiceStack.OrmLite.VistaDB.Tests/ServiceStack.OrmLite.VistaDB.Tests.csproj deleted file mode 100644 index b82c3b4fc..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/ServiceStack.OrmLite.VistaDB.Tests.csproj +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Debug - AnyCPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357} - Library - Properties - ServiceStack.OrmLite.VistaDB.Tests - ServiceStack.OrmLite.VistaDB.Tests - v4.0 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\lib\tests\nunit.framework.dll - - - False - ..\..\lib\ServiceStack.Common.dll - - - False - ..\..\lib\ServiceStack.Interfaces.dll - - - - - - - - - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {d18d9d3c-b3b3-433c-9578-68e978587858} - ServiceStack.OrmLite.VistaDB - - - {96179ac6-f6f1-40c3-9fdd-4f6582f54c5c} - ServiceStack.OrmLite - - - - - - - - PreserveNewest - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/SqlServerExpressionVisitorQueryTest.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/SqlServerExpressionVisitorQueryTest.cs deleted file mode 100644 index 10fc958d0..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/SqlServerExpressionVisitorQueryTest.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.OrmLite.VistaDB.Tests.UseCase; -using System.Data; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - [TestFixture] - public class SqlServerExpressionVisitorQueryTest : OrmLiteTestBase - { - [Test] - public void Skip_Take_works_with_injected_Visitor() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var result = db.Select(q => q.Limit(10, 100)); - - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.Less(10, result[0].Id); - Assert.Greater(111, result[99].Id); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.Less(10, result[0].Id); - Assert.Greater(111, result[99].Id); - } - } - - [Test] - public void test_if_limit_works_with_rows() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(100); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.Less(0, result[0].Id); - Assert.Greater(101, result[99].Id); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip_and_orderby() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - ev.OrderBy(e => e.Baz); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.LessOrEqual(result[10].Baz, result[11].Baz); - } - } - - [Test] - public void test_if_ev_still_works_without_limit_and_orderby() - { - using (var db = OpenDbConnection()) - { - FillTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.OrderBy(e => e.Baz); - ev.Where(e => e.Baz < 0.1m); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.IsTrue(result.Count > 0); - } - } - - [Test] - public void test_if_and_works_with_nullable_parameter() - { - using(var db = OpenDbConnection()) - { - db.CreateTable(true); - db.Insert(new TestEntity - { - Foo = this.RandomString(16), - Bar = this.RandomString(16), - Baz = this.RandomDecimal() - }); - - var id = (int)db.LastInsertId(); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Where(e => e.Id == id); - int? i = null; - ev.And(e => e.NullInt == i); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.IsTrue(result.Count > 0); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip_if_pk_columnname_has_space() - { - using (var db = OpenDbConnection()) - { - FillAliasedTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - } - } - - [Test] - public void test_if_limit_works_with_rows_and_skip_and_orderby_if_pk_columnname_has_space() - { - using (var db = OpenDbConnection()) - { - FillAliasedTestEntityTableWithTestData(db); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Limit(10, 100); - ev.OrderBy(e => e.Baz); - - var result = db.Select(ev); - Assert.NotNull(result); - Assert.AreEqual(100, result.Count); - Assert.LessOrEqual(result[10].Baz, result[11].Baz); - } - } - - protected void FillTestEntityTableWithTestData(IDbConnection db) - { - db.CreateTable(true); - - for (int i = 1; i < 1000; i++) - { - db.Insert(new TestEntity() - { - Foo = RandomString(16), - Bar = RandomString(16), - Baz = RandomDecimal(i) - }); - } - } - - protected void FillAliasedTestEntityTableWithTestData(IDbConnection db) - { - db.CreateTable(true); - - for (int i = 1; i < 1000; i++) - { - db.Insert(new TestEntityWithAliases() - { - Foo = RandomString(16), - Bar = RandomString(16), - Baz = RandomDecimal(i) - }); - } - } - - protected string RandomString(int length) - { - var rnd = new System.Random(); - var buffer = new StringBuilder(); - - for (var i = 0; i < length; i++) - { - buffer.Append(Convert.ToChar(((byte)rnd.Next(254))) - .ToString(CultureInfo.InvariantCulture)); - } - - return buffer.ToString(); - } - - protected decimal RandomDecimal(int seed = 0) - { - var rnd = new Random(seed); - return new decimal(rnd.NextDouble()); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/TestVistaDb.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/TestVistaDb.cs deleted file mode 100644 index fb3d5893b..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/TestVistaDb.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Configuration; -using System.Data; -using System.Data.Common; -using System.IO; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - [TestFixture] - public class TestVistaDb - { - public static string ExtractTestDatabaseFileToTempFile() - { - var dataFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".vdb5"); - - ExtractTestDatabaseFile(dataFileName); - - return dataFileName; - } - - public static void ExtractTestDatabaseFile(string dataFileName) - { - var sourceStream = typeof(OrmLiteTestBase).Assembly - .GetManifestResourceStream("ServiceStack.OrmLite.VistaDB.Tests.Resources.test.vdb5"); - - using (sourceStream) - using (var destStream = File.Create(dataFileName)) - sourceStream.CopyTo(destStream); - } - - public static void CreateDatabase(DbProviderFactory factory) - { - using (var conn = factory.CreateConnection()) - using (var comm = conn.CreateCommand()) - { - comm.CommandText = @"CREATE DATABASE '|DataDirectory|\Database.vdb5', PAGE SIZE 4, LCID 1033, CASE SENSITIVE FALSE;"; - comm.ExecuteNonQuery(); - } - } - - [Test] - public void TestVistaDB() - { - string VersionInfo = null; - for (int i = 0; i < System.Configuration.ConfigurationManager.ConnectionStrings.Count; i++) - { - System.Diagnostics.Debug.WriteLine(System.Configuration.ConfigurationManager.ConnectionStrings[i].ToString()); - } - - string connectionName = "myVDBConnection"; - // Find this connection string in the app.config - System.Configuration.ConnectionStringSettings connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName]; - if (connectionString == null) - { - VersionInfo = "Failed to load connectionString from config file"; - Assert.Fail(VersionInfo); - } - - DbProviderFactory factory = null; - // Loads the factory - try - { - factory = DbProviderFactories.GetFactory(connectionString.ProviderName); - } - catch - { - Assert.Fail("VistaDB library should be copied locally or installed into GAC."); - } - - try - { - CreateDatabase(factory); - } - catch { } - - // After this it looks pretty normal - using (DbConnection connection = factory.CreateConnection()) - { - connection.ConnectionString = connectionString.ConnectionString; - connection.Open(); - using (DbCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT @@VERSION;"; - command.CommandType = CommandType.Text; - - using (DbDataReader reader = command.ExecuteReader()) - { - while (reader.Read()) - { - string result = reader.GetString(0); - if (!reader.IsDBNull(0)) - { - VersionInfo = result; - Assert.True(true, "Connected to: " + VersionInfo); - return; - } - } - } - } - } - VersionInfo = string.Empty; - Assert.Fail("Could not connect to VistaDB"); - } - } - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/TypeWithByteArrayFieldTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/TypeWithByteArrayFieldTests.cs deleted file mode 100644 index 756ee9c8d..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/TypeWithByteArrayFieldTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -using NUnit.Framework; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - public class TypeWithByteArrayFieldTests : OrmLiteTestBase - { - [Test] - public void CanInsertAndSelectByteArray() - { - var orig = new TypeWithByteArrayField { Id = 1, Content = new byte[] { 0, 17, 0, 17, 0, 7 } }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Save(orig); - - var target = db.SingleById(orig.Id); - - Assert.AreEqual(orig.Id, target.Id); - Assert.AreEqual(orig.Content, target.Content); - } - } - } - - class TypeWithByteArrayField - { - public int Id { get; set; } - public byte[] Content { get; set; } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/UnicodeTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/UnicodeTests.cs deleted file mode 100644 index 1278a3b86..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/UnicodeTests.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - /// - /// test for issue #69 - /// - class UnicodeTests : OrmLiteTestBase - { - [Test] - public void can_insert_and_retrieve_unicode_values() - { - //save and restore state, so it doesn't mess with other tests - bool prevUnicodestate = OrmLiteConfig.DialectProvider.UseUnicode; - try { - OrmLiteConfig.DialectProvider.UseUnicode = true; - - var testData = new[]{ - "árvíztűrő tükörfúrógép", - "ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP", //these are the Hungarian "special" characters, they work fine out of the box. At least on Hungarian_Technical_CI_AS - "♪♪♫", //this one comes back as 'ddd' - //greek alphabet - @" -Letter Name Sound value -Ancient[5] Modern[6] -Α α alpha [a] [aː] [a] -Β β beta [b] [v] -Γ γ gamma [ɡ] [ɣ] ~ [ʝ] -Δ δ delta [d] [ð] -Ε ε epsilon [e] [e] -Ζ ζ zeta [zd] (or [dz][7]) [z] -Η η eta [ɛː] [i] -Θ θ theta [tʰ] [θ] -Ι ι iota [i] [iː] [i] -Κ κ kappa [k] [k] ~ [c] -Λ λ lambda [l] [l] -Μ μ mu [m] [m] -Letter Name Sound value -Ancient Modern -Ν ν nu [n] [n] -Ξ ξ xi [ks] [ks] -Ο ο omicron [o] [o] -Π π pi [p] [p] -Ρ ρ rho [r] [r] -Σ σς sigma [s] [s] -Τ τ tau [t] [t] -Υ υ upsilon [y] [yː] [i] -Φ φ phi [pʰ] [f] -Χ χ chi [kʰ] [x] ~ [ç] -Ψ ψ psi [ps] [ps] -Ω ω omega [ɔː] [o] -" - }; - - using(var con = OpenDbConnection()) { - con.ExecuteSql(table_re_creation_script); - - foreach(var item in testData) { con.Insert(new Unicode_poco { Text = item }); } - - var fromDb = con.Select().Select(x => x.Text).ToArray(); - - CollectionAssert.AreEquivalent(testData, fromDb); - } - } - finally { OrmLiteConfig.DialectProvider.UseUnicode = prevUnicodestate; } - } - - - /* * ---if you run this in SSMS, it produces 'ddd' -INSERT INTO [Unicode_poco] ([Text]) VALUES ('hai ♪♪♫') - ---if you run this in SSMS, it works fine -INSERT INTO [Unicode_poco] ([Text]) VALUES (N'hai ♪♪♫') - -select * from Unicode_poco - * */ - - - private class Unicode_poco - { - [PrimaryKey, AutoIncrement] - public int Id { get; set; } - - public string Text { get; set; } - } - - /// - /// because OrmLite does not create nvarchar columns - /// - private string table_re_creation_script = @" -DROP TABLE Unicode_poco; -CREATE TABLE Unicode_poco -( - Id int IDENTITY(1,1) NOT NULL, - [Text] [nvarchar](4000) NULL -);"; - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/UpdateTests.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/UpdateTests.cs deleted file mode 100644 index bb9af60d8..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/UpdateTests.cs +++ /dev/null @@ -1,161 +0,0 @@ -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests -{ - public class UpdateTests : OrmLiteTestBase - { - [Test] - public void Can_execute_update_using_expression() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(con.LastInsertId()); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj, q => q.Id == storedObj.Id); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_update_only() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(con.LastInsertId()); - - Assert.AreEqual(obj.Name, storedObj.Name); - - var ev = OrmLiteConfig.DialectProvider.SqlExpression(); - ev.Update(); - ev.Where(q => q.Id == storedObj.Id); - storedObj.Name = "Someothername"; - - con.UpdateOnly(storedObj, ev); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual("Someothername", target.Name); - } - } - - - [Test] - public void Can_execute_update() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(con.LastInsertId()); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_update_using_aliased_columns() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleAliasedType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(con.LastInsertId()); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_updateParam() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(con.LastInsertId()); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - - [Test] - public void Can_execute_updateParam_using_aliased_columns() - { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - var obj = new SimpleAliasedType { Name = "Somename" }; - con.Save(obj); - var storedObj = con.SingleById(con.LastInsertId()); - - Assert.AreEqual(obj.Name, storedObj.Name); - - obj.Id = storedObj.Id; - obj.Name = "Someothername"; - con.Update(obj); - - var target = con.SingleById(storedObj.Id); - - Assert.AreEqual(obj.Name, target.Name); - } - } - } - - - public class SimpleType - { - [AutoIncrement] - public int Id { get; set; } - public string Name { get; set; } - } - - public class SimpleAliasedType - { - [AutoIncrement] - public int Id { get; set; } - [Alias("NewName")] - public string Name { get; set; } - - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/SimpleUseCase.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/SimpleUseCase.cs deleted file mode 100644 index b3898b83a..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/SimpleUseCase.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using NUnit.Framework; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests.UseCase -{ - [TestFixture, NUnit.Framework.Ignore] - public class SimpleUseCase - { - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - //Inject your database provider here - OrmLiteConfig.DialectProvider = new VistaDbDialectProvider(); - } - - public class User - { - public long Id { get; set; } - - [Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - - public bool IsAdmin { get; set; } - } - - public class Dual - { - [AutoIncrement] - public int Id { get; set; } - - public string Name { get; set; } - } - - [Test] - public void Simple_CRUD_example() - { - //using (IDbConnection db = ":memory:".OpenDbConnection()) - - var connStr = ConfigurationManager.ConnectionStrings["TestDb"].ConnectionString; - var sqlServerFactory = new OrmLiteConnectionFactory(connStr, VistaDbDialectProvider.Instance); - - using (IDbConnection db = sqlServerFactory.OpenDbConnection()) - { - db.CreateTable(true); - db.CreateTable(true); - - db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now }); - db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); - db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now, IsAdmin = true}); - - db.Insert(new Dual { Name = "Dual" }); - var lastInsertId = db.LastInsertId(); - Assert.That(lastInsertId, Is.GreaterThan(0)); - - var rowsB = db.SelectFmt("Name = {0}", "B"); - - Assert.That(rowsB, Has.Count.EqualTo(2)); - - var admin = db.SelectFmt("IsAdmin = {0}", true); - Assert.That(admin[0].Id, Is.EqualTo(3)); - - var rowIds = rowsB.ConvertAll(x => x.Id); - Assert.That(rowIds, Is.EquivalentTo(new List { 2, 3 })); - - rowsB.ForEach(x => db.Delete(x)); - - rowsB = db.SelectFmt("Name = {0}", "B"); - Assert.That(rowsB, Has.Count.EqualTo(0)); - - var rowsLeft = db.Select(); - Assert.That(rowsLeft, Has.Count.EqualTo(1)); - - Assert.That(rowsLeft[0].Name, Is.EqualTo("A")); - } - } - - } - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/TestEntity.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/TestEntity.cs deleted file mode 100644 index a1205234c..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/TestEntity.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests.UseCase -{ - public class TestEntity - { - #region Properties - - [AutoIncrement] - public int Id { get; set; } - - public String Foo { get; set; } - public String Bar { get; set; } - public int? NullInt { get; set; } - - [Index] - public Decimal Baz { get; set; } - - #endregion - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/TestEntityWithAliases.cs b/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/TestEntityWithAliases.cs deleted file mode 100644 index ac3541e24..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/UseCase/TestEntityWithAliases.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB.Tests.UseCase -{ - public class TestEntityWithAliases - { - #region Properties - - [AutoIncrement] - [Alias("Id Column")] - public int Id { get; set; } - - [Alias("Foo Column")] - public String Foo { get; set; } - - [Alias("Bar Column")] - public String Bar { get; set; } - - //[Index] - [Alias("Baz Column")] - public Decimal Baz { get; set; } - - #endregion - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB.Tests/VistaDB5.playlist b/src/ServiceStack.OrmLite.VistaDB.Tests/VistaDB5.playlist deleted file mode 100644 index d8bbbd418..000000000 --- a/src/ServiceStack.OrmLite.VistaDB.Tests/VistaDB5.playlist +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbCommand.cs b/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbCommand.cs deleted file mode 100644 index c7f180ce4..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbCommand.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Data; - -namespace ServiceStack.OrmLite.VistaDB -{ - public class OrmLiteVistaDbCommand : IDbCommand - { - public IDbCommand VistaDbCommand { get; private set; } - - private OrmLiteVistaDbConnection connectionWrapper; - private OrmLiteVistaDbTransaction transactionWrapper; - - public OrmLiteVistaDbCommand(OrmLiteVistaDbConnection connectionWrapper, IDbCommand vistaDbCommand) - { - if (connectionWrapper == null) - throw new ArgumentNullException("connectionWrapper"); - - if (vistaDbCommand == null) - throw new ArgumentNullException("vistaDbCommand"); - - this.connectionWrapper = connectionWrapper; - - this.VistaDbCommand = vistaDbCommand; - this.Parameters = new OrmLiteVistaDbParameterCollection(vistaDbCommand.Parameters); - } - - public void Cancel() - { - this.VistaDbCommand.Cancel(); - } - - public string CommandText - { - get { return this.VistaDbCommand.CommandText; } - set { this.VistaDbCommand.CommandText = value; } - } - - public int CommandTimeout - { - get { return this.VistaDbCommand.CommandTimeout; } - set { this.VistaDbCommand.CommandTimeout = value; } - } - - public CommandType CommandType - { - get { return this.VistaDbCommand.CommandType; } - set { this.VistaDbCommand.CommandType = value; } - } - - public IDbConnection Connection - { - get { return connectionWrapper; } - set - { - connectionWrapper = (OrmLiteVistaDbConnection)value; - this.VistaDbCommand.Connection = connectionWrapper.VistaDbConnection; - } - } - - public IDbDataParameter CreateParameter() - { - var vistaDbParameter = this.VistaDbCommand.CreateParameter(); - - return new OrmLiteVistaDbParameter(vistaDbParameter); - } - - public int ExecuteNonQuery() - { - return this.VistaDbCommand.ExecuteNonQuery(); - } - - public IDataReader ExecuteReader(CommandBehavior behavior) - { - return this.VistaDbCommand.ExecuteReader(behavior); - } - - public IDataReader ExecuteReader() - { - return this.VistaDbCommand.ExecuteReader(); - } - - public object ExecuteScalar() - { - return this.VistaDbCommand.ExecuteScalar(); - } - - public IDataParameterCollection Parameters { get; private set; } - - public void Prepare() - { - this.VistaDbCommand.Prepare(); - } - - public IDbTransaction Transaction - { - get - { - return transactionWrapper; - } - set - { - transactionWrapper = (OrmLiteVistaDbTransaction)value; - - if (transactionWrapper != null) - this.VistaDbCommand.Transaction = transactionWrapper.VistaDbTransaction; - } - } - - public UpdateRowSource UpdatedRowSource - { - get { return this.VistaDbCommand.UpdatedRowSource; } - set { this.VistaDbCommand.UpdatedRowSource = value; } - } - - public void Dispose() - { - this.VistaDbCommand.Dispose(); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbConnection.cs b/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbConnection.cs deleted file mode 100644 index f5dde6e21..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbConnection.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Data; - -namespace ServiceStack.OrmLite.VistaDB -{ - public class OrmLiteVistaDbConnection : IDbConnection, ICloneable - { - public IDbConnection VistaDbConnection { get; private set; } - - public OrmLiteVistaDbConnection(IDbConnection conn) - { - if (conn == null) - throw new ArgumentNullException("conn"); - - VistaDbConnection = conn; - } - - public IDbTransaction BeginTransaction(IsolationLevel il) - { - //VistaDB 4 supports only ReadCommited isolation level - if (il != IsolationLevel.Unspecified && il != IsolationLevel.ReadCommitted) - il = IsolationLevel.ReadCommitted; - - var tn = VistaDbConnection.BeginTransaction(il); - return new OrmLiteVistaDbTransaction(this, tn); - } - - public IDbTransaction BeginTransaction() - { - var tn = this.VistaDbConnection.BeginTransaction(); - - return new OrmLiteVistaDbTransaction(this, tn); - } - - public void ChangeDatabase(string databaseName) - { - VistaDbConnection.ChangeDatabase(databaseName); - } - - public void Close() - { - VistaDbConnection.Close(); - } - - public string ConnectionString - { - get { return VistaDbConnection.ConnectionString; } - set { VistaDbConnection.ConnectionString = value; } - } - - public int ConnectionTimeout - { - get { return VistaDbConnection.ConnectionTimeout; } - } - - public IDbCommand CreateCommand() - { - var cmd = VistaDbConnection.CreateCommand(); - - return new OrmLiteVistaDbCommand(this, cmd); - } - - public string Database - { - get { return VistaDbConnection.Database; } - } - - public void Open() - { - VistaDbConnection.Open(); - } - - public ConnectionState State - { - get { return VistaDbConnection.State; } - } - - public void Dispose() - { - VistaDbConnection.Dispose(); - } - - public object Clone() - { - var cloneable = (ICloneable) VistaDbConnection; - var conn = (IDbConnection) cloneable.Clone(); - - return new OrmLiteVistaDbConnection(conn); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbParameter.cs b/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbParameter.cs deleted file mode 100644 index 5a27386d8..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbParameter.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Data; - -namespace ServiceStack.OrmLite.VistaDB -{ - public class OrmLiteVistaDbParameter : IDbDataParameter - { - private object _backgroundValue; - - public IDbDataParameter VistaDbParameter { get; private set; } - - internal OrmLiteVistaDbParameter(IDbDataParameter vistaDbParameter) - { - if (vistaDbParameter == null) - throw new ArgumentNullException("vistaDbParameter"); - - this.VistaDbParameter = vistaDbParameter; - - _backgroundValue = vistaDbParameter.Value; - } - - public byte Precision - { - get { return this.VistaDbParameter.Precision; } - set { this.VistaDbParameter.Precision = value; } - } - - public byte Scale - { - get { return this.VistaDbParameter.Scale; } - set { this.VistaDbParameter.Scale = value; } - } - - public int Size - { - get { return this.VistaDbParameter.Size; } - set { this.VistaDbParameter.Size = value; } - } - - public DbType DbType - { - get { return this.VistaDbParameter.DbType; } - set { this.VistaDbParameter.DbType = value; } - } - - public ParameterDirection Direction - { - get { return this.VistaDbParameter.Direction; } - set { this.VistaDbParameter.Direction = value; } - } - - public bool IsNullable { get { return this.VistaDbParameter.IsNullable; } } - - public string ParameterName - { - get { return this.VistaDbParameter.ParameterName; } - set { this.VistaDbParameter.ParameterName = value; } - } - - public string SourceColumn - { - get { return this.VistaDbParameter.SourceColumn; } - set { this.VistaDbParameter.SourceColumn = value; } - } - - public DataRowVersion SourceVersion - { - get { return this.VistaDbParameter.SourceVersion; } - set { this.VistaDbParameter.SourceVersion = value; } - } - - public object Value - { - get { return _backgroundValue; } - set - { - _backgroundValue = value; - - var vistaDbValue = value; ; - if (vistaDbValue != null && vistaDbValue.GetType().IsEnum) - vistaDbValue = vistaDbValue.ToString(); - - this.VistaDbParameter.Value = vistaDbValue; - } - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbParameterCollection.cs b/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbParameterCollection.cs deleted file mode 100644 index eedbd556c..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbParameterCollection.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Data; - -namespace ServiceStack.OrmLite.VistaDB -{ - public class OrmLiteVistaDbParameterCollection : IDataParameterCollection - { - private readonly OrderedDictionary parameters; - - public IDataParameterCollection VistaDbParameterCollection { get; private set; } - - public OrmLiteVistaDbParameterCollection(IDataParameterCollection vistaDbParameterCollection) - { - if (vistaDbParameterCollection == null) - throw new ArgumentNullException("vistaDbParameterCollection"); - - this.VistaDbParameterCollection = vistaDbParameterCollection; - - parameters = new OrderedDictionary(StringComparer.InvariantCultureIgnoreCase); - } - - public bool Contains(string parameterName) - { - return this.VistaDbParameterCollection.Contains(parameterName); - } - - public int IndexOf(string parameterName) - { - return this.VistaDbParameterCollection.IndexOf(parameterName); - } - - public void RemoveAt(string parameterName) - { - this.VistaDbParameterCollection.RemoveAt(parameterName); - parameters.Remove(parameterName); - } - - public object this[string parameterName] - { - get - { - return parameters[parameterName]; - } - set - { - var parameter = (OrmLiteVistaDbParameter)value; - - this.VistaDbParameterCollection[parameterName] = parameter.VistaDbParameter; - parameters[parameterName] = parameter; - } - } - - public int Add(object value) - { - var parameter = (OrmLiteVistaDbParameter)value; - - parameters[parameter.ParameterName] = parameter; - - return this.VistaDbParameterCollection.Add(parameter.VistaDbParameter); - } - - public void Clear() - { - parameters.Clear(); - - this.VistaDbParameterCollection.Clear(); - } - - public bool Contains(object value) - { - var parameter = (OrmLiteVistaDbParameter)value; - - return this.VistaDbParameterCollection.Contains(parameter.VistaDbParameter); - } - - public int IndexOf(object value) - { - var parameter = (OrmLiteVistaDbParameter)value; - - return this.VistaDbParameterCollection.IndexOf(parameter.VistaDbParameter); - } - - public void Insert(int index, object value) - { - var parameter = (OrmLiteVistaDbParameter)value; - - parameters.Insert(index, parameter.ParameterName, parameter); - this.VistaDbParameterCollection.Insert(index, parameter.VistaDbParameter); - } - - public bool IsFixedSize { get { return this.VistaDbParameterCollection.IsFixedSize; } } - - public bool IsReadOnly { get { return this.VistaDbParameterCollection.IsReadOnly; } } - - public void Remove(object value) - { - var parameter = (OrmLiteVistaDbParameter)value; - - parameters.Remove(parameter); - this.VistaDbParameterCollection.Remove(parameter.VistaDbParameter); - } - - public void RemoveAt(int index) - { - parameters.RemoveAt(index); - - this.VistaDbParameterCollection.RemoveAt(index); - } - - public object this[int index] - { - get - { - return parameters[index]; - } - set - { - var parameter = (OrmLiteVistaDbParameter)value; - - parameters[index] = parameter; - this.VistaDbParameterCollection[index] = parameter.VistaDbParameter; - } - } - - public void CopyTo(Array array, int index) - { - this.VistaDbParameterCollection.CopyTo(array, index); - } - - public int Count { get { return this.VistaDbParameterCollection.Count; } } - - public bool IsSynchronized { get { return this.VistaDbParameterCollection.IsSynchronized; } } - - public object SyncRoot { get { return this.VistaDbParameterCollection.SyncRoot; } } - - public IEnumerator GetEnumerator() - { - return parameters.Values.GetEnumerator(); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbTransaction.cs b/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbTransaction.cs deleted file mode 100644 index 101f27990..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/OrmLiteVistaDbTransaction.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Data; - -namespace ServiceStack.OrmLite.VistaDB -{ - public class OrmLiteVistaDbTransaction : IDbTransaction - { - public IDbTransaction VistaDbTransaction { get; private set; } - - private bool finalized, disposed; - - public OrmLiteVistaDbTransaction(OrmLiteVistaDbConnection connectionWrapper, IDbTransaction transaction) - { - if (connectionWrapper == null) - throw new ArgumentNullException("connectionWrapper"); - - if (transaction == null) - throw new ArgumentNullException("transaction"); - - finalized = disposed = false; - - this.Connection = connectionWrapper; - this.VistaDbTransaction = transaction; - } - - public void Commit() - { - this.VistaDbTransaction.Commit(); - finalized = true; - } - - public IDbConnection Connection { get; private set; } - - public IsolationLevel IsolationLevel { get { return this.VistaDbTransaction.IsolationLevel; } } - - public void Rollback() - { - this.VistaDbTransaction.Rollback(); - finalized = true; - } - - public void Dispose() - { - if (!finalized && !disposed) - { - try - { - this.Rollback(); - this.Connection = null; - disposed = true; - } - catch { } - } - - this.VistaDbTransaction.Dispose(); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite.VistaDB/Properties/AssemblyInfo.cs deleted file mode 100644 index e2cf0765b..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.VistaDB")] -[assembly: AssemblyDescription("VistaDB provider for ServiceStack.OrmLite micro ORM")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.VistaDB")] -[assembly: AssemblyCopyright("Copyright 2013 Ilya Lukyanov")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("0657ef05-1cef-458c-9ff9-06584f2def46")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.5.0.0")] -[assembly: AssemblyFileVersion("0.5.0.0")] diff --git a/src/ServiceStack.OrmLite.VistaDB/ReflectionBasedDialectProvider.cs b/src/ServiceStack.OrmLite.VistaDB/ReflectionBasedDialectProvider.cs deleted file mode 100644 index 2d38c7351..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/ReflectionBasedDialectProvider.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Reflection; - -namespace ServiceStack.OrmLite.VistaDB -{ - public abstract class ReflectionBasedDialectProvider : OrmLiteDialectProviderBase - where T: IOrmLiteDialectProvider - { - private Lazy _connectionType; - - private AssemblyName _assemblyGacName; - private AssemblyName _assemblyLocalName; - private string _providerTypeName; - - protected ReflectionBasedDialectProvider() - { - _connectionType = new Lazy(LoadAssemblyAndGetType); - } - - protected abstract AssemblyName DefaultAssemblyGacName { get; } - - protected abstract AssemblyName DefaultAssemblyLocalName { get; } - - protected abstract string DefaultProviderTypeName { get; } - - protected Type ConnectionType { get { return _connectionType.Value; } } - - public bool UseLibraryFromGac { get; set; } - - public AssemblyName AssemblyGacName - { - get - { - if (_assemblyGacName == null) - _assemblyGacName = DefaultAssemblyGacName; - - return _assemblyGacName; - } - set - { - SetValueSafe(value, v => _assemblyGacName = v); - } - } - - public AssemblyName AssemblyLocalName - { - get - { - if (_assemblyLocalName == null) - _assemblyLocalName = DefaultAssemblyLocalName; - - return _assemblyLocalName; - } - set - { - SetValueSafe(value, v => _assemblyLocalName = v); - } - } - - public string ProviderTypeName - { - get - { - if (_providerTypeName == null) - _providerTypeName = DefaultProviderTypeName; - - return _providerTypeName; - } - set - { - SetValueSafe(value, v => _providerTypeName = v); - } - } - - protected Type LoadAssemblyAndGetType() - { - var assemblyName = this.UseLibraryFromGac - ? this.AssemblyGacName - : this.AssemblyLocalName; - - var assembly = Assembly.Load(assemblyName); - - return assembly.GetType(this.ProviderTypeName, true); - } - - protected virtual IDbConnection ActivateDbConnection(string connectionString) - { - var conn = Activator.CreateInstance(this.ConnectionType) as IDbConnection; - conn.ConnectionString = connectionString; - - return conn; - } - - public override IDbConnection CreateConnection(string connectionString, Dictionary options) - { - return this.ActivateDbConnection(connectionString); - } - - private static void ThrowUnableToChangeProperty() - { - throw new InvalidOperationException("This property should only be set before the first time a connection is created"); - } - - private void SetValueSafe(TValue value, Action action) - where TValue: class - { - if (_connectionType.IsValueCreated) - ThrowUnableToChangeProperty(); - - action.Invoke(value); - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/ServiceStack.OrmLite.VistaDB.csproj b/src/ServiceStack.OrmLite.VistaDB/ServiceStack.OrmLite.VistaDB.csproj deleted file mode 100644 index 1c6d2c191..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/ServiceStack.OrmLite.VistaDB.csproj +++ /dev/null @@ -1,73 +0,0 @@ - - - - - Debug - AnyCPU - {D18D9D3C-B3B3-433C-9578-68E978587858} - Library - Properties - ServiceStack.OrmLite.VistaDB - ServiceStack.OrmLite.VistaDB - v4.0 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - - - - - - - - - - {96179ac6-f6f1-40c3-9fdd-4f6582f54c5c} - ServiceStack.OrmLite - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.VistaDB/VistaDBExpression.cs b/src/ServiceStack.OrmLite.VistaDB/VistaDBExpression.cs deleted file mode 100644 index 193e6afea..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/VistaDBExpression.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Linq; -using System.Text; -using System.Linq.Expressions; - -namespace ServiceStack.OrmLite.VistaDB -{ - public class VistaDbExpression : SqlExpression - { - public VistaDbExpression(IOrmLiteDialectProvider dialectProvider) - : base(dialectProvider) {} - - public override string ToUpdateStatement(T item, bool excludeDefaults = false) - { - var setFields = new StringBuilder(); - var dialectProvider = OrmLiteConfig.DialectProvider; - - foreach (var fieldDef in ModelDef.FieldDefinitions) - { - if (UpdateFields.Count > 0 && !UpdateFields.Contains(fieldDef.Name) || fieldDef.AutoIncrement) - continue; // added - - var value = fieldDef.GetValue(item); - if (excludeDefaults && (value == null || value.Equals(value.GetType().GetDefaultValue()))) - continue; //GetDefaultValue? - - fieldDef.GetQuotedValue(item); - - if (setFields.Length > 0) setFields.Append(","); - setFields.AppendFormat("{0} = {1}", - dialectProvider.GetQuotedColumnName(fieldDef.FieldName), - dialectProvider.GetQuotedValue(value, fieldDef.FieldType)); - } - - return string.Format("UPDATE {0} SET {1} {2}", - dialectProvider.GetQuotedTableName(ModelDef), setFields, WhereExpression); - } - - protected override object VisitColumnAccessMethod(MethodCallExpression m) - { - if (m.Arguments.Count == 1 && m.Method.Name == "Equals") - { - return Visit( - Expression.Equal( - Expression.Convert(m.Object, typeof(object)), - Expression.Convert(m.Arguments.First(), typeof(object)))); - } - else - { - return base.VisitColumnAccessMethod(m); - } - } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/VistaDbDialect.cs b/src/ServiceStack.OrmLite.VistaDB/VistaDbDialect.cs deleted file mode 100644 index 0420272fa..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/VistaDbDialect.cs +++ /dev/null @@ -1,9 +0,0 @@ -using ServiceStack.OrmLite.VistaDB; - -namespace ServiceStack.OrmLite -{ - public static class VistaDbDialect - { - public static VistaDbDialectProvider Provider { get { return VistaDbDialectProvider.Instance; } } - } -} diff --git a/src/ServiceStack.OrmLite.VistaDB/VistaDbDialectProvider.cs b/src/ServiceStack.OrmLite.VistaDB/VistaDbDialectProvider.cs deleted file mode 100644 index 87d69413e..000000000 --- a/src/ServiceStack.OrmLite.VistaDB/VistaDbDialectProvider.cs +++ /dev/null @@ -1,500 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Globalization; -using System.IO; -using System.Reflection; -using System.Text; -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.VistaDB -{ - public class VistaDbDialectProvider : ReflectionBasedDialectProvider - { - const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; - - public static VistaDbDialectProvider Instance = new VistaDbDialectProvider(); - - private static DateTime timeSpanOffset = new DateTime(1900, 01, 01); - - protected override AssemblyName DefaultAssemblyGacName - { - get { return new AssemblyName("VistaDB.5.NET40, Version=5.0.0.0, Culture=neutral, PublicKeyToken=dfc935afe2125461"); } - } - - protected override AssemblyName DefaultAssemblyLocalName { get { return new AssemblyName("VistaDB.5.NET40"); } } - - protected override string DefaultProviderTypeName { get { return "VistaDB.Provider.VistaDBConnection"; } } - - public string RowVersionTriggerFormat { get; set; } - - public VistaDbDialectProvider() - { - this.RowVersionTriggerFormat = "{0}RowVersionUpdateTrigger"; - - base.AutoIncrementDefinition = "IDENTITY(1,1)"; - base.SelectIdentitySql = "SELECT @@IDENTITY"; - base.GuidColumnDefinition = "UniqueIdentifier"; - base.RealColumnDefinition = "FLOAT"; - base.BoolColumnDefinition = "BIT"; - base.BlobColumnDefinition = "VARBINARY(MAX)"; - base.IntColumnDefinition = "INT"; - base.DefaultValueFormat = " DEFAULT {0}"; - base.TimeColumnDefinition = "BIGINT"; //TIME"; //SQLSERVER 2008+ - base.MaxStringColumnDefinition = "VARCHAR(MAX)"; - - base.InitColumnTypeMap(); - } - - public override void OnAfterInitColumnTypeMap() - { - DbTypeMap.Set(DbType.DateTime, TimeColumnDefinition); - DbTypeMap.Set(DbType.DateTime, TimeColumnDefinition); - } - - public override string GetQuotedValue(string paramValue) - { - return (this.UseUnicode ? "N'" : "'") + paramValue.Replace("'", "''") + "'"; - } - - public override void SetParameterValues(IDbCommand dbCmd, object obj) - { - base.SetParameterValues(dbCmd, obj); - - foreach (IDbDataParameter p in dbCmd.Parameters) - { - var newName = p.ParameterName.Replace(" ", "___"); - dbCmd.CommandText = dbCmd.CommandText.Replace(p.ParameterName, newName); - - p.ParameterName = newName; - } - } - - public override IDbConnection CreateConnection(string connectionString, Dictionary options) - { - var isFullConnectionString = connectionString.Contains(";"); - - if (!isFullConnectionString) - { - var filePath = connectionString; - var filePathWithExt = filePath.ToLower().EndsWith(".vdb5") - ? filePath - : filePath + ".vdb5"; - - var fileName = Path.GetFileName(filePathWithExt); - - connectionString = string.Format(@"Data Source={0};Open Mode=NonExclusiveReadWrite;", filePathWithExt); - } - - if (options != null) - { - foreach (var option in options) - connectionString += option.Key + "=" + option.Value + ";"; - } - - return new OrmLiteVistaDbConnection( - base.CreateConnection(connectionString, options)); - } - - public override string ToCreateTableStatement(Type tableType) - { - var modelDefinition = OrmLiteUtils.GetModelDefinition(tableType); - var quotedTableName = this.GetQuotedTableName(modelDefinition); - - var columns = new StringBuilder(); - var constraints = new StringBuilder(); - - foreach (var fd in modelDefinition.FieldDefinitions) - { - if (columns.Length != 0) - columns.Append(", \n "); - - var columnDefinition = this.GetColumnDefinition( - fd.FieldName, - fd.FieldType, - false, - fd.AutoIncrement, - fd.IsNullable, - fd.IsRowVersion, - fd.FieldLength, - null, - fd.DefaultValue, - fd.CustomFieldDefinition); - - columns.Append(columnDefinition); - - if (fd.IsPrimaryKey) - { - constraints.AppendFormat("ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY ({2});\n", - quotedTableName, - this.GetQuotedName("PK_" + modelDefinition.ModelName), - this.GetQuotedColumnName(fd.FieldName)); - } - else if (fd.ForeignKey != null) - { - var foreignModelDefinition = OrmLiteUtils.GetModelDefinition(fd.ForeignKey.ReferenceType); - constraints.AppendFormat("ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}){5}{6};\n", - quotedTableName, - this.GetQuotedName(fd.ForeignKey.GetForeignKeyName(modelDefinition, foreignModelDefinition, this.NamingStrategy, fd)), - this.GetQuotedColumnName(fd.FieldName), - this.GetQuotedTableName(foreignModelDefinition), - this.GetQuotedColumnName(foreignModelDefinition.PrimaryKey.FieldName), - this.GetForeignKeyOnDeleteClause(fd.ForeignKey), - this.GetForeignKeyOnUpdateClause(fd.ForeignKey)); - } - } - - return String.Format("CREATE TABLE {0} \n(\n {1} \n); \n {2}\n", - quotedTableName, - columns, - constraints); - } - - public override string GetColumnDefinition(string fieldName, Type fieldType, - bool isPrimaryKey, bool autoIncrement, bool isNullable, bool isRowVersion, - int? fieldLength, int? scale, string defaultValue, string customFieldDefinition) - { - string fieldDefinition; - if (fieldType == typeof (string)) - { - fieldDefinition = fieldLength == StringLengthAttribute.MaxText - ? MaxStringColumnDefinition - : string.Format(StringLengthColumnDefinitionFormat, fieldLength.GetValueOrDefault(DefaultStringLength)); - } - else if (!this.DbTypeMap.ColumnTypeMap.TryGetValue(fieldType, out fieldDefinition)) - { - fieldDefinition = this.GetUndefinedColumnDefinition(fieldType, fieldLength); - } - - var sql = new StringBuilder(); - sql.AppendFormat("{0} {1}", this.GetQuotedColumnName(fieldName), fieldDefinition); - if (isPrimaryKey) - { - sql.Append(" PRIMARY KEY"); - } - else - { - if (isNullable && !autoIncrement) - sql.Append(" NULL"); - else - sql.Append(" NOT NULL"); - } - - if (autoIncrement) - sql.Append(" ").Append(this.AutoIncrementDefinition); - - if (!String.IsNullOrEmpty(defaultValue)) - sql.AppendFormat(this.DefaultValueFormat, defaultValue); - - return sql.ToString(); - } - - public override string ToExistStatement(Type fromTableType, object objWithProperties, string sqlFilter, params object[] filterParams) - { - var fromModelDef = GetModel(fromTableType); - - var sql = new StringBuilder(); - sql.AppendFormat("SELECT 1 \nFROM {0}", this.GetQuotedTableName(fromModelDef)); - - var filter = new StringBuilder(); - - if (objWithProperties != null) - { - var tableType = objWithProperties.GetType(); - - if (fromTableType != tableType) - { - int i = 0; - var fpk = new List(); - var modelDef = GetModel(tableType); - - foreach (var def in modelDef.FieldDefinitions) - { - if (def.IsPrimaryKey) - fpk.Add(def); - } - - foreach (var fieldDef in fromModelDef.FieldDefinitions) - { - if (fieldDef.IsComputed || fieldDef.ForeignKey == null) - continue; - - var model = GetModel(fieldDef.ForeignKey.ReferenceType); - if (model.ModelName != modelDef.ModelName) - continue; - - if (filter.Length > 0) - filter.Append(" AND "); - - filter.AppendFormat("{0} = {1}", GetQuotedColumnName(fieldDef.FieldName), fpk[i++].GetQuotedValue(objWithProperties)); - } - } - else - { - var modelDef = GetModel(tableType); - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.IsComputed || !fieldDef.IsPrimaryKey) - continue; - - if (filter.Length > 0) - filter.Append(" AND "); - - filter.AppendFormat("{0} = {1}", - GetQuotedColumnName(fieldDef.FieldName), fieldDef.GetQuotedValue(objWithProperties)); - } - } - - if (filter.Length > 0) - sql.AppendFormat("\nWHERE {0} ", filter); - } - - if (!string.IsNullOrEmpty(sqlFilter)) - { - sqlFilter = sqlFilter.SqlFmt(filterParams); - sql.Append(filter.Length > 0 ? " AND " : "\nWHERE "); - sql.Append(sqlFilter); - } - - return String.Format("SELECT EXISTS({0});", sql); - } - - public override object ConvertDbValue(object value, Type type) - { - if (value == null || value is DBNull) - return null; - - if (type == typeof(bool) && !(value is bool)) - { - var intVal = Convert.ToInt32(value.ToString()); - return intVal != 0; - } - - if (type == typeof(TimeSpan) && value is DateTime) - { - var dateTimeValue = (DateTime)value; - return dateTimeValue - timeSpanOffset; - } - - if (type == typeof(byte[])) - return value; - - return base.ConvertDbValue(value, type); - } - - public override string GetQuotedValue(object value, Type fieldType) - { - if (value == null) - return "NULL"; - - if (fieldType == typeof(Guid)) - return string.Format("CAST('{0}' AS UNIQUEIDENTIFIER)", (Guid)value); - - if (fieldType == typeof(DateTime)) - { - var dateValue = (DateTime)value; - - return base.GetQuotedValue(dateValue.ToString(dateTimeFormat, CultureInfo.InvariantCulture), typeof(string)); - } - if (fieldType == typeof(DateTimeOffset)) - { - var dateValue = (DateTimeOffset)value; - - return base.GetQuotedValue(dateValue.ToString(dateTimeFormat, CultureInfo.InvariantCulture), typeof(string)); - } - - if (fieldType == typeof(bool)) - return base.GetQuotedValue((bool)value ? 1 : 0, typeof(int)); - - if (fieldType == typeof(string)) - return GetQuotedValue(value.ToString()); - - if (fieldType == typeof(byte[])) - return "0x" + BitConverter.ToString((byte[])value).Replace("-", ""); - - return base.GetQuotedValue(value, fieldType); - } - - public override SqlExpression SqlExpression() - { - return new VistaDbExpression(this); - } - - public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) - { - dbCmd.CommandText = "SELECT COUNT(*) FROM [database schema] WHERE typeid = 1 AND name = {0}" - .SqlFmt(tableName); - - return dbCmd.LongScalar() > 0; - } - - public override void UpdateStringColumnDefinitions() - { - if (base.useUnicode && this.DefaultStringLength > 4000) - this.DefaultStringLength = 4000; - - base.UpdateStringColumnDefinitions(); - } - - public override string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignKey) - { - return String.Equals("RESTRICT", foreignKey.OnDelete, StringComparison.OrdinalIgnoreCase) - ? String.Empty - : base.GetForeignKeyOnDeleteClause(foreignKey); - } - - public override string GetForeignKeyOnUpdateClause(ForeignKeyConstraint foreignKey) - { - return String.Equals("RESTRICT", foreignKey.OnUpdate, StringComparison.OrdinalIgnoreCase) - ? String.Empty - : base.GetForeignKeyOnUpdateClause(foreignKey); - } - - public override string GetDropForeignKeyConstraints(ModelDefinition modelDef) - { - var sb = new StringBuilder(); - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.ForeignKey != null) - { - var foreignKeyName = fieldDef.ForeignKey.GetForeignKeyName( - modelDef, - OrmLiteUtils.GetModelDefinition(fieldDef.ForeignKey.ReferenceType), - NamingStrategy, - fieldDef); - - var tableName = GetQuotedTableName(modelDef); - sb.AppendFormat("IF EXISTS (SELECT name FROM [database schema] WHERE typeid = 7 AND name = '{0}')\n", foreignKeyName); - sb.AppendLine("BEGIN"); - sb.AppendFormat(" ALTER TABLE {0} DROP {1};\n", tableName, foreignKeyName); - sb.AppendLine("END"); - } - } - - return sb.ToString(); - } - - public override string ToAddColumnStatement(Type modelType, FieldDefinition fieldDef) - { - var column = GetColumnDefinition( - fieldDef.FieldName, - fieldDef.FieldType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - - return string.Format("ALTER TABLE {0} ADD {1};", - GetQuotedTableName(GetModel(modelType).ModelName), - column); - } - - public override string ToAlterColumnStatement(Type modelType, FieldDefinition fieldDef) - { - var column = GetColumnDefinition( - fieldDef.FieldName, - fieldDef.FieldType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - - return string.Format("ALTER TABLE {0} ALTER COLUMN {1};", - GetQuotedTableName(GetModel(modelType).ModelName), - column); - } - - public override string ToChangeColumnNameStatement(Type modelType, FieldDefinition fieldDef, string oldColumnName) - { - var objectName = string.Format("{0}.{1}", - NamingStrategy.GetTableName(GetModel(modelType).ModelName), - oldColumnName); - - return string.Format("sp_rename ({0}, {1}, {2});", - GetQuotedValue(objectName), - GetQuotedValue(fieldDef.FieldName), - GetQuotedValue("COLUMN")); - } - - /// Limit/Offset paging logic needs to be implemented here: - public override string ToSelectStatement( - ModelDefinition modelDef, string selectExpression, string bodyExpression, string orderByExpression = null, int? offset = null, int? rows = null) - { - var sb = new StringBuilder(selectExpression); - sb.Append(bodyExpression); - - var hasOrderBy = !String.IsNullOrWhiteSpace(orderByExpression); - - var skip = offset.GetValueOrDefault(); - if ((skip > 0 || rows.HasValue) && !hasOrderBy) - { - hasOrderBy = true; - //Ordering by the first column in select list - orderByExpression = "\nORDER BY 1"; - } - - if (hasOrderBy) - sb.Append(orderByExpression); - - if (skip > 0) - sb.Append(this.GetPagingOffsetExpression(skip)); - - if (rows.HasValue) - { - if (skip == 0) - sb.Append(this.GetPagingOffsetExpression(0)); - - sb.Append(this.GetPagingFetchExpression(rows.Value)); - } - - return sb.ToString(); - } - - protected virtual string GetPagingOffsetExpression(int rows) - { - return String.Format("\nOFFSET {0} ROWS", rows); - } - - protected virtual string GetPagingFetchExpression(int rows) - { - return String.Format("\nFETCH NEXT {0} ROWS ONLY", rows); - } - - //should create CLR-trigger assembly - /*public override string ToPostDropTableStatement(ModelDefinition modelDef) - { - if (modelDef.RowVersion != null) - { - var triggerName = RowVersionTriggerFormat.Fmt(modelDef.ModelName); - return "DROP TRIGGER IF EXISTS {0}".Fmt(GetQuotedTableName(triggerName)); - } - - return null; - } - - public override string ToPostCreateTableStatement(ModelDefinition modelDef) - { - if (modelDef.RowVersion != null) - { - var triggerName = RowVersionTriggerFormat.Fmt(modelDef.ModelName); - var triggerBody = "SET NEW.{0} = OLD.{0} + 1;".Fmt( - modelDef.RowVersion.FieldName.SqlColumn()); - - var sql = "CREATE TRIGGER {0} BEFORE UPDATE ON {1} FOR EACH ROW BEGIN {2} END;".Fmt( - triggerName, modelDef.ModelName, triggerBody); - - return sql; - } - - return null; - }*/ - } -} diff --git a/src/ServiceStack.OrmLite.iOS.sln b/src/ServiceStack.OrmLite.iOS.sln deleted file mode 100644 index 417f6f796..000000000 --- a/src/ServiceStack.OrmLite.iOS.sln +++ /dev/null @@ -1,133 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.iOS", "ServiceStack.OrmLite\ServiceStack.OrmLite.iOS.csproj", "{7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Sqlite.iOS", "ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.iOS.csproj", "{E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExpressionsDemo", "ExpressionsDemo", "{3226CAEF-4117-4478-84B1-2B1EE0A88AF0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqliteExpressionsTest.iOS", "XamarinTests\SqliteExpressionsTest.iOS\SqliteExpressionsTest.iOS.csproj", "{9627154D-8CA4-4212-8033-26356B0C54F6}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Ad-Hoc|Any CPU = Ad-Hoc|Any CPU - Ad-Hoc|iPhone = Ad-Hoc|iPhone - Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator - Ad-Hoc|Mixed Platforms = Ad-Hoc|Mixed Platforms - AppStore|Any CPU = AppStore|Any CPU - AppStore|iPhone = AppStore|iPhone - AppStore|iPhoneSimulator = AppStore|iPhoneSimulator - AppStore|Mixed Platforms = AppStore|Mixed Platforms - Debug|Any CPU = Debug|Any CPU - Debug|iPhone = Debug|iPhone - Debug|iPhoneSimulator = Debug|iPhoneSimulator - Debug|Mixed Platforms = Debug|Mixed Platforms - Release|Any CPU = Release|Any CPU - Release|iPhone = Release|iPhone - Release|iPhoneSimulator = Release|iPhoneSimulator - Release|Mixed Platforms = Release|Mixed Platforms - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|Mixed Platforms.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Ad-Hoc|Mixed Platforms.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.AppStore|Any CPU.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.AppStore|Mixed Platforms.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.AppStore|Mixed Platforms.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|iPhone.Build.0 = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|Any CPU.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|iPhone.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|iPhone.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|Mixed Platforms.ActiveCfg = Ad-Hoc|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Ad-Hoc|Mixed Platforms.Build.0 = Ad-Hoc|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.AppStore|iPhone.ActiveCfg = AppStore|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.AppStore|iPhone.Build.0 = AppStore|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.AppStore|Mixed Platforms.ActiveCfg = AppStore|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.AppStore|Mixed Platforms.Build.0 = AppStore|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|Any CPU.ActiveCfg = Debug|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|Any CPU.Build.0 = Debug|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|iPhone.ActiveCfg = Debug|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|iPhone.Build.0 = Debug|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|Mixed Platforms.ActiveCfg = Debug|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Debug|Mixed Platforms.Build.0 = Debug|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|Any CPU.ActiveCfg = Release|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|Any CPU.Build.0 = Release|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|iPhone.ActiveCfg = Release|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|iPhone.Build.0 = Release|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|Mixed Platforms.ActiveCfg = Release|iPhone - {9627154D-8CA4-4212-8033-26356B0C54F6}.Release|Mixed Platforms.Build.0 = Release|iPhone - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|Mixed Platforms.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Ad-Hoc|Mixed Platforms.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.AppStore|Any CPU.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.AppStore|Mixed Platforms.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.AppStore|Mixed Platforms.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|iPhone.Build.0 = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|Any CPU.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|iPhone.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|iPhone.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85}.Release|Mixed Platforms.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {9627154D-8CA4-4212-8033-26356B0C54F6} = {3226CAEF-4117-4478-84B1-2B1EE0A88AF0} - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = XamarinTests\SqliteExpressionsTest.iOS\SqliteExpressionsTest.iOS.csproj - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/ServiceStack.OrmLite.sln b/src/ServiceStack.OrmLite.sln index 98efe6163..a8e118d09 100644 --- a/src/ServiceStack.OrmLite.sln +++ b/src/ServiceStack.OrmLite.sln @@ -1,99 +1,59 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{6CEB3EDE-9F02-4F4F-BD8A-1B2939C1AE6E}" ProjectSection(SolutionItems) = preProject - ..\build\appsettings.license.txt = ..\build\appsettings.license.txt - ..\build\build-sn.proj = ..\build\build-sn.proj ..\build\build.bat = ..\build\build.bat ..\build\build.proj = ..\build\build.proj ..\build\build.tasks = ..\build\build.tasks - ..\build\copy.bat = ..\build\copy.bat ..\README.md = ..\README.md - ..\NuGet\ServiceStack.OrmLite.Firebird\servicestack.ormlite.firebird.nuspec = ..\NuGet\ServiceStack.OrmLite.Firebird\servicestack.ormlite.firebird.nuspec - ..\NuGet\ServiceStack.OrmLite.MySql\servicestack.ormlite.mysql.nuspec = ..\NuGet\ServiceStack.OrmLite.MySql\servicestack.ormlite.mysql.nuspec - ..\NuGet\ServiceStack.OrmLite\servicestack.ormlite.nuspec = ..\NuGet\ServiceStack.OrmLite\servicestack.ormlite.nuspec - ..\NuGet\ServiceStack.OrmLite.Oracle\servicestack.ormlite.oracle.nuspec = ..\NuGet\ServiceStack.OrmLite.Oracle\servicestack.ormlite.oracle.nuspec - ..\NuGet\ServiceStack.OrmLite.PostgreSQL\servicestack.ormlite.postgresql.nuspec = ..\NuGet\ServiceStack.OrmLite.PostgreSQL\servicestack.ormlite.postgresql.nuspec - ..\NuGet\ServiceStack.OrmLite.Sqlite.Mono\servicestack.ormlite.sqlite.mono.nuspec = ..\NuGet\ServiceStack.OrmLite.Sqlite.Mono\servicestack.ormlite.sqlite.mono.nuspec - ..\NuGet\ServiceStack.OrmLite.Sqlite.Windows\servicestack.ormlite.sqlite.windows.nuspec = ..\NuGet\ServiceStack.OrmLite.Sqlite.Windows\servicestack.ormlite.sqlite.windows.nuspec - ..\NuGet\ServiceStack.OrmLite.Sqlite32\servicestack.ormlite.sqlite32.nuspec = ..\NuGet\ServiceStack.OrmLite.Sqlite32\servicestack.ormlite.sqlite32.nuspec - ..\NuGet\ServiceStack.OrmLite.Sqlite64\servicestack.ormlite.sqlite64.nuspec = ..\NuGet\ServiceStack.OrmLite.Sqlite64\servicestack.ormlite.sqlite64.nuspec - ..\NuGet\ServiceStack.OrmLite.SqlServer\servicestack.ormlite.sqlserver.nuspec = ..\NuGet\ServiceStack.OrmLite.SqlServer\servicestack.ormlite.sqlserver.nuspec - ..\NuGet\ServiceStack.OrmLite.T4\servicestack.ormlite.t4.nuspec = ..\NuGet\ServiceStack.OrmLite.T4\servicestack.ormlite.t4.nuspec + Directory.Build.props = Directory.Build.props + ServiceStack.OrmLite\ServiceStack.OrmLite.Core.csproj = ServiceStack.OrmLite\ServiceStack.OrmLite.Core.csproj + ServiceStack.OrmLite.Firebird\ServiceStack.OrmLite.Firebird.Core.csproj = ServiceStack.OrmLite.Firebird\ServiceStack.OrmLite.Firebird.Core.csproj + ServiceStack.OrmLite.MySql\ServiceStack.OrmLite.MySql.Core.csproj = ServiceStack.OrmLite.MySql\ServiceStack.OrmLite.MySql.Core.csproj + ServiceStack.OrmLite.MySqlConnector\ServiceStack.OrmLite.MySqlConnector.Core.csproj = ServiceStack.OrmLite.MySqlConnector\ServiceStack.OrmLite.MySqlConnector.Core.csproj + ServiceStack.OrmLite.PostgreSQL\ServiceStack.OrmLite.PostgreSQL.Core.csproj = ServiceStack.OrmLite.PostgreSQL\ServiceStack.OrmLite.PostgreSQL.Core.csproj + ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.Core.csproj = ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.Core.csproj + ServiceStack.OrmLite.SqlServer\ServiceStack.OrmLite.SqlServer.Core.csproj = ServiceStack.OrmLite.SqlServer\ServiceStack.OrmLite.SqlServer.Core.csproj + ..\build\build-core.proj = ..\build\build-core.proj + ServiceStack.OrmLite.Sqlite.Data\ServiceStack.OrmLite.Sqlite.Data.csproj = ServiceStack.OrmLite.Sqlite.Data\ServiceStack.OrmLite.Sqlite.Data.csproj + ServiceStack.OrmLite.SqlServer.Data\ServiceStack.OrmLite.SqlServer.Data.csproj = ServiceStack.OrmLite.SqlServer.Data\ServiceStack.OrmLite.SqlServer.Data.csproj + ServiceStack.OrmLite.SqlServer.Data\ServiceStack.OrmLite.SqlServer.Data.Core.csproj = ServiceStack.OrmLite.SqlServer.Data\ServiceStack.OrmLite.SqlServer.Data.Core.csproj + ..\build\build-core-data.proj = ..\build\build-core-data.proj + ..\tests\Directory.Build.props = ..\tests\Directory.Build.props + ServiceStack.OrmLite.PostgreSQL\ServiceStack.OrmLite.PostgreSQL.Source.csproj = ServiceStack.OrmLite.PostgreSQL\ServiceStack.OrmLite.PostgreSQL.Source.csproj + ServiceStack.OrmLite.MySql\ServiceStack.OrmLite.MySql.Source.csproj = ServiceStack.OrmLite.MySql\ServiceStack.OrmLite.MySql.Source.csproj + ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.Source.csproj = ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.Source.csproj + ServiceStack.OrmLite.SqlServer\ServiceStack.OrmLite.SqlServer.Source.csproj = ServiceStack.OrmLite.SqlServer\ServiceStack.OrmLite.SqlServer.Source.csproj EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FirebirdTests", "FirebirdTests", "{AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.Sqlite", "ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.csproj", "{CF68A37D-D071-469D-AE04-68594CB95382}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLiteFirebird02", "FirebirdTests\TestSimpleFirebird02\TestLiteFirebird02.csproj", "{924A8BBF-4D88-41A3-9F83-4332B0019D0C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite", "ServiceStack.OrmLite\ServiceStack.OrmLite.csproj", "{96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestSimpleFirebird03", "FirebirdTests\TestSimpleFirebird03\TestSimpleFirebird03.csproj", "{E4489930-7E42-43B8-93C3-7E1974845D88}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.SqlServer", "ServiceStack.OrmLite.SqlServer\ServiceStack.OrmLite.SqlServer.csproj", "{1887DC99-9139-43E3-A7AA-6D74714B3A5D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestSimpleFirebirdProcedures", "FirebirdTests\TestSimpleFirebirdProcedures\TestSimpleFirebirdProcedures.csproj", "{60B6BD41-6415-418E-A71F-FB6622C379D9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.Tests", "..\tests\ServiceStack.OrmLite.Tests\ServiceStack.OrmLite.Tests.csproj", "{9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLiteFirebird01", "FirebirdTests\TestSimpleFirebird01\TestLiteFirebird01.csproj", "{1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.SqlServer.Tests", "..\tests\ServiceStack.OrmLite.SqlServer.Tests\ServiceStack.OrmLite.SqlServer.Tests.csproj", "{96793C11-2A99-4217-8946-3E0DB9534A4D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClassWriter", "FirebirdTests\TestClassWriter\TestClassWriter.csproj", "{85DF0278-488D-460B-8B40-737E07089465}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.Firebird", "ServiceStack.OrmLite.Firebird\ServiceStack.OrmLite.Firebird.csproj", "{317B64BA-D7A6-4A15-8719-821B38147C63}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestExpressions", "FirebirdTests\TestExpressions\TestExpressions.csproj", "{80896749-19C6-437C-8852-F07243AA5F59}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.FirebirdTests", "..\tests\ServiceStack.OrmLite.FirebirdTests\ServiceStack.OrmLite.FirebirdTests.csproj", "{CB988768-7753-4EF2-8C06-6A74B384C78E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLiteFirebird00", "FirebirdTests\TestLiteFirebird00\TestLiteFirebird00.csproj", "{83CEE527-DC55-4AB1-82FC-B90F17AB0E66}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.MySql", "ServiceStack.OrmLite.MySql\ServiceStack.OrmLite.MySql.csproj", "{FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLiteFirebird04", "FirebirdTests\TestLiteFirebird04\TestLiteFirebird04.csproj", "{B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.MySql.Tests", "..\tests\ServiceStack.OrmLite.MySql.Tests\ServiceStack.OrmLite.MySql.Tests.csproj", "{21EBB2F6-030B-492C-963B-2FC447684CCD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Sqlite", "ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.csproj", "{CF68A37D-D071-469D-AE04-68594CB95382}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.PostgreSQL", "ServiceStack.OrmLite.PostgreSQL\ServiceStack.OrmLite.PostgreSQL.csproj", "{3220F088-BDD0-6979-AC0C-8C541C2E7DE5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite", "ServiceStack.OrmLite\ServiceStack.OrmLite.csproj", "{96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.PostgreSQL.Tests", "..\tests\ServiceStack.OrmLite.PostgreSQL.Tests\ServiceStack.OrmLite.PostgreSQL.Tests.csproj", "{E692B423-82E9-46DE-AA80-F4E36A4B4D56}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.SqlServer", "ServiceStack.OrmLite.SqlServer\ServiceStack.OrmLite.SqlServer.csproj", "{1887DC99-9139-43E3-A7AA-6D74714B3A5D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.Oracle", "ServiceStack.OrmLite.Oracle\ServiceStack.OrmLite.Oracle.csproj", "{517B64BA-D7A6-4A15-8719-821B38147C61}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Tests", "..\tests\ServiceStack.OrmLite.Tests\ServiceStack.OrmLite.Tests.csproj", "{9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlMapper", "dapper-dot-net\SqlMapper.csproj", "{A2A80512-11F4-4028-A995-505463632C84}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.SqlServerTests", "ServiceStack.OrmLite.SqlServerTests\ServiceStack.OrmLite.SqlServerTests.csproj", "{96793C11-2A99-4217-8946-3E0DB9534A4D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Firebird", "ServiceStack.OrmLite.Firebird\ServiceStack.OrmLite.Firebird.csproj", "{317B64BA-D7A6-4A15-8719-821B38147C63}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.FirebirdTests", "..\tests\ServiceStack.OrmLite.FirebirdTests\ServiceStack.OrmLite.FirebirdTests.csproj", "{CB988768-7753-4EF2-8C06-6A74B384C78E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.MySql", "ServiceStack.OrmLite.MySql\ServiceStack.OrmLite.MySql.csproj", "{FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.MySql.Tests", "ServiceStack.OrmLite.MySql.Tests\ServiceStack.OrmLite.MySql.Tests.csproj", "{21EBB2F6-030B-492C-963B-2FC447684CCD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExpressionsDemo", "ExpressionsDemo", "{E2CAD578-0966-401B-83C2-792F8861FF5D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySqlExpressionsTest", "MySqlExpressionsTest\MySqlExpressionsTest.csproj", "{79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqliteExpressionsTest", "SqliteExpressionsTest\SqliteExpressionsTest.csproj", "{7CF9CE3E-F5FE-4C73-843F-57A64B202743}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PostgreSQLExpressionsTest", "PostgreSQLExpressionsTest\PostgreSQLExpressionsTest.csproj", "{348E82EE-7D30-4D60-90E5-CA60C290C589}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServerExpressionsTest", "SqlServerExpressionsTest\SqlServerExpressionsTest.csproj", "{19825530-1D25-4528-AB6D-E236809A7F34}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AllDialectsTest", "AllDialectsTest\AllDialectsTest.csproj", "{A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.PostgreSQL", "ServiceStack.OrmLite.PostgreSQL\ServiceStack.OrmLite.PostgreSQL.csproj", "{3220F088-BDD0-6979-AC0C-8C541C2E7DE5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.PostgreSQL.Tests", "ServiceStack.OrmLite.PostgreSQL.Tests\ServiceStack.OrmLite.PostgreSQL.Tests.csproj", "{E692B423-82E9-46DE-AA80-F4E36A4B4D56}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Oracle", "ServiceStack.OrmLite.Oracle\ServiceStack.OrmLite.Oracle.csproj", "{517B64BA-D7A6-4A15-8719-821B38147C61}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OracleTests", "OracleTests", "{86A84A8B-29B8-4C4D-839B-76836AD59D28}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClassWriter", "OracleTests\TestClassWriter\TestClassWriter.csproj", "{AAE7E422-EAC0-4B06-A973-C32E7E600769}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestExpression02", "OracleTests\TestExpression02\TestExpression02.csproj", "{3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestExpressions", "OracleTests\TestExpressions\TestExpressions.csproj", "{619CF480-0DFB-429E-8FC1-B039E8C47AD9}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLiteOracle00", "OracleTests\TestLiteOracle00\TestLiteOracle00.csproj", "{81280460-2358-40D2-94AA-85951612EA04}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLiteOracle04", "OracleTests\TestLiteOracle04\TestLiteOracle04.csproj", "{583D79EF-27D8-4725-B706-BFE041F096A4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Oracle.Tests", "ServiceStack.OrmLite.Oracle.Tests\ServiceStack.OrmLite.Oracle.Tests.csproj", "{DE5CA3EB-010D-492A-A0B7-501D7941FA51}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.DDLTest", "ServiceStack.OrmLite.DDLTest\ServiceStack.OrmLite.DDLTest.csproj", "{E106F587-2DFF-4550-BA49-9A81A2EC344F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.Oracle.Tests", "..\tests\ServiceStack.OrmLite.Oracle.Tests\ServiceStack.OrmLite.Oracle.Tests.csproj", "{DE5CA3EB-010D-492A-A0B7-501D7941FA51}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "T4", "T4", "{ACB237F8-B931-4945-9533-FA2207510F75}" ProjectSection(SolutionItems) = preProject @@ -102,32 +62,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "T4", "T4", "{ACB237F8-B931- T4\OrmLite.SP.tt = T4\OrmLite.SP.tt EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Signed", "Signed", "{4A755D3C-CE48-4DB1-BF29-90A696ACD71B}" - ProjectSection(SolutionItems) = preProject - ..\NuGet.Signed\ServiceStack.OrmLite.Oracle.Signed\servicestack.ormlite.oracle.signed.nuspec = ..\NuGet.Signed\ServiceStack.OrmLite.Oracle.Signed\servicestack.ormlite.oracle.signed.nuspec - ..\NuGet.Signed\ServiceStack.OrmLite.Signed\servicestack.ormlite.signed.nuspec = ..\NuGet.Signed\ServiceStack.OrmLite.Signed\servicestack.ormlite.signed.nuspec - ..\NuGet.Signed\ServiceStack.OrmLite.SqlServer.Signed\servicestack.ormlite.sqlserver.signed.nuspec = ..\NuGet.Signed\ServiceStack.OrmLite.SqlServer.Signed\servicestack.ormlite.sqlserver.signed.nuspec - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.Sqlite.Windows", "ServiceStack.OrmLite.Sqlite.Windows\ServiceStack.OrmLite.Sqlite.Windows.csproj", "{A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.VistaDB", "ServiceStack.OrmLite.VistaDB\ServiceStack.OrmLite.VistaDB.csproj", "{D18D9D3C-B3B3-433C-9578-68E978587858}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.Sqlite.Windows.Tests", "..\tests\ServiceStack.OrmLite.Sqlite.Windows.Tests\ServiceStack.OrmLite.Sqlite.Windows.Tests.csproj", "{701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Sqlite.Windows", "ServiceStack.OrmLite.Sqlite.Windows\ServiceStack.OrmLite.Sqlite.Windows.csproj", "{A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.SqliteTests", "..\tests\ServiceStack.OrmLite.SqliteTests\ServiceStack.OrmLite.SqliteTests.csproj", "{956FD518-A6CC-46B1-A93A-1C92779BF942}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Sqlite.Windows.Tests", "..\tests\ServiceStack.OrmLite.Sqlite.Windows.Tests\ServiceStack.OrmLite.Sqlite.Windows.Tests.csproj", "{701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.SqlServer.Converters", "ServiceStack.OrmLite.SqlServer.Converters\ServiceStack.OrmLite.SqlServer.Converters.csproj", "{7E9BB57B-53E3-425E-9882-B6E078C5C9BA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.SqliteTests", "..\tests\ServiceStack.OrmLite.SqliteTests\ServiceStack.OrmLite.SqliteTests.csproj", "{956FD518-A6CC-46B1-A93A-1C92779BF942}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.MySqlConnector", "ServiceStack.OrmLite.MySqlConnector\ServiceStack.OrmLite.MySqlConnector.csproj", "{7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.VistaDB.Tests", "ServiceStack.OrmLite.VistaDB.Tests\ServiceStack.OrmLite.VistaDB.Tests.csproj", "{DBD5FF1A-454C-4763-A604-6EBB0C230357}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.OrmLite.MySqlConnector.Tests", "..\tests\ServiceStack.OrmLite.MySqlConnector.Tests\ServiceStack.OrmLite.MySqlConnector.Tests.csproj", "{3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLiteV45", "ServiceStack.OrmLiteV45\ServiceStack.OrmLiteV45.csproj", "{FDC37335-9ECC-413B-BEC5-16B466B0E689}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.T4", "ServiceStack.OrmLite.T4\ServiceStack.OrmLite.T4.csproj", "{196CD5D3-23E5-4C98-83DC-C5397396A574}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLiteV45.Tests", "..\tests\ServiceStack.OrmLiteV45.Tests\ServiceStack.OrmLiteV45.Tests.csproj", "{01ABABFF-FA2C-492A-9217-E83658BF6971}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Tests.Setup", "..\tests\ServiceStack.OrmLite.Tests.Setup\ServiceStack.OrmLite.Tests.Setup.csproj", "{74A4B761-974C-4AE8-88BE-7B29460D80B4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.MySqlV45", "ServiceStack.OrmLite.MySqlV45\ServiceStack.OrmLite.MySqlV45.csproj", "{D1858737-FC4F-4432-8725-E5B79A13D5F6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Sqlite.Data", "ServiceStack.OrmLite.Sqlite.Data\ServiceStack.OrmLite.Sqlite.Data.csproj", "{05F1FC33-8DF2-457D-820D-3C47CCD6D82E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.SqlServerV45", "ServiceStack.OrmLite.SqlServerV45\ServiceStack.OrmLite.SqlServerV45.csproj", "{6F851563-08F6-4692-89F8-F1D6C86F0069}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.SqlServer.Data", "ServiceStack.OrmLite.SqlServer.Data\ServiceStack.OrmLite.SqlServer.Data.csproj", "{A889689C-3B66-42E8-91EE-E2BCCDC00592}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.SqliteV45", "ServiceStack.OrmLite.SqliteV45\ServiceStack.OrmLite.SqliteV45.csproj", "{30C0C876-ABCB-441B-BFD4-AA9F688D9E54}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.OrmLite.Sqlite.Cil", "ServiceStack.OrmLite.Sqlite.Cil\ServiceStack.OrmLite.Sqlite.Cil.csproj", "{0A8CE66F-2D9B-4E52-9043-710A6E250660}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -140,174 +95,8 @@ Global Release|Any CPU = Release|Any CPU Release|Mixed Platforms = Release|Mixed Platforms Release|x86 = Release|x86 - Signed|Any CPU = Signed|Any CPU - Signed|Mixed Platforms = Signed|Mixed Platforms - Signed|x86 = Signed|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Debug|x86.ActiveCfg = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Debug|x86.Build.0 = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Default|x86.ActiveCfg = Debug|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Release|Any CPU.Build.0 = Release|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Release|x86.ActiveCfg = Release|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Release|x86.Build.0 = Release|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Signed|Any CPU.Build.0 = Signed|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {924A8BBF-4D88-41A3-9F83-4332B0019D0C}.Signed|x86.ActiveCfg = Signed|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Debug|x86.ActiveCfg = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Debug|x86.Build.0 = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Default|x86.ActiveCfg = Debug|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Release|Any CPU.Build.0 = Release|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Release|x86.ActiveCfg = Release|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Release|x86.Build.0 = Release|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Signed|Any CPU.Build.0 = Signed|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {E4489930-7E42-43B8-93C3-7E1974845D88}.Signed|x86.ActiveCfg = Signed|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Debug|x86.ActiveCfg = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Debug|x86.Build.0 = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Default|x86.ActiveCfg = Debug|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Release|Any CPU.Build.0 = Release|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Release|x86.ActiveCfg = Release|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Release|x86.Build.0 = Release|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Signed|Any CPU.Build.0 = Signed|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {60B6BD41-6415-418E-A71F-FB6622C379D9}.Signed|x86.ActiveCfg = Signed|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Debug|x86.ActiveCfg = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Debug|x86.Build.0 = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Default|x86.ActiveCfg = Debug|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Release|Any CPU.Build.0 = Release|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Release|x86.ActiveCfg = Release|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Release|x86.Build.0 = Release|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Signed|Any CPU.Build.0 = Signed|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003}.Signed|x86.ActiveCfg = Signed|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Debug|Any CPU.Build.0 = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Debug|x86.ActiveCfg = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Debug|x86.Build.0 = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Default|Any CPU.Build.0 = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Default|x86.ActiveCfg = Debug|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Release|Any CPU.ActiveCfg = Release|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Release|Any CPU.Build.0 = Release|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Release|x86.ActiveCfg = Release|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Release|x86.Build.0 = Release|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Signed|Any CPU.Build.0 = Signed|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {85DF0278-488D-460B-8B40-737E07089465}.Signed|x86.ActiveCfg = Signed|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Debug|Any CPU.Build.0 = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Debug|x86.ActiveCfg = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Debug|x86.Build.0 = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Default|Any CPU.Build.0 = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Default|x86.ActiveCfg = Debug|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Release|Any CPU.ActiveCfg = Release|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Release|Any CPU.Build.0 = Release|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Release|x86.ActiveCfg = Release|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Release|x86.Build.0 = Release|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Signed|Any CPU.Build.0 = Signed|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {80896749-19C6-437C-8852-F07243AA5F59}.Signed|x86.ActiveCfg = Signed|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Debug|Any CPU.Build.0 = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Debug|x86.ActiveCfg = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Debug|x86.Build.0 = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Default|x86.ActiveCfg = Debug|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Release|Any CPU.Build.0 = Release|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Release|x86.ActiveCfg = Release|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Release|x86.Build.0 = Release|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Signed|Any CPU.Build.0 = Signed|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66}.Signed|x86.ActiveCfg = Signed|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Debug|x86.ActiveCfg = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Debug|x86.Build.0 = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Default|Any CPU.Build.0 = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Default|x86.ActiveCfg = Debug|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Release|Any CPU.Build.0 = Release|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Release|x86.ActiveCfg = Release|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Release|x86.Build.0 = Release|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Signed|Any CPU.Build.0 = Signed|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A}.Signed|x86.ActiveCfg = Signed|Any CPU {CF68A37D-D071-469D-AE04-68594CB95382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CF68A37D-D071-469D-AE04-68594CB95382}.Debug|Any CPU.Build.0 = Debug|Any CPU {CF68A37D-D071-469D-AE04-68594CB95382}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -321,11 +110,6 @@ Global {CF68A37D-D071-469D-AE04-68594CB95382}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {CF68A37D-D071-469D-AE04-68594CB95382}.Release|Mixed Platforms.Build.0 = Release|Any CPU {CF68A37D-D071-469D-AE04-68594CB95382}.Release|x86.ActiveCfg = Release|Any CPU - {CF68A37D-D071-469D-AE04-68594CB95382}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {CF68A37D-D071-469D-AE04-68594CB95382}.Signed|Any CPU.Build.0 = Signed|Any CPU - {CF68A37D-D071-469D-AE04-68594CB95382}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {CF68A37D-D071-469D-AE04-68594CB95382}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {CF68A37D-D071-469D-AE04-68594CB95382}.Signed|x86.ActiveCfg = Signed|Any CPU {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Debug|Any CPU.Build.0 = Debug|Any CPU {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -339,11 +123,6 @@ Global {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Release|Mixed Platforms.Build.0 = Release|Any CPU {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Release|x86.ActiveCfg = Release|Any CPU - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Signed|Any CPU.Build.0 = Signed|Any CPU - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C}.Signed|x86.ActiveCfg = Signed|Any CPU {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -357,11 +136,6 @@ Global {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Release|Mixed Platforms.Build.0 = Release|Any CPU {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Release|x86.ActiveCfg = Release|Any CPU - {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Signed|Any CPU.Build.0 = Signed|Any CPU - {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {1887DC99-9139-43E3-A7AA-6D74714B3A5D}.Signed|x86.ActiveCfg = Signed|Any CPU {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -375,29 +149,6 @@ Global {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Release|Mixed Platforms.Build.0 = Release|Any CPU {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Release|x86.ActiveCfg = Release|Any CPU - {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Signed|Any CPU.Build.0 = Signed|Any CPU - {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD}.Signed|x86.ActiveCfg = Signed|Any CPU - {A2A80512-11F4-4028-A995-505463632C84}.Debug|Any CPU.ActiveCfg = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Debug|x86.ActiveCfg = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Debug|x86.Build.0 = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Default|Any CPU.ActiveCfg = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Default|Mixed Platforms.ActiveCfg = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Default|x86.ActiveCfg = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Release|Any CPU.ActiveCfg = Release|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Release|Mixed Platforms.Build.0 = Release|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Release|x86.ActiveCfg = Release|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Release|x86.Build.0 = Release|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Signed|Any CPU.ActiveCfg = Signed|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Signed|Mixed Platforms.ActiveCfg = Signed|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Signed|Mixed Platforms.Build.0 = Signed|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Signed|x86.ActiveCfg = Signed|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Signed|x86.Build.0 = Signed|x86 {96793C11-2A99-4217-8946-3E0DB9534A4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {96793C11-2A99-4217-8946-3E0DB9534A4D}.Debug|Any CPU.Build.0 = Debug|Any CPU {96793C11-2A99-4217-8946-3E0DB9534A4D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -411,11 +162,6 @@ Global {96793C11-2A99-4217-8946-3E0DB9534A4D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {96793C11-2A99-4217-8946-3E0DB9534A4D}.Release|Mixed Platforms.Build.0 = Release|Any CPU {96793C11-2A99-4217-8946-3E0DB9534A4D}.Release|x86.ActiveCfg = Release|Any CPU - {96793C11-2A99-4217-8946-3E0DB9534A4D}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {96793C11-2A99-4217-8946-3E0DB9534A4D}.Signed|Any CPU.Build.0 = Signed|Any CPU - {96793C11-2A99-4217-8946-3E0DB9534A4D}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {96793C11-2A99-4217-8946-3E0DB9534A4D}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {96793C11-2A99-4217-8946-3E0DB9534A4D}.Signed|x86.ActiveCfg = Signed|Any CPU {317B64BA-D7A6-4A15-8719-821B38147C63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {317B64BA-D7A6-4A15-8719-821B38147C63}.Debug|Any CPU.Build.0 = Debug|Any CPU {317B64BA-D7A6-4A15-8719-821B38147C63}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -431,11 +177,6 @@ Global {317B64BA-D7A6-4A15-8719-821B38147C63}.Release|Mixed Platforms.Build.0 = Release|Any CPU {317B64BA-D7A6-4A15-8719-821B38147C63}.Release|x86.ActiveCfg = Release|Any CPU {317B64BA-D7A6-4A15-8719-821B38147C63}.Release|x86.Build.0 = Release|Any CPU - {317B64BA-D7A6-4A15-8719-821B38147C63}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {317B64BA-D7A6-4A15-8719-821B38147C63}.Signed|Any CPU.Build.0 = Signed|Any CPU - {317B64BA-D7A6-4A15-8719-821B38147C63}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {317B64BA-D7A6-4A15-8719-821B38147C63}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {317B64BA-D7A6-4A15-8719-821B38147C63}.Signed|x86.ActiveCfg = Signed|Any CPU {CB988768-7753-4EF2-8C06-6A74B384C78E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CB988768-7753-4EF2-8C06-6A74B384C78E}.Debug|Any CPU.Build.0 = Debug|Any CPU {CB988768-7753-4EF2-8C06-6A74B384C78E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -452,11 +193,6 @@ Global {CB988768-7753-4EF2-8C06-6A74B384C78E}.Release|Mixed Platforms.Build.0 = Release|Any CPU {CB988768-7753-4EF2-8C06-6A74B384C78E}.Release|x86.ActiveCfg = Release|Any CPU {CB988768-7753-4EF2-8C06-6A74B384C78E}.Release|x86.Build.0 = Release|Any CPU - {CB988768-7753-4EF2-8C06-6A74B384C78E}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {CB988768-7753-4EF2-8C06-6A74B384C78E}.Signed|Any CPU.Build.0 = Signed|Any CPU - {CB988768-7753-4EF2-8C06-6A74B384C78E}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {CB988768-7753-4EF2-8C06-6A74B384C78E}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {CB988768-7753-4EF2-8C06-6A74B384C78E}.Signed|x86.ActiveCfg = Signed|Any CPU {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Debug|Any CPU.Build.0 = Debug|Any CPU {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -470,11 +206,6 @@ Global {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Release|x86.ActiveCfg = Release|Any CPU - {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Signed|Any CPU.Build.0 = Signed|Any CPU - {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {FD20F088-ACC0-4979-AC0C-8C541C2E7DE5}.Signed|x86.ActiveCfg = Signed|Any CPU {21EBB2F6-030B-492C-963B-2FC447684CCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {21EBB2F6-030B-492C-963B-2FC447684CCD}.Debug|Any CPU.Build.0 = Debug|Any CPU {21EBB2F6-030B-492C-963B-2FC447684CCD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -488,120 +219,6 @@ Global {21EBB2F6-030B-492C-963B-2FC447684CCD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {21EBB2F6-030B-492C-963B-2FC447684CCD}.Release|Mixed Platforms.Build.0 = Release|Any CPU {21EBB2F6-030B-492C-963B-2FC447684CCD}.Release|x86.ActiveCfg = Release|Any CPU - {21EBB2F6-030B-492C-963B-2FC447684CCD}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {21EBB2F6-030B-492C-963B-2FC447684CCD}.Signed|Any CPU.Build.0 = Signed|Any CPU - {21EBB2F6-030B-492C-963B-2FC447684CCD}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {21EBB2F6-030B-492C-963B-2FC447684CCD}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {21EBB2F6-030B-492C-963B-2FC447684CCD}.Signed|x86.ActiveCfg = Signed|Any CPU - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Debug|Any CPU.ActiveCfg = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Debug|Any CPU.Build.0 = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Debug|x86.ActiveCfg = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Debug|x86.Build.0 = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Default|Any CPU.ActiveCfg = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Default|Any CPU.Build.0 = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Default|Mixed Platforms.ActiveCfg = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Default|Mixed Platforms.Build.0 = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Default|x86.ActiveCfg = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Default|x86.Build.0 = Debug|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Release|Any CPU.ActiveCfg = Release|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Release|Any CPU.Build.0 = Release|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Release|Mixed Platforms.Build.0 = Release|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Release|x86.ActiveCfg = Release|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Release|x86.Build.0 = Release|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Signed|Any CPU.ActiveCfg = Signed|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Signed|Mixed Platforms.ActiveCfg = Signed|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Signed|Mixed Platforms.Build.0 = Signed|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Signed|x86.ActiveCfg = Signed|x86 - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D}.Signed|x86.Build.0 = Signed|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Debug|Any CPU.ActiveCfg = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Debug|Any CPU.Build.0 = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Debug|x86.ActiveCfg = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Debug|x86.Build.0 = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Default|Any CPU.ActiveCfg = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Default|Any CPU.Build.0 = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Default|Mixed Platforms.ActiveCfg = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Default|Mixed Platforms.Build.0 = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Default|x86.ActiveCfg = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Default|x86.Build.0 = Debug|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Release|Any CPU.ActiveCfg = Release|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Release|Any CPU.Build.0 = Release|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Release|Mixed Platforms.Build.0 = Release|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Release|x86.ActiveCfg = Release|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Release|x86.Build.0 = Release|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Signed|Any CPU.ActiveCfg = Signed|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Signed|Mixed Platforms.ActiveCfg = Signed|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Signed|Mixed Platforms.Build.0 = Signed|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Signed|x86.ActiveCfg = Signed|x86 - {7CF9CE3E-F5FE-4C73-843F-57A64B202743}.Signed|x86.Build.0 = Signed|x86 - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Debug|Any CPU.Build.0 = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Debug|x86.ActiveCfg = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Default|Any CPU.Build.0 = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Default|x86.ActiveCfg = Debug|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Release|Any CPU.ActiveCfg = Release|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Release|Any CPU.Build.0 = Release|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Release|x86.ActiveCfg = Release|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Signed|Any CPU.Build.0 = Signed|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {348E82EE-7D30-4D60-90E5-CA60C290C589}.Signed|x86.ActiveCfg = Signed|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Debug|Any CPU.Build.0 = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Debug|x86.ActiveCfg = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Default|Any CPU.Build.0 = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Default|x86.ActiveCfg = Debug|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Release|Any CPU.ActiveCfg = Release|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Release|Any CPU.Build.0 = Release|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Release|x86.ActiveCfg = Release|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Signed|Any CPU.Build.0 = Signed|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {19825530-1D25-4528-AB6D-E236809A7F34}.Signed|x86.ActiveCfg = Signed|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Debug|x86.ActiveCfg = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Debug|x86.Build.0 = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Default|Any CPU.Build.0 = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Default|x86.ActiveCfg = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Default|x86.Build.0 = Debug|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Release|Any CPU.Build.0 = Release|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Release|x86.ActiveCfg = Release|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Release|x86.Build.0 = Release|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Signed|Any CPU.Build.0 = Signed|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480}.Signed|x86.ActiveCfg = Signed|Any CPU {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Debug|Any CPU.Build.0 = Debug|Any CPU {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -617,11 +234,6 @@ Global {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Release|x86.ActiveCfg = Release|Any CPU - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Signed|Any CPU.Build.0 = Signed|Any CPU - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5}.Signed|x86.ActiveCfg = Signed|Any CPU {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Debug|Any CPU.Build.0 = Debug|Any CPU {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -634,11 +246,6 @@ Global {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Release|Mixed Platforms.Build.0 = Release|Any CPU {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Release|x86.ActiveCfg = Release|Any CPU - {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Signed|Any CPU.Build.0 = Signed|Any CPU - {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {E692B423-82E9-46DE-AA80-F4E36A4B4D56}.Signed|x86.ActiveCfg = Signed|Any CPU {517B64BA-D7A6-4A15-8719-821B38147C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {517B64BA-D7A6-4A15-8719-821B38147C61}.Debug|Any CPU.Build.0 = Debug|Any CPU {517B64BA-D7A6-4A15-8719-821B38147C61}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -654,111 +261,6 @@ Global {517B64BA-D7A6-4A15-8719-821B38147C61}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {517B64BA-D7A6-4A15-8719-821B38147C61}.Release|Mixed Platforms.Build.0 = Release|Any CPU {517B64BA-D7A6-4A15-8719-821B38147C61}.Release|x86.ActiveCfg = Release|Any CPU - {517B64BA-D7A6-4A15-8719-821B38147C61}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {517B64BA-D7A6-4A15-8719-821B38147C61}.Signed|Any CPU.Build.0 = Signed|Any CPU - {517B64BA-D7A6-4A15-8719-821B38147C61}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {517B64BA-D7A6-4A15-8719-821B38147C61}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {517B64BA-D7A6-4A15-8719-821B38147C61}.Signed|x86.ActiveCfg = Signed|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Debug|x86.ActiveCfg = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Default|Any CPU.Build.0 = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Default|x86.ActiveCfg = Debug|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Release|Any CPU.Build.0 = Release|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Release|x86.ActiveCfg = Release|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Signed|Any CPU.Build.0 = Signed|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {AAE7E422-EAC0-4B06-A973-C32E7E600769}.Signed|x86.ActiveCfg = Signed|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Debug|x86.ActiveCfg = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Default|Any CPU.Build.0 = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Default|x86.ActiveCfg = Debug|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Release|Any CPU.Build.0 = Release|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Release|x86.ActiveCfg = Release|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Signed|Any CPU.Build.0 = Signed|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F}.Signed|x86.ActiveCfg = Signed|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Debug|x86.ActiveCfg = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Default|Any CPU.Build.0 = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Default|x86.ActiveCfg = Debug|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Release|Any CPU.Build.0 = Release|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Release|x86.ActiveCfg = Release|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Signed|Any CPU.Build.0 = Signed|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {619CF480-0DFB-429E-8FC1-B039E8C47AD9}.Signed|x86.ActiveCfg = Signed|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Debug|Any CPU.Build.0 = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Debug|x86.ActiveCfg = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Default|Any CPU.Build.0 = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Default|x86.ActiveCfg = Debug|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Release|Any CPU.ActiveCfg = Release|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Release|Any CPU.Build.0 = Release|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Release|x86.ActiveCfg = Release|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Signed|Any CPU.Build.0 = Signed|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {81280460-2358-40D2-94AA-85951612EA04}.Signed|x86.ActiveCfg = Signed|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Debug|x86.ActiveCfg = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Default|Any CPU.Build.0 = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Default|x86.ActiveCfg = Debug|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Release|Any CPU.Build.0 = Release|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Release|x86.ActiveCfg = Release|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Signed|Any CPU.Build.0 = Signed|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {583D79EF-27D8-4725-B706-BFE041F096A4}.Signed|x86.ActiveCfg = Signed|Any CPU {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Debug|Any CPU.Build.0 = Debug|Any CPU {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -774,52 +276,6 @@ Global {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Release|Mixed Platforms.Build.0 = Release|Any CPU {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Release|x86.ActiveCfg = Release|Any CPU - {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Signed|Any CPU.Build.0 = Signed|Any CPU - {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {DE5CA3EB-010D-492A-A0B7-501D7941FA51}.Signed|x86.ActiveCfg = Signed|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Debug|x86.ActiveCfg = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Debug|x86.Build.0 = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Default|Any CPU.Build.0 = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Default|x86.ActiveCfg = Debug|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Release|Any CPU.Build.0 = Release|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Release|x86.ActiveCfg = Release|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Release|x86.Build.0 = Release|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Signed|Any CPU.Build.0 = Signed|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {E106F587-2DFF-4550-BA49-9A81A2EC344F}.Signed|x86.ActiveCfg = Signed|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Debug|x86.ActiveCfg = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Default|Any CPU.Build.0 = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Default|x86.ActiveCfg = Debug|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Release|Any CPU.Build.0 = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Release|x86.ActiveCfg = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Signed|Any CPU.Build.0 = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Signed|Mixed Platforms.Build.0 = Release|Any CPU - {D18D9D3C-B3B3-433C-9578-68E978587858}.Signed|x86.ActiveCfg = Release|Any CPU {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -835,11 +291,6 @@ Global {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Release|Mixed Platforms.Build.0 = Release|Any CPU {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Release|x86.ActiveCfg = Release|Any CPU - {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Signed|Any CPU.Build.0 = Release|Any CPU - {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {A5541444-70EE-4B5E-8A5F-C7D8A0048EBE}.Signed|x86.ActiveCfg = Release|Any CPU {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Debug|Any CPU.Build.0 = Debug|Any CPU {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -855,11 +306,6 @@ Global {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Release|Mixed Platforms.Build.0 = Release|Any CPU {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Release|x86.ActiveCfg = Release|Any CPU - {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Signed|Any CPU.Build.0 = Release|Any CPU - {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU - {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Signed|Mixed Platforms.Build.0 = Release|Any CPU - {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08}.Signed|x86.ActiveCfg = Release|Any CPU {956FD518-A6CC-46B1-A93A-1C92779BF942}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {956FD518-A6CC-46B1-A93A-1C92779BF942}.Debug|Any CPU.Build.0 = Debug|Any CPU {956FD518-A6CC-46B1-A93A-1C92779BF942}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -875,157 +321,158 @@ Global {956FD518-A6CC-46B1-A93A-1C92779BF942}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {956FD518-A6CC-46B1-A93A-1C92779BF942}.Release|Mixed Platforms.Build.0 = Release|Any CPU {956FD518-A6CC-46B1-A93A-1C92779BF942}.Release|x86.ActiveCfg = Release|Any CPU - {956FD518-A6CC-46B1-A93A-1C92779BF942}.Signed|Any CPU.ActiveCfg = Signed|Any CPU - {956FD518-A6CC-46B1-A93A-1C92779BF942}.Signed|Any CPU.Build.0 = Signed|Any CPU - {956FD518-A6CC-46B1-A93A-1C92779BF942}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {956FD518-A6CC-46B1-A93A-1C92779BF942}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {956FD518-A6CC-46B1-A93A-1C92779BF942}.Signed|x86.ActiveCfg = Signed|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Debug|x86.ActiveCfg = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Default|Any CPU.Build.0 = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Default|x86.ActiveCfg = Debug|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Release|Any CPU.Build.0 = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Release|x86.ActiveCfg = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Signed|Any CPU.Build.0 = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Signed|Mixed Platforms.Build.0 = Release|Any CPU - {DBD5FF1A-454C-4763-A604-6EBB0C230357}.Signed|x86.ActiveCfg = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Debug|x86.ActiveCfg = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Default|Any CPU.Build.0 = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Default|x86.ActiveCfg = Debug|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Release|Any CPU.Build.0 = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Release|x86.ActiveCfg = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Signed|Any CPU.Build.0 = Release|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689}.Signed|x86.ActiveCfg = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Debug|Any CPU.Build.0 = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Debug|x86.ActiveCfg = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Default|Any CPU.Build.0 = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Default|x86.ActiveCfg = Debug|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Release|Any CPU.ActiveCfg = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Release|Any CPU.Build.0 = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Release|x86.ActiveCfg = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Signed|Any CPU.Build.0 = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Signed|Mixed Platforms.Build.0 = Release|Any CPU - {01ABABFF-FA2C-492A-9217-E83658BF6971}.Signed|x86.ActiveCfg = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Debug|x86.ActiveCfg = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Default|Any CPU.Build.0 = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Default|x86.ActiveCfg = Debug|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Release|Any CPU.Build.0 = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Release|x86.ActiveCfg = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Signed|Any CPU.Build.0 = Release|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {D1858737-FC4F-4432-8725-E5B79A13D5F6}.Signed|x86.ActiveCfg = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Debug|x86.ActiveCfg = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Default|Any CPU.Build.0 = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Default|x86.ActiveCfg = Debug|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Release|Any CPU.Build.0 = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Release|x86.ActiveCfg = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Signed|Any CPU.Build.0 = Release|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Signed|Mixed Platforms.ActiveCfg = Signed|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Signed|Mixed Platforms.Build.0 = Signed|Any CPU - {6F851563-08F6-4692-89F8-F1D6C86F0069}.Signed|x86.ActiveCfg = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Debug|Any CPU.Build.0 = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Debug|x86.ActiveCfg = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Default|Any CPU.ActiveCfg = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Default|Any CPU.Build.0 = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Default|Mixed Platforms.Build.0 = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Default|x86.ActiveCfg = Debug|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Release|Any CPU.ActiveCfg = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Release|Any CPU.Build.0 = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Release|x86.ActiveCfg = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Signed|Any CPU.ActiveCfg = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Signed|Any CPU.Build.0 = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Signed|Mixed Platforms.ActiveCfg = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Signed|Mixed Platforms.Build.0 = Release|Any CPU - {30C0C876-ABCB-441B-BFD4-AA9F688D9E54}.Signed|x86.ActiveCfg = Release|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Debug|x86.ActiveCfg = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Debug|x86.Build.0 = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Default|Any CPU.Build.0 = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Default|x86.ActiveCfg = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Default|x86.Build.0 = Debug|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Release|Any CPU.Build.0 = Release|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Release|x86.ActiveCfg = Release|Any CPU + {7E9BB57B-53E3-425E-9882-B6E078C5C9BA}.Release|x86.Build.0 = Release|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Debug|x86.ActiveCfg = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Debug|x86.Build.0 = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Default|Any CPU.Build.0 = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Default|x86.ActiveCfg = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Default|x86.Build.0 = Debug|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Release|Any CPU.Build.0 = Release|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Release|x86.ActiveCfg = Release|Any CPU + {7ECD23BC-AB3A-4528-AE6F-0F182874AA9B}.Release|x86.Build.0 = Release|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Debug|x86.ActiveCfg = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Debug|x86.Build.0 = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Default|Any CPU.Build.0 = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Default|x86.ActiveCfg = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Default|x86.Build.0 = Debug|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Release|Any CPU.Build.0 = Release|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Release|x86.ActiveCfg = Release|Any CPU + {3F41BD6C-66BE-49B6-B3B3-B27A7A8527B4}.Release|x86.Build.0 = Release|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Debug|Any CPU.Build.0 = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Debug|x86.ActiveCfg = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Debug|x86.Build.0 = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Default|Any CPU.Build.0 = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Default|x86.ActiveCfg = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Default|x86.Build.0 = Debug|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Release|Any CPU.ActiveCfg = Release|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Release|Any CPU.Build.0 = Release|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Release|x86.ActiveCfg = Release|Any CPU + {196CD5D3-23E5-4C98-83DC-C5397396A574}.Release|x86.Build.0 = Release|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Debug|x86.ActiveCfg = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Debug|x86.Build.0 = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Default|Any CPU.Build.0 = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Default|x86.ActiveCfg = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Default|x86.Build.0 = Debug|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Release|Any CPU.Build.0 = Release|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Release|x86.ActiveCfg = Release|Any CPU + {74A4B761-974C-4AE8-88BE-7B29460D80B4}.Release|x86.Build.0 = Release|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Debug|x86.ActiveCfg = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Debug|x86.Build.0 = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Default|Any CPU.Build.0 = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Default|x86.ActiveCfg = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Default|x86.Build.0 = Debug|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Release|Any CPU.Build.0 = Release|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Release|x86.ActiveCfg = Release|Any CPU + {05F1FC33-8DF2-457D-820D-3C47CCD6D82E}.Release|x86.Build.0 = Release|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Debug|x86.ActiveCfg = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Debug|x86.Build.0 = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Default|Any CPU.Build.0 = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Default|x86.ActiveCfg = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Default|x86.Build.0 = Debug|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Release|Any CPU.Build.0 = Release|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Release|x86.ActiveCfg = Release|Any CPU + {A889689C-3B66-42E8-91EE-E2BCCDC00592}.Release|x86.Build.0 = Release|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Debug|x86.ActiveCfg = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Debug|x86.Build.0 = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Default|Any CPU.ActiveCfg = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Default|Any CPU.Build.0 = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Default|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Default|Mixed Platforms.Build.0 = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Default|x86.ActiveCfg = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Default|x86.Build.0 = Debug|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Release|Any CPU.Build.0 = Release|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Release|x86.ActiveCfg = Release|Any CPU + {0A8CE66F-2D9B-4E52-9043-710A6E250660}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {924A8BBF-4D88-41A3-9F83-4332B0019D0C} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {E4489930-7E42-43B8-93C3-7E1974845D88} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {60B6BD41-6415-418E-A71F-FB6622C379D9} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {1E5BEEEC-9A28-4BCC-B6DD-9B342C3F3003} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {85DF0278-488D-460B-8B40-737E07089465} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {80896749-19C6-437C-8852-F07243AA5F59} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {83CEE527-DC55-4AB1-82FC-B90F17AB0E66} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {B0EBA56F-626B-4F38-A189-5E1B6BD60D9A} = {AA7D8994-D1CA-484E-B3A4-EF6044CBE9BB} - {79F42E0D-EC0B-4591-BEE9-3A1BE3F0C57D} = {E2CAD578-0966-401B-83C2-792F8861FF5D} - {7CF9CE3E-F5FE-4C73-843F-57A64B202743} = {E2CAD578-0966-401B-83C2-792F8861FF5D} - {348E82EE-7D30-4D60-90E5-CA60C290C589} = {E2CAD578-0966-401B-83C2-792F8861FF5D} - {19825530-1D25-4528-AB6D-E236809A7F34} = {E2CAD578-0966-401B-83C2-792F8861FF5D} - {A55FAA4E-7900-4F77-AEA2-FA7F44D0A480} = {E2CAD578-0966-401B-83C2-792F8861FF5D} - {AAE7E422-EAC0-4B06-A973-C32E7E600769} = {86A84A8B-29B8-4C4D-839B-76836AD59D28} - {3D07D1C9-62EA-48C7-8242-CDC10BC46E6F} = {86A84A8B-29B8-4C4D-839B-76836AD59D28} - {619CF480-0DFB-429E-8FC1-B039E8C47AD9} = {86A84A8B-29B8-4C4D-839B-76836AD59D28} - {81280460-2358-40D2-94AA-85951612EA04} = {86A84A8B-29B8-4C4D-839B-76836AD59D28} - {583D79EF-27D8-4725-B706-BFE041F096A4} = {86A84A8B-29B8-4C4D-839B-76836AD59D28} - {4A755D3C-CE48-4DB1-BF29-90A696ACD71B} = {6CEB3EDE-9F02-4F4F-BD8A-1B2939C1AE6E} + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {03B25106-F90B-4FE9-8BD9-851DE4CAB153} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = ServiceStack.OrmLite.Sqlite\ServiceStack.OrmLite.Sqlite.csproj EndGlobalSection + GlobalSection(NestedProjects) = preSolution + EndGlobalSection EndGlobal diff --git a/src/ServiceStack.OrmLite.sln.DotSettings b/src/ServiceStack.OrmLite.sln.DotSettings index 11f2c267a..28747c5cb 100644 --- a/src/ServiceStack.OrmLite.sln.DotSettings +++ b/src/ServiceStack.OrmLite.sln.DotSettings @@ -1,3 +1,4 @@  + True <data><IncludeFilters /><ExcludeFilters /></data> <data /> \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/AliasNamingStrategy.cs b/src/ServiceStack.OrmLite/AliasNamingStrategy.cs deleted file mode 100644 index 65691e5a2..000000000 --- a/src/ServiceStack.OrmLite/AliasNamingStrategy.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; - -namespace ServiceStack.OrmLite -{ - public class AliasNamingStrategy : OrmLiteNamingStrategyBase - { - public Dictionary TableAliases = new Dictionary(); - public Dictionary ColumnAliases = new Dictionary(); - public INamingStrategy UseNamingStrategy { get; set; } - - public override string GetTableName(string name) - { - string alias; - return UseNamingStrategy != null - ? UseNamingStrategy.GetTableName(TableAliases.TryGetValue(name, out alias) ? alias : name) - : base.GetTableName(TableAliases.TryGetValue(name, out alias) ? alias : name); - } - - public override string GetColumnName(string name) - { - string alias; - return UseNamingStrategy != null - ? UseNamingStrategy.GetColumnName(ColumnAliases.TryGetValue(name, out alias) ? alias : name) - : base.GetColumnName(ColumnAliases.TryGetValue(name, out alias) ? alias : name); - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Async/OrmLiteReadCommandExtensionsAsync.cs b/src/ServiceStack.OrmLite/Async/OrmLiteReadCommandExtensionsAsync.cs index f64496fa1..f989f1f80 100644 --- a/src/ServiceStack.OrmLite/Async/OrmLiteReadCommandExtensionsAsync.cs +++ b/src/ServiceStack.OrmLite/Async/OrmLiteReadCommandExtensionsAsync.cs @@ -1,44 +1,38 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; using System.Collections; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Threading; using System.Threading.Tasks; using ServiceStack.Logging; using ServiceStack.OrmLite.Support; +using ServiceStack.Text; namespace ServiceStack.OrmLite { internal static class OrmLiteReadCommandExtensionsAsync { - private static readonly ILog Log = LogManager.GetLogger(typeof(OrmLiteReadCommandExtensionsAsync)); - - private static void LogDebug(string fmt) - { - Log.Debug(fmt); - } + internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteReadCommandExtensionsAsync)); internal static Task ExecReaderAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { + dbCmd.CommandText = sql; + if (Log.IsDebugEnabled) - LogDebug(sql); + Log.DebugCommand(dbCmd); - dbCmd.CommandTimeout = OrmLiteConfig.CommandTimeout; - dbCmd.CommandText = sql; + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); return dbCmd.GetDialectProvider().ExecuteReaderAsync(dbCmd, token); } internal static Task ExecReaderAsync(this IDbCommand dbCmd, string sql, IEnumerable parameters, CancellationToken token) { - if (Log.IsDebugEnabled) - LogDebug(sql); - - dbCmd.CommandTimeout = OrmLiteConfig.CommandTimeout; dbCmd.CommandText = sql; dbCmd.Parameters.Clear(); @@ -47,291 +41,243 @@ internal static Task ExecReaderAsync(this IDbCommand dbCmd, string dbCmd.Parameters.Add(param); } + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + return dbCmd.GetDialectProvider().ExecuteReaderAsync(dbCmd, token); } internal static Task> SelectAsync(this IDbCommand dbCmd, CancellationToken token) { - return SelectFmtAsync(dbCmd, token, (string)null); - } - - internal static Task> SelectFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFilter, params object[] filterParams) - { - return dbCmd.ConvertToListAsync( - dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sqlFilter, filterParams), token); + return SelectAsync(dbCmd, (string)null, (object)null, token); } internal static Task> SelectAsync(this IDbCommand dbCmd, Type fromTableType, CancellationToken token) { - return SelectFmtAsync(dbCmd, token, fromTableType, null); - } - - internal static Task> SelectFmtAsync(this IDbCommand dbCmd, CancellationToken token, Type fromTableType, string sqlFilter, params object[] filterParams) - { - var sql = OrmLiteReadCommandExtensions.ToSelectFmt(dbCmd.GetDialectProvider(), fromTableType, sqlFilter, filterParams); - - return dbCmd.ConvertToListAsync(sql.ToString(), token); + return SelectAsync(dbCmd, fromTableType, null, null, token); } - internal static Task SelectByIdFmtAsync(this IDbCommand dbCmd, object idValue, CancellationToken token) + internal static Task> SelectAsync(this IDbCommand dbCmd, Type fromTableType, string sqlFilter, object anonType, CancellationToken token) { - return dbCmd.SingleFmtAsync(token, dbCmd.GetDialectProvider().GetQuotedColumnName(ModelDefinition.PrimaryKeyName) + " = {0}".SqlFmt(idValue)); - } - - internal static Task SingleFmtAsync(this IDbCommand dbCmd, CancellationToken token, string filter, params object[] filterParams) - { - return dbCmd.ConvertToAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), filter, filterParams), token); + if (anonType != null) dbCmd.SetParameters(fromTableType, anonType, excludeDefaults: false, sql: ref sqlFilter); + var sql = OrmLiteReadCommandExtensions.ToSelect(dbCmd.GetDialectProvider(), fromTableType, sqlFilter); + return dbCmd.ConvertToListAsync(sql, token); } internal static Task> SelectByIdsAsync(this IDbCommand dbCmd, IEnumerable idValues, CancellationToken token) { - var sql = idValues.GetIdsInSql(); - return sql == null + var sqlIn = dbCmd.SetIdsInSqlParams(idValues); + return string.IsNullOrEmpty(sqlIn) ? new List().InTask() - : SelectFmtAsync(dbCmd, token, dbCmd.GetDialectProvider().GetQuotedColumnName(ModelDefinition.PrimaryKeyName) + " IN (" + sql + ")"); + : SelectAsync(dbCmd, dbCmd.GetDialectProvider().GetQuotedColumnName(ModelDefinition.PrimaryKeyName) + " IN (" + sqlIn + ")", (object)null, token); } internal static Task SingleByIdAsync(this IDbCommand dbCmd, object value, CancellationToken token) { - if (!dbCmd.CanReuseParam(ModelDefinition.PrimaryKeyName)) - dbCmd.SetFilter(ModelDefinition.PrimaryKeyName, value); - - ((IDbDataParameter)dbCmd.Parameters[0]).Value = value; - + dbCmd.SetFilter(ModelDefinition.PrimaryKeyName, value); return dbCmd.ConvertToAsync(null, token); } internal static Task SingleWhereAsync(this IDbCommand dbCmd, string name, object value, CancellationToken token) { - if (!dbCmd.CanReuseParam(name)) - dbCmd.SetFilter(name, value); - - ((IDbDataParameter)dbCmd.Parameters[0]).Value = value; - + dbCmd.SetFilter(name, value); return dbCmd.ConvertToAsync(null, token); } internal static Task SingleAsync(this IDbCommand dbCmd, object anonType, CancellationToken token) { - dbCmd.SetFilters(anonType, excludeDefaults: false); + return dbCmd.SetFilters(anonType, excludeDefaults: false).ConvertToAsync(null, token); + } - return dbCmd.ConvertToAsync(null, token); + internal static Task SingleAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + return OrmLiteUtils.IsScalar() + ? dbCmd.ScalarAsync(sql, sqlParams, token) + : dbCmd.SetParameters(sqlParams).ConvertToAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token); } internal static Task SingleAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (OrmLiteUtils.IsScalar()) - return dbCmd.ScalarAsync(sql, anonType, token); - - dbCmd.SetParameters(anonType, excludeDefaults: false); - - return dbCmd.ConvertToAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token); + return OrmLiteUtils.IsScalar() + ? dbCmd.ScalarAsync(sql, anonType, token) + : dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).ConvertToAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token); } internal static Task> WhereAsync(this IDbCommand dbCmd, string name, object value, CancellationToken token) { - if (!dbCmd.CanReuseParam(name)) - dbCmd.SetFilter(name, value); - - ((IDbDataParameter)dbCmd.Parameters[0]).Value = value; - + dbCmd.SetFilter(name, value); return dbCmd.ConvertToListAsync(null, token); } internal static Task> WhereAsync(this IDbCommand dbCmd, object anonType, CancellationToken token) { - dbCmd.SetFilters(anonType); + return dbCmd.SetFilters(anonType).ConvertToListAsync(null, token); + } + internal static Task> SelectAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + dbCmd.SetParameters(sqlParams).CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); return dbCmd.ConvertToListAsync(null, token); } internal static Task> SelectAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); - dbCmd.CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); - + dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); return dbCmd.ConvertToListAsync(null, token); } internal static Task> SelectAsync(this IDbCommand dbCmd, string sql, Dictionary dict, CancellationToken token) { - if (dict != null) dbCmd.SetParameters((IDictionary)dict, (bool)false); - - dbCmd.CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); + dbCmd.SetParameters(dict, excludeDefaults: false, sql:ref sql).CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); + return dbCmd.ConvertToListAsync(null, token); + } + internal static Task> SqlListAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + dbCmd.SetParameters(sqlParams).CommandText = sql; return dbCmd.ConvertToListAsync(null, token); } internal static Task> SqlListAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); - dbCmd.CommandText = sql; - + dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).CommandText = sql; return dbCmd.ConvertToListAsync(null, token); } internal static Task> SqlListAsync(this IDbCommand dbCmd, string sql, Dictionary dict, CancellationToken token) { - if (dict != null) dbCmd.SetParameters(dict, false); - dbCmd.CommandText = sql; - + dbCmd.SetParameters(dict, excludeDefaults: false, sql:ref sql).CommandText = sql; return dbCmd.ConvertToListAsync(null, token); } internal static Task> SqlListAsync(this IDbCommand dbCmd, string sql, Action dbCmdFilter, CancellationToken token) { - if (dbCmdFilter != null) dbCmdFilter(dbCmd); + dbCmdFilter?.Invoke(dbCmd); dbCmd.CommandText = sql; return dbCmd.ConvertToListAsync(null, token); } - internal static Task> SqlColumnAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) + internal static Task> SqlColumnAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); - dbCmd.CommandText = sql; + dbCmd.SetParameters(sqlParams).CommandText = sql; + return dbCmd.ConvertToListAsync(null, token); + } + internal static Task> SqlColumnAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) + { + dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql).CommandText = sql; return dbCmd.ConvertToListAsync(null, token); } internal static Task> SqlColumnAsync(this IDbCommand dbCmd, string sql, Dictionary dict, CancellationToken token) { - if (dict != null) dbCmd.SetParameters(dict, false); - dbCmd.CommandText = sql; - + dbCmd.SetParameters(dict, excludeDefaults: false, sql:ref sql).CommandText = sql; return dbCmd.ConvertToListAsync(null, token); } - internal static Task SqlScalarAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) + internal static Task SqlScalarAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + return dbCmd.SetParameters(sqlParams).ScalarAsync(sql, token); + } - return dbCmd.ScalarAsync(sql, token); + internal static Task SqlScalarAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) + { + return dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).ScalarAsync(sql, token); } internal static Task SqlScalarAsync(this IDbCommand dbCmd, string sql, Dictionary dict, CancellationToken token) { - if (dict != null) dbCmd.SetParameters(dict, false); - - return dbCmd.ScalarAsync(sql, token); + return dbCmd.SetParameters(dict, excludeDefaults: false, sql:ref sql).ScalarAsync(sql, token); } internal static Task> SelectNonDefaultsAsync(this IDbCommand dbCmd, object filter, CancellationToken token) { - dbCmd.SetFilters(filter, excludeDefaults: true); - - return dbCmd.ConvertToListAsync(null, token); + return dbCmd.SetFilters(filter, excludeDefaults: true).ConvertToListAsync(null, token); } internal static Task> SelectNonDefaultsAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: true); - - return dbCmd.ConvertToListAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token); + return dbCmd.SetParameters(anonType, excludeDefaults: true, sql: ref sql).ConvertToListAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token); } internal static Task ScalarAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); - - return dbCmd.ScalarAsync(sql, token); - } - - internal static Task ScalarFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) - { - return dbCmd.ScalarAsync(sql.SqlFmt(sqlParams), token); + return dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).ScalarAsync(sql, token); } internal static Task ScalarAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) { return dialectProvider.ReaderRead(reader, () => - OrmLiteReadCommandExtensions.ToScalar(dialectProvider, reader.GetValue(0)), token); + OrmLiteReadCommandExtensions.ToScalar(dialectProvider, reader), token); } - public static Task LongScalarAsync(this IDbCommand dbCmd, CancellationToken token) + public static async Task LongScalarAsync(this IDbCommand dbCmd, CancellationToken token) { - return dbCmd.GetDialectProvider().ExecuteScalarAsync(dbCmd, token) - .Then(OrmLiteReadCommandExtensions.ToLong); + var ret = await dbCmd.GetDialectProvider().ExecuteScalarAsync(dbCmd, token).ConfigAwait(); + return OrmLiteReadCommandExtensions.ToLong(ret); } internal static Task> ColumnAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); return dbCmd.ColumnAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token); } - internal static Task> ColumnFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) + internal static async Task> ColumnAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) { - return dbCmd.ColumnAsync(sql.SqlFmt(sqlParams), token); - } - - internal static Task> ColumnAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) - { - return dialectProvider.ReaderEach(reader, () => + var ret = await dialectProvider.ReaderEach(reader, () => { - var value = dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(T)); + var value = dialectProvider.FromDbValue(reader, 0, typeof(T)); return value == DBNull.Value ? default(T) : value; - }, token) - .Then(x => - { - var columValues = new List(); - x.Each(o => columValues.Add((T)o)); - return columValues; - }); + }, token).ConfigAwait(); + + var columnValues = new List(); + ret.Each(o => columnValues.Add((T)o)); + return columnValues; } internal static Task> ColumnDistinctAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); return dbCmd.ColumnDistinctAsync(sql, token); } - internal static Task> ColumnDistinctFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) - { - return dbCmd.ColumnDistinctAsync(sql.SqlFmt(sqlParams), token); - } - - internal static Task> ColumnDistinctAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) + internal static async Task> ColumnDistinctAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) { - return dialectProvider.ReaderEach(reader, () => + var ret = await dialectProvider.ReaderEach(reader, () => { - var value = dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(T)); + var value = dialectProvider.FromDbValue(reader, 0, typeof(T)); return value == DBNull.Value ? default(T) : value; - }, token) - .Then(x => - { - var columValues = new HashSet(); - x.Each(o => columValues.Add((T)o)); - return columValues; - }); + }, token).ConfigAwait(); + + var columnValues = new HashSet(); + ret.Each(o => columnValues.Add((T)o)); + return columnValues; } internal static Task>> LookupAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { if (anonType != null) - dbCmd.SetParameters(anonType, (bool)false); + dbCmd.SetParameters(anonType.ToObjectDictionary(), (bool)false, sql:ref sql); return dbCmd.LookupAsync(sql, token); } - internal static Task>> LookupFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) - { - return dbCmd.LookupAsync(sql.SqlFmt(sqlParams), token); - } - internal static Task>> LookupAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) { var lookup = new Dictionary>(); return dialectProvider.ReaderEach(reader, () => { - var key = (K)dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(K)); - var value = (V)dialectProvider.ConvertDbValue(reader.GetValue(1), typeof(V)); + var key = (K)dialectProvider.FromDbValue(reader, 0, typeof(K)); + var value = (V)dialectProvider.FromDbValue(reader, 1, typeof(V)); - List values; - if (!lookup.TryGetValue(key, out values)) + if (!lookup.TryGetValue(key, out var values)) { values = new List(); lookup[key] = values; @@ -343,51 +289,60 @@ internal static Task>> LookupAsync(this IDataReader internal static Task> DictionaryAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { if (anonType != null) - dbCmd.SetParameters(anonType, excludeDefaults: false); + dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); return dbCmd.DictionaryAsync(sql, token); } - internal static Task> DictionaryFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFormat, params object[] sqlParams) - { - return dbCmd.DictionaryAsync(sqlFormat.SqlFmt(sqlParams), token); - } - internal static Task> DictionaryAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) { var map = new Dictionary(); return dialectProvider.ReaderEach(reader, () => { - var key = (K)dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(K)); - var value = (V)dialectProvider.ConvertDbValue(reader.GetValue(1), typeof(V)); + var key = (K)dialectProvider.FromDbValue(reader, 0, typeof(K)); + var value = (V)dialectProvider.FromDbValue(reader, 1, typeof(V)); map.Add(key, value); }, map, token); } - internal static Task ExistsAsync(this IDbCommand dbCmd, object anonType, CancellationToken token) + internal static Task>> KeyValuePairsAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: true); + if (anonType != null) + dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); - var sql = dbCmd.GetDialectProvider().ToExecuteProcedureStatement(anonType) - ?? dbCmd.GetFilterSql(); + return dbCmd.KeyValuePairsAsync(sql, token); + } - return dbCmd.ScalarAsync(sql, token).Then(x => x != null); + internal static Task>> KeyValuePairsAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) + { + var to = new List>(); + + return dialectProvider.ReaderEach(reader, () => + { + var key = (K)dialectProvider.FromDbValue(reader, 0, typeof(K)); + var value = (V)dialectProvider.FromDbValue(reader, 1, typeof(V)); + to.Add(new KeyValuePair(key, value)); + }, to, token); } - internal static Task ExistsAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) + internal static async Task ExistsAsync(this IDbCommand dbCmd, object anonType, CancellationToken token) { - if (anonType != null) dbCmd.SetParameters(anonType, (bool)false); + string sql = null; + if (anonType != null) dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: true, sql:ref sql); + + sql = dbCmd.GetFilterSql(); - return dbCmd.ScalarAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token) - .Then(x => x != null); + var ret = await dbCmd.ScalarAsync(sql, token).ConfigAwait(); + return ret != null; } - internal static Task ExistsFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFilter, params object[] filterParams) + internal static async Task ExistsAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - var fromTableType = typeof(T); - return dbCmd.ScalarAsync(dbCmd.GetDialectProvider().ToSelectStatement(fromTableType, sqlFilter, filterParams), token) - .Then(x => x != null); + if (anonType != null) dbCmd.SetParameters(anonType.ToObjectDictionary(), (bool)false, sql:ref sql); + + var ret = await dbCmd.ScalarAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql), token).ConfigAwait(); + return ret != null; } // procedures ... @@ -409,50 +364,67 @@ internal static Task> SqlProcedureFmtAsync(this return dbCmd.ConvertToListAsync(sql, token); } - internal static async Task LoadSingleByIdAsync(this IDbCommand dbCmd, object value, CancellationToken token) + internal static async Task LoadSingleByIdAsync(this IDbCommand dbCmd, object value, string[] include = null, CancellationToken token = default) { - var row = await dbCmd.SingleByIdAsync(value, token); + var row = await dbCmd.SingleByIdAsync(value, token).ConfigAwait(); if (row == null) return default(T); - await dbCmd.LoadReferencesAsync(row, token); + await dbCmd.LoadReferencesAsync(row, include, token).ConfigAwait(); return row; } - public static async Task LoadReferencesAsync(this IDbCommand dbCmd, T instance, CancellationToken token) + public static async Task LoadReferencesAsync(this IDbCommand dbCmd, T instance, string[] include = null, CancellationToken token = default) { var loadRef = new LoadReferencesAsync(dbCmd, instance); + var fieldDefs = loadRef.FieldDefs; - foreach (var fieldDef in loadRef.FieldDefs) + var includeSet = include != null + ? new HashSet(include, StringComparer.OrdinalIgnoreCase) + : null; + + foreach (var fieldDef in fieldDefs) { + if (includeSet != null && !includeSet.Contains(fieldDef.Name)) + continue; + dbCmd.Parameters.Clear(); var listInterface = fieldDef.FieldType.GetTypeWithGenericInterfaceOf(typeof(IList<>)); if (listInterface != null) { - await loadRef.SetRefFieldList(fieldDef, listInterface.GenericTypeArguments()[0], token); + await loadRef.SetRefFieldList(fieldDef, listInterface.GetGenericArguments()[0], token).ConfigAwait(); } else { - await loadRef.SetRefField(fieldDef, fieldDef.FieldType, token); + await loadRef.SetRefField(fieldDef, fieldDef.FieldType, token).ConfigAwait(); } } } - internal static async Task> LoadListWithReferences(this IDbCommand dbCmd, SqlExpression expr = null, CancellationToken token = default(CancellationToken)) + internal static async Task> LoadListWithReferences(this IDbCommand dbCmd, SqlExpression expr = null, IEnumerable include = null, CancellationToken token = default) { var loadList = new LoadListAsync(dbCmd, expr); - foreach (var fieldDef in loadList.FieldDefs) + var fieldDefs = loadList.FieldDefs; + + var includeSet = include != null + ? new HashSet(include, StringComparer.OrdinalIgnoreCase) + : null; + + foreach (var fieldDef in fieldDefs) { + if (includeSet != null && !includeSet.Contains(fieldDef.Name)) + continue; + var listInterface = fieldDef.FieldType.GetTypeWithGenericInterfaceOf(typeof(IList<>)); if (listInterface != null) { - await loadList.SetRefFieldListAsync(fieldDef, listInterface.GenericTypeArguments()[0], token); + await loadList.SetRefFieldListAsync(fieldDef, listInterface.GetGenericArguments()[0], token).ConfigAwait(); } else { - await loadList.SetRefFieldAsync(fieldDef, fieldDef.FieldType, token); + await loadList.SetRefFieldAsync(fieldDef, fieldDef.FieldType, token).ConfigAwait(); } } diff --git a/src/ServiceStack.OrmLite/Async/OrmLiteResultsFilterExtensionsAsync.cs b/src/ServiceStack.OrmLite/Async/OrmLiteResultsFilterExtensionsAsync.cs index 9064efc54..bc7929984 100644 --- a/src/ServiceStack.OrmLite/Async/OrmLiteResultsFilterExtensionsAsync.cs +++ b/src/ServiceStack.OrmLite/Async/OrmLiteResultsFilterExtensionsAsync.cs @@ -1,5 +1,5 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; @@ -8,124 +8,185 @@ using System.Data; using System.Threading; using System.Threading.Tasks; +using ServiceStack.Logging; +using ServiceStack.Text; namespace ServiceStack.OrmLite { - internal static class OrmLiteResultsFilterExtensionsAsync + public static class OrmLiteResultsFilterExtensionsAsync { - internal static Task ExecNonQueryAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) + internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteResultsFilterExtensionsAsync)); + + public static Task ExecNonQueryAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token = default) { if (anonType != null) - dbCmd.SetParameters(anonType, (bool)false); + dbCmd.SetParameters(anonType.ToObjectDictionary(), (bool)false, sql:ref sql); dbCmd.CommandText = sql; + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd).InTask(); + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + return dbCmd.GetDialectProvider().ExecuteNonQueryAsync(dbCmd, token); } - internal static Task ExecNonQueryAsync(this IDbCommand dbCmd, string sql, IDictionary dict, CancellationToken token) + public static Task ExecNonQueryAsync(this IDbCommand dbCmd, string sql, Dictionary dict, CancellationToken token = default) { if (dict != null) - dbCmd.SetParameters(dict, (bool)false); + dbCmd.SetParameters(dict, (bool)false, sql:ref sql); dbCmd.CommandText = sql; + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd).InTask(); + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + return dbCmd.GetDialectProvider().ExecuteNonQueryAsync(dbCmd, token); } - internal static Task ExecNonQueryAsync(this IDbCommand dbCmd, CancellationToken token) + public static Task ExecNonQueryAsync(this IDbCommand dbCmd, CancellationToken token = default) { + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd).InTask(); + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + return dbCmd.GetDialectProvider().ExecuteNonQueryAsync(dbCmd, token); } - public static Task> ConvertToListAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + public static Task> ConvertToListAsync(this IDbCommand dbCmd) + { + return dbCmd.ConvertToListAsync(null, default(CancellationToken)); + } + + public static async Task> ConvertToListAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetList(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetList(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => - OrmLiteUtils.IsScalar() - ? reader.ColumnAsync(dialectProvider, token) - : reader.ConvertToListAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + if (OrmLiteUtils.IsScalar()) + return await reader.ColumnAsync(dialectProvider, token).ConfigAwait(); + + return await reader.ConvertToListAsync(dialectProvider, null, token).ConfigAwait(); + } + + public static Task ConvertToListAsync(this IDbCommand dbCmd, Type refType) + { + return dbCmd.ConvertToListAsync(refType, null, default(CancellationToken)); } - public static Task ConvertToListAsync(this IDbCommand dbCmd, Type refType, string sql, CancellationToken token) + public static async Task ConvertToListAsync(this IDbCommand dbCmd, Type refType, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetRefList(dbCmd, refType).InTask(); + return OrmLiteConfig.ResultsFilter.GetRefList(dbCmd, refType); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ConvertToListAsync(dialectProvider, refType, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ConvertToListAsync(dialectProvider, refType, token).ConfigAwait(); } - internal static Task> ExprConvertToListAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static async Task> ExprConvertToListAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, HashSet onlyFields, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; + dbCmd.SetParameters(sqlParams); + if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetList(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetList(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ExprConvertToListAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ConvertToListAsync(dialectProvider, onlyFields, token).ConfigAwait(); } - public static Task ConvertToAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + public static Task ConvertToAsync(this IDbCommand dbCmd) + { + return dbCmd.ConvertToAsync(null, default(CancellationToken)); + } + + public static async Task ConvertToAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetSingle(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetSingle(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ConvertToAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ConvertToAsync(dialectProvider, token).ConfigAwait(); } - internal static Task ConvertToAsync(this IDbCommand dbCmd, Type refType, string sql, CancellationToken token) + internal static async Task ConvertToAsync(this IDbCommand dbCmd, Type refType, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetRefSingle(dbCmd, refType).InTask(); + return OrmLiteConfig.ResultsFilter.GetRefSingle(dbCmd, refType); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ConvertToAsync(dialectProvider, refType, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ConvertToAsync(dialectProvider, refType, token).ConfigAwait(); + } + + public static Task ScalarAsync(this IDbCommand dbCmd) + { + return dbCmd.ScalarAsync(null, default(CancellationToken)); } - public static Task ScalarAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + public static Task ScalarAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + return dbCmd.SetParameters(sqlParams).ScalarAsync(sql, token); + } + + public static async Task ScalarAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetScalar(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetScalar(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ScalarAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ScalarAsync(dialectProvider, token).ConfigAwait(); + } + + public static Task ScalarAsync(this IDbCommand dbCmd) + { + return dbCmd.ScalarAsync((string)null, default(CancellationToken)); + } + + public static Task ScalarAsync(this IDbCommand dbCmd, ISqlExpression expression, CancellationToken token) + { + dbCmd.PopulateWith(expression, QueryType.Scalar); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.GetScalar(dbCmd).InTask(); + + return dbCmd.GetDialectProvider().ExecuteScalarAsync(dbCmd, token); } public static Task ScalarAsync(this IDbCommand dbCmd, string sql, CancellationToken token) @@ -139,80 +200,130 @@ public static Task ScalarAsync(this IDbCommand dbCmd, string sql, Cancel return dbCmd.GetDialectProvider().ExecuteScalarAsync(dbCmd, token); } - internal static Task ExecLongScalarAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + public static Task ExecLongScalarAsync(this IDbCommand dbCmd) + { + return dbCmd.ExecLongScalarAsync(null, default); + } + + public static Task ExecLongScalarAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) return OrmLiteConfig.ResultsFilter.GetLongScalar(dbCmd).InTask(); return dbCmd.LongScalarAsync(token); } - internal static Task ExprConvertToAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static async Task ExprConvertToAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + if (sql != null) + dbCmd.CommandText = sql; + + dbCmd.SetParameters(sqlParams); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.GetSingle(dbCmd); + + var dialectProvider = dbCmd.GetDialectProvider(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ConvertToAsync(dialectProvider, token).ConfigAwait(); + } + + internal static Task> ColumnAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + return dbCmd.SetParameters(sqlParams).ColumnAsync(sql, token); + } + + internal static async Task> ColumnAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetSingle(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetColumn(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ConvertToAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ColumnAsync(dialectProvider, token).ConfigAwait(); } - internal static Task> ColumnAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static Task> ColumnDistinctAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + return dbCmd.SetParameters(sqlParams).ColumnDistinctAsync(sql, token); + } + + internal static async Task> ColumnDistinctAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetColumn(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetColumnDistinct(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ColumnAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.ColumnDistinctAsync(dialectProvider, token).ConfigAwait(); + } + + internal static Task> DictionaryAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + return dbCmd.SetParameters(sqlParams).DictionaryAsync(sql, token); } - internal static Task> ColumnDistinctAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static async Task> DictionaryAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetColumnDistinct(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetDictionary(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.ColumnDistinctAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.DictionaryAsync(dialectProvider, token).ConfigAwait(); + } + + internal static Task>> KeyValuePairsAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + return dbCmd.SetParameters(sqlParams).KeyValuePairsAsync(sql, token); } - internal static Task> DictionaryAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static async Task>> KeyValuePairsAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetDictionary(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetKeyValuePairs(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.DictionaryAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.KeyValuePairsAsync(dialectProvider, token).ConfigAwait(); + } + + internal static Task>> LookupAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) + { + return dbCmd.SetParameters(sqlParams).LookupAsync(sql, token); } - internal static Task>> LookupAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static async Task>> LookupAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - return OrmLiteConfig.ResultsFilter.GetLookup(dbCmd).InTask(); + return OrmLiteConfig.ResultsFilter.GetLookup(dbCmd); var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecReaderAsync(dbCmd.CommandText, token) - .Then(reader => reader.LookupAsync(dialectProvider, token)).Unwrap(); + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return await reader.LookupAsync(dialectProvider, token).ConfigAwait(); } } } diff --git a/src/ServiceStack.OrmLite/Async/OrmLiteUtilExtensionsAsync.cs b/src/ServiceStack.OrmLite/Async/OrmLiteUtilExtensionsAsync.cs index 111f78ad4..37cb3487d 100644 --- a/src/ServiceStack.OrmLite/Async/OrmLiteUtilExtensionsAsync.cs +++ b/src/ServiceStack.OrmLite/Async/OrmLiteUtilExtensionsAsync.cs @@ -1,13 +1,16 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; using System.Collections; using System.Collections.Generic; using System.Data; +using System.Dynamic; +using System.Linq; using System.Threading; using System.Threading.Tasks; +using ServiceStack.Text; namespace ServiceStack.OrmLite { @@ -18,73 +21,146 @@ public static T CreateInstance() return (T)ReflectionExtensions.CreateInstance(); } - public static Task ConvertToAsync(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) + public static async Task ConvertToAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) { - var fieldDefs = ModelDefinition.Definition.AllFieldDefinitionsArray; - return dialectProvider.ReaderRead(dataReader, () => + using (reader) + return await dialectProvider.ReaderRead(reader, () => { + if (typeof(T) == typeof(List)) + return (T) (object) reader.ConvertToListObjects(); + + if (typeof(T) == typeof(Dictionary)) + return (T) (object) reader.ConvertToDictionaryObjects(); + + var values = new object[reader.FieldCount]; + + if (typeof(T).IsValueTuple()) + return reader.ConvertToValueTuple(values, dialectProvider); + var row = CreateInstance(); - var indexCache = dataReader.GetIndexFieldsCache(ModelDefinition.Definition); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); return row; - }, token).Then(t => { - dataReader.Dispose(); - return t; - }); + }, token).ConfigAwait(); } - public static Task> ConvertToListAsync(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) + public static async Task> ConvertToListAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, HashSet onlyFields, CancellationToken token) { - var fieldDefs = ModelDefinition.Definition.AllFieldDefinitionsArray; - var indexCache = dataReader.GetIndexFieldsCache(ModelDefinition.Definition); - return dialectProvider.ReaderEach(dataReader, () => + if (typeof(T) == typeof(List)) { - var row = CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); - return row; - }, token).Then(t => { - dataReader.Dispose(); - return t; - }); + using (reader) + { + return await dialectProvider.ReaderEach(reader, () => + { + var row = reader.ConvertToListObjects(); + return (T) (object) row; + }, token).ConfigAwait(); + } + } + if (typeof(T) == typeof(Dictionary)) + { + using (reader) + { + return await dialectProvider.ReaderEach(reader, () => + { + var row = reader.ConvertToDictionaryObjects(); + return (T) (object) row; + }, token).ConfigAwait(); + } + } + if (typeof(T) == typeof(object)) + { + using (reader) + { + return await dialectProvider.ReaderEach(reader, () => + { + var row = reader.ConvertToExpandoObject(); + return (T) (object) row; + }, token).ConfigAwait(); + } + } + if (typeof(T).IsValueTuple()) + { + using (reader) + { + var values = new object[reader.FieldCount]; + return await dialectProvider.ReaderEach(reader, () => + { + var row = reader.ConvertToValueTuple(values, dialectProvider); + return row; + }, token).ConfigAwait(); + } + } + if (typeof(T).IsTuple()) + { + var genericArgs = typeof(T).GetGenericArguments(); + var modelIndexCaches = reader.GetMultiIndexCaches(dialectProvider, onlyFields, genericArgs); + + var values = new object[reader.FieldCount]; + var genericTupleMi = typeof(T).GetGenericTypeDefinition().GetCachedGenericType(genericArgs); + var activator = genericTupleMi.GetConstructor(genericArgs).GetActivator(); + + using (reader) + { + return await dialectProvider.ReaderEach(reader, () => + { + var tupleArgs = reader.ToMultiTuple(dialectProvider, modelIndexCaches, genericArgs, values); + var tuple = activator(tupleArgs.ToArray()); + return (T) tuple; + }, token).ConfigAwait(); + } + } + else + { + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider, onlyFields:onlyFields); + var values = new object[reader.FieldCount]; + + using (reader) + { + return await dialectProvider.ReaderEach(reader, () => + { + var row = CreateInstance(); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); + return row; + }, token).ConfigAwait(); + } + } } - public static Task ConvertToAsync(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, Type type, CancellationToken token) + public static async Task ConvertToAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, Type type, CancellationToken token) { var modelDef = type.GetModelDefinition(); - var fieldDefs = modelDef.AllFieldDefinitionsArray; - - return dialectProvider.ReaderRead(dataReader, () => + var indexCache = reader.GetIndexFieldsCache(modelDef, dialectProvider); + var values = new object[reader.FieldCount]; + + using (reader) + return await dialectProvider.ReaderRead(reader, () => { var row = type.CreateInstance(); - var indexCache = dataReader.GetIndexFieldsCache(modelDef); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); return row; - }, token).Then(t => - { - dataReader.Dispose(); - return t; - }); + }, token).ConfigAwait(); } - public static Task ConvertToListAsync(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, Type type, CancellationToken token) + public static async Task ConvertToListAsync(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, Type type, CancellationToken token) { var modelDef = type.GetModelDefinition(); - var fieldDefs = modelDef.AllFieldDefinitionsArray; + var indexCache = reader.GetIndexFieldsCache(modelDef, dialectProvider); + var values = new object[reader.FieldCount]; - var indexCache = dataReader.GetIndexFieldsCache(modelDef); - return dialectProvider.ReaderEach(dataReader, () => + using (reader) { - var row = type.CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); - return row; - }, token) - .Then(x => - { - dataReader.Dispose(); - var to = (IList)typeof(List<>).MakeGenericType(type).CreateInstance(); - x.Each(o => to.Add(o)); + var ret = await dialectProvider.ReaderEach(reader, () => + { + var row = type.CreateInstance(); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); + return row; + }, token).ConfigAwait(); + + var to = (IList)typeof(List<>).GetCachedGenericType(type).CreateInstance(); + ret.Each(o => to.Add(o)); return to; - }); + } } } } diff --git a/src/ServiceStack.OrmLite/Async/OrmLiteWriteCommandExtensionsAsync.cs b/src/ServiceStack.OrmLite/Async/OrmLiteWriteCommandExtensionsAsync.cs index f2749afd9..d55010d2f 100644 --- a/src/ServiceStack.OrmLite/Async/OrmLiteWriteCommandExtensionsAsync.cs +++ b/src/ServiceStack.OrmLite/Async/OrmLiteWriteCommandExtensionsAsync.cs @@ -1,69 +1,125 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; using System.Collections; using System.Collections.Generic; using System.Data; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using ServiceStack.Data; using ServiceStack.Logging; +using ServiceStack.Text; namespace ServiceStack.OrmLite { internal static class OrmLiteWriteCommandExtensionsAsync { - private static readonly ILog Log = LogManager.GetLogger(typeof(OrmLiteWriteCommandExtensionsAsync)); + internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteWriteCommandExtensionsAsync)); - private static void LogDebug(string fmt) + internal static Task ExecuteSqlAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) => + dbCmd.SetParameters(sqlParams).ExecuteSqlAsync(sql, (Action) null, token); + + internal static Task ExecuteSqlAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, + Action commandFilter, CancellationToken token) { - Log.Debug(fmt); + return dbCmd.SetParameters(sqlParams).ExecuteSqlAsync(sql, commandFilter, token); } - internal static Task ExecuteSqlAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static Task ExecuteSqlAsync(this IDbCommand dbCmd, string sql, CancellationToken token) => + dbCmd.ExecuteSqlAsync(sql,(Action)null, token); + + internal static Task ExecuteSqlAsync(this IDbCommand dbCmd, string sql, + Action commandFilter, CancellationToken token) { + dbCmd.CommandText = sql; + + commandFilter?.Invoke(dbCmd); + if (Log.IsDebugEnabled) - LogDebug(sql); + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd).InTask(); + + return dbCmd.GetDialectProvider().ExecuteNonQueryAsync(dbCmd, token); + } + + internal static Task ExecuteSqlAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) => + dbCmd.ExecuteSqlAsync(sql, anonType, null, token); + + internal static Task ExecuteSqlAsync(this IDbCommand dbCmd, string sql, object anonType, + Action commandFilter, CancellationToken token) + { + if (anonType != null) + dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); dbCmd.CommandText = sql; + commandFilter?.Invoke(dbCmd); + + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd).InTask(); - return dbCmd.GetDialectProvider().ExecuteNonQueryAsync(dbCmd); + return dbCmd.GetDialectProvider().ExecuteNonQueryAsync(dbCmd, token); + } + + internal static Task UpdateAsync(this IDbCommand dbCmd, T obj, CancellationToken token, Action commandFilter = null) + { + return dbCmd.UpdateInternalAsync(obj, token, commandFilter); + } + + internal static Task UpdateAsync(this IDbCommand dbCmd, Dictionary obj, CancellationToken token, Action commandFilter = null) + { + return dbCmd.UpdateInternalAsync(obj, token, commandFilter); } - internal static Task UpdateAsync(this IDbCommand dbCmd, T obj, CancellationToken token) + internal static async Task UpdateInternalAsync(this IDbCommand dbCmd, object obj, CancellationToken token, Action commandFilter=null) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, obj); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, obj.ToFilterType()); var dialectProvider = dbCmd.GetDialectProvider(); var hadRowVersion = dialectProvider.PrepareParameterizedUpdateStatement(dbCmd); if (string.IsNullOrEmpty(dbCmd.CommandText)) - return TaskResult.Zero; + return 0; dialectProvider.SetParameterValues(dbCmd, obj); - return dialectProvider.ExecuteNonQueryAsync(dbCmd) - .Then(rowsUpdated => - { - if (hadRowVersion && rowsUpdated == 0) - throw new OptimisticConcurrencyException(); - return rowsUpdated; - }); + return await dbCmd.UpdateAndVerifyAsync(commandFilter, hadRowVersion, token).ConfigAwait(); } - internal static Task UpdateAsync(this IDbCommand dbCmd, CancellationToken token, params T[] objs) + internal static async Task UpdateAndVerifyAsync(this IDbCommand dbCmd, Action commandFilter, bool hadRowVersion, CancellationToken token) { - return dbCmd.UpdateAllAsync(objs, token); + commandFilter?.Invoke(dbCmd); + var rowsUpdated = await dbCmd.ExecNonQueryAsync(token).ConfigAwait(); + + if (hadRowVersion && rowsUpdated == 0) + throw new OptimisticConcurrencyException(); + + return rowsUpdated; } - internal static Task UpdateAllAsync(this IDbCommand dbCmd, IEnumerable objs, CancellationToken token) + internal static Task UpdateAsync(this IDbCommand dbCmd, Action commandFilter, CancellationToken token, T[] objs) { + return dbCmd.UpdateAllAsync(objs, commandFilter, token); + } + + internal static async Task UpdateAllAsync(this IDbCommand dbCmd, IEnumerable objs, Action commandFilter, CancellationToken token) + { + OrmLiteUtils.AssertNotAnonType(); + IDbTransaction dbTrans = null; int count = 0; @@ -74,44 +130,39 @@ internal static Task UpdateAllAsync(this IDbCommand dbCmd, IEnumerable(dbCmd); if (string.IsNullOrEmpty(dbCmd.CommandText)) - return TaskResult.Zero; + return 0; - return objs.EachAsync((obj, i) => + using (dbTrans) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, obj); - - dialectProvider.SetParameterValues(dbCmd, obj); - - return dbCmd.ExecNonQueryAsync(token).Then(rowsUpdated => + foreach (var obj in objs) { + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, obj); + + dialectProvider.SetParameterValues(dbCmd, obj); + + commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once + commandFilter = null; + + var rowsUpdated = await dbCmd.ExecNonQueryAsync(token).ConfigAwait(); + if (hadRowVersion && rowsUpdated == 0) throw new OptimisticConcurrencyException(); - + count += rowsUpdated; - return count; - }); - }).ContinueWith(t => - { - if (dbTrans != null && t.IsSuccess()) - dbTrans.Commit(); - - if (dbTrans != null) - dbTrans.Dispose(); + } - return count; - }); + dbTrans?.Commit(); + } + return count; } - private static Task AssertRowsUpdatedAsync(IDbCommand dbCmd, bool hadRowVersion, CancellationToken token) + private static async Task AssertRowsUpdatedAsync(IDbCommand dbCmd, bool hadRowVersion, CancellationToken token) { - return dbCmd.ExecNonQueryAsync(token).Then(rowsUpdated => - { - if (hadRowVersion && rowsUpdated == 0) - throw new OptimisticConcurrencyException(); + var rowsUpdated = await dbCmd.ExecNonQueryAsync(token).ConfigAwait(); + if (hadRowVersion && rowsUpdated == 0) + throw new OptimisticConcurrencyException(); - return rowsUpdated; - }); + return rowsUpdated; } internal static Task DeleteAsync(this IDbCommand dbCmd, T filter, CancellationToken token) @@ -121,6 +172,8 @@ internal static Task DeleteAsync(this IDbCommand dbCmd, T filter, Cancel internal static Task DeleteAsync(this IDbCommand dbCmd, object anonType, CancellationToken token) { + OrmLiteUtils.AssertNotAnonType(); + var dialectProvider = dbCmd.GetDialectProvider(); var hadRowVersion = dialectProvider.PrepareParameterizedDeleteStatement( @@ -133,6 +186,8 @@ internal static Task DeleteAsync(this IDbCommand dbCmd, object anonType, internal static Task DeleteNonDefaultsAsync(this IDbCommand dbCmd, T filter, CancellationToken token) { + OrmLiteUtils.AssertNotAnonType(); + var dialectProvider = dbCmd.GetDialectProvider(); var hadRowVersion = dialectProvider.PrepareParameterizedDeleteStatement( dbCmd, filter.AllFieldsMap().NonDefaultsOnly()); @@ -155,11 +210,14 @@ internal static Task DeleteNonDefaultsAsync(this IDbCommand dbCmd, Cance if (filters.Length == 0) return TaskResult.Zero; - return DeleteAllAsync(dbCmd, filters, o => o.AllFieldsMap().NonDefaultsOnly(), token); + return DeleteAllAsync(dbCmd, filters, o => o.AllFieldsMap().NonDefaultsOnly(), token:token); } - private static Task DeleteAllAsync(IDbCommand dbCmd, IEnumerable objs, Func> fieldValuesFn = null, CancellationToken token=default(CancellationToken)) + private static async Task DeleteAllAsync(IDbCommand dbCmd, IEnumerable objs, Func> fieldValuesFn = null, + Action commandFilter=null, CancellationToken token=default) { + OrmLiteUtils.AssertNotAnonType(); + IDbTransaction dbTrans = null; int count = 0; @@ -168,57 +226,61 @@ private static Task DeleteAllAsync(IDbCommand dbCmd, IEnumerable objs var dialectProvider = dbCmd.GetDialectProvider(); - return objs.EachAsync((obj, i) => + using (dbTrans) { - var fieldValues = fieldValuesFn != null - ? fieldValuesFn(obj) - : obj.AllFieldsMap(); - - dialectProvider.PrepareParameterizedDeleteStatement(dbCmd, fieldValues); + foreach (var obj in objs) + { + var fieldValues = fieldValuesFn != null + ? fieldValuesFn(obj) + : obj.AllFieldsMap(); - dialectProvider.SetParameterValues(dbCmd, obj); + dialectProvider.PrepareParameterizedDeleteStatement(dbCmd, fieldValues); - return dbCmd.ExecNonQueryAsync(token) - .Then(rowsAffected => count += rowsAffected); - }) - .ContinueWith(t => { - if (dbTrans != null && t.IsSuccess()) - dbTrans.Commit(); + dialectProvider.SetParameterValues(dbCmd, obj); + + commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once + commandFilter = null; - if (dbTrans != null) - dbTrans.Dispose(); + var rowsAffected = await dbCmd.ExecNonQueryAsync(token).ConfigAwait(); + count += rowsAffected; + } + dbTrans?.Commit(); + } - return count; - }); + return count; } - internal static Task DeleteByIdAsync(this IDbCommand dbCmd, object id, CancellationToken token) + internal static Task DeleteByIdAsync(this IDbCommand dbCmd, object id, + Action commandFilter, CancellationToken token) { + OrmLiteUtils.AssertNotAnonType(); + var sql = dbCmd.DeleteByIdSql(id); - return dbCmd.ExecuteSqlAsync(sql, token); + return dbCmd.ExecuteSqlAsync(sql, commandFilter, token); } - internal static Task DeleteByIdAsync(this IDbCommand dbCmd, object id, ulong rowVersion, CancellationToken token) + internal static async Task DeleteByIdAsync(this IDbCommand dbCmd, object id, ulong rowVersion, + Action commandFilter, CancellationToken token) { + OrmLiteUtils.AssertNotAnonType(); + var sql = dbCmd.DeleteByIdSql(id, rowVersion); - return dbCmd.ExecuteSqlAsync(sql, token).Then(rowsAffected => { - if (rowsAffected == 0) - throw new OptimisticConcurrencyException("The row was modified or deleted since the last read"); - - return TaskResult.Finished; - }); + var rowsAffected = await dbCmd.ExecuteSqlAsync(sql, commandFilter, token).ConfigAwait(); + if (rowsAffected == 0) + throw new OptimisticConcurrencyException("The row was modified or deleted since the last read"); } - internal static Task DeleteByIdsAsync(this IDbCommand dbCmd, IEnumerable idValues, CancellationToken token) + internal static Task DeleteByIdsAsync(this IDbCommand dbCmd, IEnumerable idValues, + Action commandFilter, CancellationToken token) { - var sqlIn = idValues.GetIdsInSql(); - if (sqlIn == null) + var sqlIn = dbCmd.SetIdsInSqlParams(idValues); + if (string.IsNullOrEmpty(sqlIn)) return TaskResult.Zero; var sql = OrmLiteWriteCommandExtensions.GetDeleteByIdsSql(sqlIn, dbCmd.GetDialectProvider()); - return dbCmd.ExecuteSqlAsync(sql, token); + return dbCmd.ExecuteSqlAsync(sql, commandFilter, token); } internal static Task DeleteAllAsync(this IDbCommand dbCmd, CancellationToken token) @@ -232,40 +294,156 @@ internal static Task DeleteAllAsync(this IDbCommand dbCmd, Type tableType, return dbCmd.ExecuteSqlAsync(dialectProvider.ToDeleteStatement(tableType, null), token); } - internal static Task DeleteFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFilter, params object[] filterParams) + internal static Task DeleteAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - return DeleteFmtAsync(dbCmd, token, typeof(T), sqlFilter, filterParams); + OrmLiteUtils.AssertNotAnonType(); + + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); + return dbCmd.ExecuteSqlAsync(dbCmd.GetDialectProvider().ToDeleteStatement(typeof(T), sql), token); } - internal static Task DeleteFmtAsync(this IDbCommand dbCmd, CancellationToken token, Type tableType, string sqlFilter, params object[] filterParams) + internal static Task DeleteAsync(this IDbCommand dbCmd, Type tableType, string sql, object anonType, CancellationToken token) { + if (anonType != null) dbCmd.SetParameters(tableType, anonType, excludeDefaults: false, sql: ref sql); + return dbCmd.ExecuteSqlAsync(dbCmd.GetDialectProvider().ToDeleteStatement(tableType, sql), token); + } + + internal static async Task InsertAsync(this IDbCommand dbCmd, T obj, Action commandFilter, bool selectIdentity, bool enableIdentityInsert,CancellationToken token) + { + OrmLiteUtils.AssertNotAnonType(); + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); + var dialectProvider = dbCmd.GetDialectProvider(); - return dbCmd.ExecuteSqlAsync(dialectProvider.ToDeleteStatement(tableType, sqlFilter, filterParams), token); + var pkField = ModelDefinition.Definition.FieldDefinitions.FirstOrDefault(f => f.IsPrimaryKey); + if (!enableIdentityInsert || pkField == null || !pkField.AutoIncrement) + { + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, + insertFields: dialectProvider.GetNonDefaultValueInsertFields(obj)); + return await InsertInternalAsync(dialectProvider, dbCmd, obj, commandFilter, selectIdentity, token).ConfigAwait(); + } + else + { + try + { + await dialectProvider.EnableIdentityInsertAsync(dbCmd, token); + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, + insertFields: dialectProvider.GetNonDefaultValueInsertFields(obj), + shouldInclude: f => f == pkField); + await InsertInternalAsync(dialectProvider, dbCmd, obj, commandFilter, selectIdentity, token).ConfigAwait(); + if (selectIdentity) + { + var id = pkField.GetValue(obj); + return Convert.ToInt64(id); + } + + return default; + } + finally + { + await dialectProvider.DisableIdentityInsertAsync(dbCmd, token); + } + } } - internal static Task InsertAsync(this IDbCommand dbCmd, T obj, bool selectIdentity, CancellationToken token) + internal static async Task InsertAsync(this IDbCommand dbCmd, Dictionary obj, Action commandFilter, bool selectIdentity, CancellationToken token) { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, obj); + OrmLiteUtils.AssertNotAnonType(); + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj.ToFilterType()); var dialectProvider = dbCmd.GetDialectProvider(); + var pkField = ModelDefinition.Definition.PrimaryKey; + object id = null; + var enableIdentityInsert = pkField?.AutoIncrement == true && obj.TryGetValue(pkField.Name, out id); + + try + { + if (enableIdentityInsert) + await dialectProvider.EnableIdentityInsertAsync(dbCmd, token).ConfigAwait(); + + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, + insertFields: dialectProvider.GetNonDefaultValueInsertFields(obj), + shouldInclude: f => obj.ContainsKey(f.Name)); + + var ret = await InsertInternalAsync(dialectProvider, dbCmd, obj, commandFilter, selectIdentity, token).ConfigAwait(); + if (enableIdentityInsert) + return Convert.ToInt64(id); + return ret; + } + finally + { + if (enableIdentityInsert) + await dialectProvider.DisableIdentityInsertAsync(dbCmd, token).ConfigAwait(); + } + } + + private static async Task InsertInternalAsync(IOrmLiteDialectProvider dialectProvider, + IDbCommand dbCmd, object obj, Action commandFilter, bool selectIdentity, CancellationToken token) + { + OrmLiteUtils.AssertNotAnonType(); - dialectProvider.PrepareParameterizedInsertStatement(dbCmd); dialectProvider.SetParameterValues(dbCmd, obj); + commandFilter?.Invoke(dbCmd); + + if (dialectProvider.HasInsertReturnValues(ModelDefinition.Definition)) + { + using var reader = await dbCmd.ExecReaderAsync(dbCmd.CommandText, token).ConfigAwait(); + return reader.PopulateReturnValues(dialectProvider, obj); + } + if (selectIdentity) - return dialectProvider.InsertAndGetLastInsertIdAsync(dbCmd, token); + { + dbCmd.CommandText += dialectProvider.GetLastInsertIdSqlSuffix(); + + return await dbCmd.ExecLongScalarAsync().ConfigAwait(); + } - return dbCmd.ExecNonQueryAsync(token).Then(i => (long)i); + return await dbCmd.ExecNonQueryAsync(token).ConfigAwait(); } - internal static Task InsertAsync(this IDbCommand dbCmd, CancellationToken token, params T[] objs) + internal static Task InsertAsync(this IDbCommand dbCmd, Action commandFilter, CancellationToken token, T[] objs) { - return InsertAllAsync(dbCmd, objs, token); + return InsertAllAsync(dbCmd, objs, commandFilter, token); } + + internal static async Task InsertUsingDefaultsAsync(this IDbCommand dbCmd, T[] objs, CancellationToken token) + { + IDbTransaction dbTrans = null; + + if (dbCmd.Transaction == null) + dbCmd.Transaction = dbTrans = dbCmd.Connection.BeginTransaction(); + + var dialectProvider = dbCmd.GetDialectProvider(); - internal static Task InsertAllAsync(this IDbCommand dbCmd, IEnumerable objs, CancellationToken token) + var modelDef = typeof(T).GetModelDefinition(); + var fieldsWithoutDefaults = modelDef.FieldDefinitionsArray + .Where(x => x.DefaultValue == null) + .Select(x => x.Name) + .ToSet(); + + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, insertFields: fieldsWithoutDefaults); + + using (dbTrans) + { + foreach (var obj in objs) + { + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); + + dialectProvider.SetParameterValues(dbCmd, obj); + + await dbCmd.ExecNonQueryAsync(token).ConfigAwait(); + } + dbTrans?.Commit(); + } + } + + internal static async Task InsertIntoSelectAsync(this IDbCommand dbCmd, ISqlExpression query, Action commandFilter, CancellationToken token) => + OrmLiteReadCommandExtensions.ToLong(await dbCmd.InsertIntoSelectInternal(query, commandFilter).ExecNonQueryAsync(token: token).ConfigAwait()); + + internal static async Task InsertAllAsync(this IDbCommand dbCmd, IEnumerable objs, Action commandFilter, CancellationToken token) { + OrmLiteUtils.AssertNotAnonType(); + IDbTransaction dbTrans = null; if (dbCmd.Transaction == null) @@ -275,26 +453,23 @@ internal static Task InsertAllAsync(this IDbCommand dbCmd, IEnumerable obj dialectProvider.PrepareParameterizedInsertStatement(dbCmd); - return objs.EachAsync((obj, i) => + using (dbTrans) { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, obj); + foreach (var obj in objs) + { + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); - dialectProvider.SetParameterValues(dbCmd, obj); + dialectProvider.SetParameterValues(dbCmd, obj); - return dbCmd.ExecNonQueryAsync(token); - }) - .ContinueWith(t => - { - if (dbTrans != null && t.IsSuccess()) - dbTrans.Commit(); + commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once + commandFilter = null; - if (dbTrans != null) - dbTrans.Dispose(); - }); + await dbCmd.ExecNonQueryAsync(token).ConfigAwait(); + } + dbTrans?.Commit(); + } } - internal static Task SaveAsync(this IDbCommand dbCmd, CancellationToken token, params T[] objs) { return SaveAllAsync(dbCmd, objs, token); @@ -302,56 +477,58 @@ internal static Task SaveAsync(this IDbCommand dbCmd, CancellationToken internal static async Task SaveAsync(this IDbCommand dbCmd, T obj, CancellationToken token) { - var id = obj.GetId(); - var existingRow = id != null ? await dbCmd.SingleByIdAsync(id, token) : default(T); + OrmLiteUtils.AssertNotAnonType(); + var modelDef = typeof(T).GetModelDefinition(); + var id = modelDef.GetPrimaryKey(obj); + var existingRow = id != null ? await dbCmd.SingleByIdAsync(id, token).ConfigAwait() : default(T); if (Equals(existingRow, default(T))) { if (modelDef.HasAutoIncrementId) { - var newId = await dbCmd.InsertAsync(obj, selectIdentity: true, token:token); - var safeId = dbCmd.GetDialectProvider().ConvertDbValue(newId, modelDef.PrimaryKey.FieldType); - modelDef.PrimaryKey.SetValueFn(obj, safeId); + var newId = await dbCmd.InsertAsync(obj, commandFilter: null, selectIdentity: true, enableIdentityInsert:false, token:token).ConfigAwait(); + var safeId = dbCmd.GetDialectProvider().FromDbValue(newId, modelDef.PrimaryKey.FieldType); + modelDef.PrimaryKey.SetValue(obj, safeId); id = newId; } else { - await dbCmd.InsertAsync(token, obj); + await dbCmd.InsertAsync(obj, commandFilter:null, selectIdentity:false, enableIdentityInsert: false, token: token).ConfigAwait(); } - if (modelDef.RowVersion != null) - modelDef.RowVersion.SetValueFn(obj, await dbCmd.GetRowVersionAsync(modelDef, id, token)); + modelDef.RowVersion?.SetValue(obj, await dbCmd.GetRowVersionAsync(modelDef, id, token).ConfigAwait()); return true; } - await dbCmd.UpdateAsync(obj, token); + await dbCmd.UpdateAsync(obj, token, null); - if (modelDef.RowVersion != null) - modelDef.RowVersion.SetValueFn(obj, await dbCmd.GetRowVersionAsync(modelDef, id, token)); + modelDef.RowVersion?.SetValue(obj, await dbCmd.GetRowVersionAsync(modelDef, id, token).ConfigAwait()); return false; } internal static async Task SaveAllAsync(this IDbCommand dbCmd, IEnumerable objs, CancellationToken token) { + OrmLiteUtils.AssertNotAnonType(); + var saveRows = objs.ToList(); var firstRow = saveRows.FirstOrDefault(); if (Equals(firstRow, default(T))) return 0; - var firstRowId = firstRow.GetId(); - var defaultIdValue = firstRowId != null ? firstRowId.GetType().GetDefaultValue() : null; + var modelDef = typeof(T).GetModelDefinition(); - var idMap = defaultIdValue != null - ? saveRows.Where(x => !defaultIdValue.Equals(x.GetId())).ToSafeDictionary(x => x.GetId()) - : saveRows.Where(x => x.GetId() != null).ToSafeDictionary(x => x.GetId()); + var firstRowId = modelDef.GetPrimaryKey(firstRow); + var defaultIdValue = firstRowId?.GetType().GetDefaultValue(); - var existingRowsMap = (await dbCmd.SelectByIdsAsync(idMap.Keys, token)).ToDictionary(x => x.GetId()); + var idMap = defaultIdValue != null + ? saveRows.Where(x => !defaultIdValue.Equals(modelDef.GetPrimaryKey(x))).ToSafeDictionary(x => modelDef.GetPrimaryKey(x)) + : saveRows.Where(x => modelDef.GetPrimaryKey(x) != null).ToSafeDictionary(x => modelDef.GetPrimaryKey(x)); - var modelDef = typeof(T).GetModelDefinition(); + var existingRowsMap = (await dbCmd.SelectByIdsAsync(idMap.Keys, token).ConfigAwait()).ToDictionary(x => modelDef.GetPrimaryKey(x)); var rowsAdded = 0; @@ -362,49 +539,36 @@ internal static async Task SaveAllAsync(this IDbCommand dbCmd, IEnumerab var dialectProvider = dbCmd.GetDialectProvider(); - try + using (dbTrans) { foreach (var row in saveRows) { - var id = row.GetId(); + var id = modelDef.GetPrimaryKey(row); if (id != defaultIdValue && existingRowsMap.ContainsKey(id)) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, row); - - await dbCmd.UpdateAsync(row, token); + await dbCmd.UpdateAsync(row, token, null).ConfigAwait(); } else { if (modelDef.HasAutoIncrementId) { - var newId = await dbCmd.InsertAsync(row, selectIdentity: true, token:token); - var safeId = dialectProvider.ConvertDbValue(newId, modelDef.PrimaryKey.FieldType); - modelDef.PrimaryKey.SetValueFn(row, safeId); + var newId = await dbCmd.InsertAsync(row, commandFilter:null, selectIdentity:true, enableIdentityInsert: false, token: token).ConfigAwait(); + var safeId = dialectProvider.FromDbValue(newId, modelDef.PrimaryKey.FieldType); + modelDef.PrimaryKey.SetValue(row, safeId); id = newId; } else { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, row); - - await dbCmd.InsertAsync(token, row); + await dbCmd.InsertAsync(row, commandFilter:null, selectIdentity:false, enableIdentityInsert: false, token:token).ConfigAwait(); } rowsAdded++; } - if (modelDef.RowVersion != null) - modelDef.RowVersion.SetValueFn(row, await dbCmd.GetRowVersionAsync(modelDef, id, token)); + modelDef.RowVersion?.SetValue(row, await dbCmd.GetRowVersionAsync(modelDef, id, token).ConfigAwait()); } - if (dbTrans != null) - dbTrans.Commit(); - } - finally - { - if (dbTrans != null) - dbTrans.Dispose(); + dbTrans?.Commit(); } return rowsAdded; @@ -421,7 +585,7 @@ public static async Task SaveAllReferencesAsync(this IDbCommand dbCmd, T inst var listInterface = fieldDef.FieldType.GetTypeWithGenericInterfaceOf(typeof(IList<>)); if (listInterface != null) { - var refType = listInterface.GenericTypeArguments()[0]; + var refType = listInterface.GetGenericArguments()[0]; var refModelDef = refType.GetModelDefinition(); var refField = modelDef.GetRefFieldDef(refModelDef, refType); @@ -431,10 +595,10 @@ public static async Task SaveAllReferencesAsync(this IDbCommand dbCmd, T inst { foreach (var oRef in results) { - refField.SetValueFn(oRef, pkValue); + refField.SetValue(oRef, pkValue); } - await dbCmd.CreateTypedApi(refType).SaveAllAsync(results, token); + await dbCmd.CreateTypedApi(refType).SaveAllAsync(results, token).ConfigAwait(); } } else @@ -451,17 +615,16 @@ public static async Task SaveAllReferencesAsync(this IDbCommand dbCmd, T inst if (result != null) { - if (refField != null) - refField.SetValueFn(result, pkValue); + refField?.SetValue(result, pkValue); - await dbCmd.CreateTypedApi(refType).SaveAsync(result, token); + await dbCmd.CreateTypedApi(refType).SaveAsync(result, token).ConfigAwait(); //Save Self Table.RefTableId PK if (refSelf != null) { var refPkValue = refModelDef.PrimaryKey.GetValue(result); - refSelf.SetValueFn(instance, refPkValue); - await dbCmd.UpdateAsync(instance, token); + refSelf.SetValue(instance, refPkValue); + await dbCmd.UpdateAsync(instance, token, null).ConfigAwait(); } } } @@ -484,11 +647,10 @@ public static async Task SaveReferencesAsync(this IDbCommand dbCmd, Can ? modelDef.GetRefFieldDef(refModelDef, refType) : modelDef.GetRefFieldDefIfExists(refModelDef); - if (refField != null) - refField.SetValueFn(oRef, pkValue); + refField?.SetValue(oRef, pkValue); } - await dbCmd.SaveAllAsync(refs, token); + await dbCmd.SaveAllAsync(refs, token).ConfigAwait(); foreach (var oRef in refs) { @@ -496,8 +658,8 @@ public static async Task SaveReferencesAsync(this IDbCommand dbCmd, Can if (refSelf != null) { var refPkValue = refModelDef.PrimaryKey.GetValue(oRef); - refSelf.SetValueFn(instance, refPkValue); - await dbCmd.UpdateAsync(instance, token); + refSelf.SetValue(instance, refPkValue); + await dbCmd.UpdateAsync(instance, token, null).ConfigAwait(); } } } @@ -511,10 +673,16 @@ internal static Task ExecuteProcedureAsync(this IDbCommand dbCommand, T obj, return dbCommand.ExecuteSqlAsync(sql, token); } - internal static Task GetRowVersionAsync(this IDbCommand dbCmd, ModelDefinition modelDef, object id, CancellationToken token) + internal static async Task GetRowVersionAsync(this IDbCommand dbCmd, ModelDefinition modelDef, object id, CancellationToken token) { var sql = dbCmd.RowVersionSql(modelDef, id); - return dbCmd.ScalarAsync(sql, token); + var rowVersion = await dbCmd.ScalarAsync(sql, token).ConfigAwait(); + var to = dbCmd.GetDialectProvider().FromDbRowVersion(modelDef.RowVersion.FieldType, rowVersion); + + if (to is ulong u && modelDef.RowVersion.ColumnType == typeof(byte[])) + return BitConverter.GetBytes(u); + + return to ?? modelDef.RowVersion.ColumnType.GetDefaultValue(); } } } diff --git a/src/ServiceStack.OrmLite/Async/ReadExpressionCommandExtensionsAsync.cs b/src/ServiceStack.OrmLite/Async/ReadExpressionCommandExtensionsAsync.cs index 58caffa31..8fb336acc 100644 --- a/src/ServiceStack.OrmLite/Async/ReadExpressionCommandExtensionsAsync.cs +++ b/src/ServiceStack.OrmLite/Async/ReadExpressionCommandExtensionsAsync.cs @@ -1,5 +1,5 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; @@ -9,147 +9,197 @@ using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using ServiceStack.Text; namespace ServiceStack.OrmLite { internal static class ReadExpressionCommandExtensionsAsync { - internal static Task> SelectAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) + internal static Task> SelectAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - var sql = expression(expr).SelectInto(); - return dbCmd.ExprConvertToListAsync(sql, token); + string sql = q.SelectInto(QueryType.Select); + return dbCmd.ExprConvertToListAsync(sql, q.Params, q.OnlyFields, token); } - internal static Task> SelectAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) + internal static Task> SelectAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - string sql = expression(expr).SelectInto(); - return dbCmd.ExprConvertToListAsync(sql, token); + string sql = q.SelectInto(QueryType.Select); + return dbCmd.ExprConvertToListAsync(sql, q.Params, q.OnlyFields, token); } - internal static Task> SelectAsync(this IDbCommand dbCmd, SqlExpression expression, CancellationToken token) + internal static Task> SelectAsync(this IDbCommand dbCmd, Expression> predicate, CancellationToken token) { - string sql = expression.SelectInto(); - return dbCmd.ExprConvertToListAsync(sql, token); + var q = dbCmd.GetDialectProvider().SqlExpression(); + string sql = q.Where(predicate).SelectInto(QueryType.Select); + + return dbCmd.ExprConvertToListAsync(sql, q.Params, q.OnlyFields, token); } - internal static Task> SelectAsync(this IDbCommand dbCmd, SqlExpression expression, CancellationToken token) + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) { - string sql = expression.SelectInto(); - return dbCmd.ExprConvertToListAsync(sql, token); + q.Select(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToListAsync>(q.ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); } - internal static Task> SelectAsync(this IDbCommand dbCmd, Expression> predicate, CancellationToken token) + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) + { + q.Select(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToListAsync>(q.ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) + { + q.Select(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToListAsync>(q.ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) + { + q.Select(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToListAsync>(q.ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - string sql = expr.Where(predicate).SelectInto(); + q.Select(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToListAsync>(q.ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) + { + q.Select(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToListAsync>(q.ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) + { + q.Select(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToListAsync>(q.ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects, CancellationToken token) + { + return dbCmd.ExprConvertToListAsync>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } - return dbCmd.ExprConvertToListAsync(sql, token); + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects, CancellationToken token) + { + return dbCmd.ExprConvertToListAsync>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); } - internal static Task SingleAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects, CancellationToken token) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - return dbCmd.SingleAsync(expression(expr), token); + return dbCmd.ExprConvertToListAsync>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); } + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects, CancellationToken token) + { + return dbCmd.ExprConvertToListAsync>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects, CancellationToken token) + { + return dbCmd.ExprConvertToListAsync>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects, CancellationToken token) + { + return dbCmd.ExprConvertToListAsync>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task>> SelectMultiAsync(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects, CancellationToken token) + { + return dbCmd.ExprConvertToListAsync>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, q.OnlyFields, token); + } + + internal static Task SingleAsync(this IDbCommand dbCmd, Expression> predicate, CancellationToken token) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); + var q = dbCmd.GetDialectProvider().SqlExpression(); - return SingleAsync(dbCmd, ev.Where(predicate), token); + return SingleAsync(dbCmd, q.Where(predicate), token); } internal static Task SingleAsync(this IDbCommand dbCmd, SqlExpression expression, CancellationToken token) { - string sql = expression.Limit(1).SelectInto(); + string sql = expression.Limit(1).SelectInto(QueryType.Single); - return dbCmd.ConvertToAsync(sql, token); + return dbCmd.ExprConvertToAsync(sql, expression.Params, token); } - public static Task ScalarAsync(this IDbCommand dbCmd, Expression> field, CancellationToken token) + public static Task ScalarAsync(this IDbCommand dbCmd, Expression> field, CancellationToken token) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Select(field); - var sql = ev.SelectInto(); - return dbCmd.ScalarAsync(sql, token); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Select(field); + var sql = q.SelectInto(QueryType.Scalar); + return dbCmd.ScalarAsync(sql, q.Params, token); } internal static Task ScalarAsync(this IDbCommand dbCmd, - Expression> field, Expression> predicate, CancellationToken token) + Expression> field, Expression> predicate, CancellationToken token) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Select(field).Where(predicate); - string sql = ev.SelectInto(); - return dbCmd.ScalarAsync(sql, token); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Select(field).Where(predicate); + string sql = q.SelectInto(QueryType.Scalar); + return dbCmd.ScalarAsync(sql, q.Params, token); } internal static Task CountAsync(this IDbCommand dbCmd, CancellationToken token) { - var expression = dbCmd.GetDialectProvider().SqlExpression(); - var sql = expression.ToCountStatement(); - return GetCountAsync(dbCmd, sql, token); - } - - internal static Task CountAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) - { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - var sql = expression(expr).ToCountStatement(); - return GetCountAsync(dbCmd, sql, token); + var q = dbCmd.GetDialectProvider().SqlExpression(); + var sql = q.ToCountStatement(); + return GetCountAsync(dbCmd, sql, q.Params, token); } - internal static Task CountAsync(this IDbCommand dbCmd, SqlExpression expression, CancellationToken token) + internal static Task CountAsync(this IDbCommand dbCmd, SqlExpression q, CancellationToken token) { - var sql = expression.ToCountStatement(); - return GetCountAsync(dbCmd, sql, token); + var sql = q.ToCountStatement(); + return GetCountAsync(dbCmd, sql, q.Params, token); } internal static Task CountAsync(this IDbCommand dbCmd, Expression> predicate, CancellationToken token) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Where(predicate); - var sql = ev.ToCountStatement(); - return GetCountAsync(dbCmd, sql, token); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(predicate); + var sql = q.ToCountStatement(); + return GetCountAsync(dbCmd, sql, q.Params, token); } - internal static Task GetCountAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static async Task GetCountAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams, CancellationToken token) { - return dbCmd.ColumnAsync(sql, token).Then(x => x.Sum()); + var ret = await dbCmd.ColumnAsync(sql, sqlParams, token).ConfigAwait(); + return ret.Sum(); } internal static Task RowCountAsync(this IDbCommand dbCmd, SqlExpression expression, CancellationToken token) { - var sql = "SELECT COUNT(*) FROM ({0}) AS COUNT".Fmt(expression.ToSelectStatement(), token); - return dbCmd.ScalarAsync(sql, token); + var countExpr = expression.Clone().OrderBy(); + return dbCmd.ScalarAsync(dbCmd.GetDialectProvider().ToRowCountStatement(countExpr.ToSelectStatement(QueryType.Scalar)), countExpr.Params, token); } - internal static Task RowCountAsync(this IDbCommand dbCmd, string sql, CancellationToken token) + internal static Task RowCountAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) { - return dbCmd.ScalarAsync("SELECT COUNT(*) FROM ({0}) AS COUNT".Fmt(sql), token); - } + if (anonType != null) + dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); - internal static Task> LoadSelectAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token = default(CancellationToken)) - { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - expr = expression(expr); - return dbCmd.LoadListWithReferences(expr, token); + return dbCmd.ScalarAsync(dbCmd.GetDialectProvider().ToRowCountStatement(sql), token); } - internal static Task> LoadSelectAsync(this IDbCommand dbCmd, SqlExpression expression = null, CancellationToken token = default(CancellationToken)) + internal static Task> LoadSelectAsync(this IDbCommand dbCmd, SqlExpression expression = null, IEnumerable include = null, CancellationToken token = default) { - return dbCmd.LoadListWithReferences(expression, token); + return dbCmd.LoadListWithReferences(expression, include, token); } - internal static Task> LoadSelectAsync(this IDbCommand dbCmd, SqlExpression expression, CancellationToken token = default(CancellationToken)) + internal static Task> LoadSelectAsync(this IDbCommand dbCmd, SqlExpression expression, IEnumerable include = null, CancellationToken token = default) { - return dbCmd.LoadListWithReferences(expression, token); + return dbCmd.LoadListWithReferences(expression, include, token); } - internal static Task> LoadSelectAsync(this IDbCommand dbCmd, Expression> predicate, CancellationToken token = default(CancellationToken)) + internal static Task> LoadSelectAsync(this IDbCommand dbCmd, Expression> predicate, IEnumerable include = null, CancellationToken token = default) { var expr = dbCmd.GetDialectProvider().SqlExpression().Where(predicate); - return dbCmd.LoadListWithReferences(expr, token); + return dbCmd.LoadListWithReferences(expr, include, token); } internal static Task ExprConvertToAsync(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) @@ -158,28 +208,26 @@ internal static Task ExprConvertToAsync(this IDataReader dataReader, IOrmL () => dataReader.ConvertTo(dialectProvider), token); } - internal static Task> ExprConvertToListAsync(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, CancellationToken token) + internal static Task> Select(this IDbCommand dbCmd, Expression> predicate, CancellationToken token) { - var fieldDefs = ModelDefinition.Definition.AllFieldDefinitionsArray; - - var indexCache = dataReader.GetIndexFieldsCache(ModelDefinition.Definition); + var q = dbCmd.GetDialectProvider().SqlExpression(); + string sql = q.Where(predicate).SelectInto(QueryType.Select); - return dialectProvider.ReaderEach(dataReader, () => - { - var row = OrmLiteUtils.CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); - return row; - }, token); + return dbCmd.ExprConvertToListAsync(sql, q.Params, q.OnlyFields, token); } - internal static Task> Select(this IDbCommand dbCmd, Expression> predicate, CancellationToken token) + + internal static async Task GetSchemaTableAsync(this IDbCommand dbCmd, string sql, CancellationToken token) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - string sql = expr.Where(predicate).SelectInto(); - - return dbCmd.ExprConvertToListAsync(sql, token); + using var reader = await dbCmd.ExecReaderAsync(sql, token).ConfigAwait(); + return reader.GetSchemaTable(); } + public static Task GetTableColumnsAsync(this IDbCommand dbCmd, Type table, CancellationToken token) => + dbCmd.GetTableColumnsAsync($"SELECT * FROM {dbCmd.GetDialectProvider().GetQuotedTableName(table.GetModelDefinition())}", token); + + public static async Task GetTableColumnsAsync(this IDbCommand dbCmd, string sql, CancellationToken token) => + (await dbCmd.GetSchemaTableAsync(sql, token).ConfigAwait()).ToColumnSchemas(dbCmd); } } #endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Async/WriteExpressionCommandExtensionsAsync.cs b/src/ServiceStack.OrmLite/Async/WriteExpressionCommandExtensionsAsync.cs index 451d3756f..a87c5324c 100644 --- a/src/ServiceStack.OrmLite/Async/WriteExpressionCommandExtensionsAsync.cs +++ b/src/ServiceStack.OrmLite/Async/WriteExpressionCommandExtensionsAsync.cs @@ -1,5 +1,6 @@ -#if NET45 +#if ASYNC using System; +using System.Collections.Generic; using System.Data; using System.Linq.Expressions; using System.Threading; @@ -9,112 +10,225 @@ namespace ServiceStack.OrmLite { internal static class WriteExpressionCommandExtensionsAsync { - internal static Task UpdateOnlyAsync(this IDbCommand dbCmd, T model, Func, SqlExpression> onlyFields, CancellationToken token) + internal static Task UpdateOnlyFieldsAsync(this IDbCommand dbCmd, T model, SqlExpression onlyFields, Action commandFilter, CancellationToken token) { - return dbCmd.UpdateOnlyAsync(model, onlyFields(dbCmd.GetDialectProvider().SqlExpression()), token); + OrmLiteUtils.AssertNotAnonType(); + + dbCmd.UpdateOnlySql(model, onlyFields); + commandFilter?.Invoke(dbCmd); + return dbCmd.ExecNonQueryAsync(token); } - internal static Task UpdateOnlyAsync(this IDbCommand dbCmd, T model, SqlExpression onlyFields, CancellationToken token) + internal static Task UpdateOnlyFieldsAsync(this IDbCommand dbCmd, T obj, + Expression> onlyFields, + Expression> where, + Action commandFilter, + CancellationToken token) { - var sql = dbCmd.UpdateOnlySql(model, onlyFields); - return dbCmd.ExecuteSqlAsync(sql, token); + OrmLiteUtils.AssertNotAnonType(); + + if (onlyFields == null) + throw new ArgumentNullException(nameof(onlyFields)); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Update(onlyFields); + q.Where(where); + return dbCmd.UpdateOnlyFieldsAsync(obj, q, commandFilter, token); } - internal static Task UpdateOnlyAsync(this IDbCommand dbCmd, T obj, - Expression> onlyFields, - Expression> where, + internal static Task UpdateOnlyFieldsAsync(this IDbCommand dbCmd, T obj, + string[] onlyFields, + Expression> where, + Action commandFilter, CancellationToken token) { + OrmLiteUtils.AssertNotAnonType(); + if (onlyFields == null) - throw new ArgumentNullException("onlyFields"); + throw new ArgumentNullException(nameof(onlyFields)); var q = dbCmd.GetDialectProvider().SqlExpression(); q.Update(onlyFields); q.Where(where); - return dbCmd.UpdateOnlyAsync(obj, q, token); + return dbCmd.UpdateOnlyFieldsAsync(obj, q, commandFilter, token); } - internal static Task UpdateNonDefaultsAsync(this IDbCommand dbCmd, T item, Expression> obj, CancellationToken token) + internal static Task UpdateOnlyAsync(this IDbCommand dbCmd, + Expression> updateFields, + SqlExpression q, + Action commandFilter, + CancellationToken token) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, item); + OrmLiteUtils.AssertNotAnonType(); + + var cmd = dbCmd.InitUpdateOnly(updateFields, q); + commandFilter?.Invoke(cmd); + return cmd.ExecNonQueryAsync(token); + } - var q = dbCmd.GetDialectProvider().SqlExpression(); - q.Where(obj); - var sql = q.ToUpdateStatement(item, excludeDefaults: true); - return dbCmd.ExecuteSqlAsync(sql, token); + internal static Task UpdateOnlyAsync(this IDbCommand dbCmd, + Expression> updateFields, + string whereExpression, + IEnumerable sqlParams, + Action commandFilter, + CancellationToken token) + { + OrmLiteUtils.AssertNotAnonType(); + + var cmd = dbCmd.InitUpdateOnly(updateFields, whereExpression, sqlParams); + commandFilter?.Invoke(cmd); + return cmd.ExecNonQueryAsync(token); } - internal static Task UpdateAsync(this IDbCommand dbCmd, T item, Expression> expression, CancellationToken token) + public static Task UpdateAddAsync(this IDbCommand dbCmd, + Expression> updateFields, + SqlExpression q, + Action commandFilter, + CancellationToken token) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, item); + OrmLiteUtils.AssertNotAnonType(); + + var cmd = dbCmd.InitUpdateAdd(updateFields, q); + commandFilter?.Invoke(cmd); + return cmd.ExecNonQueryAsync(token); + } + + public static Task UpdateOnlyAsync(this IDbCommand dbCmd, + Dictionary updateFields, + Expression> where, + Action commandFilter = null, + CancellationToken token = default) + { + OrmLiteUtils.AssertNotAnonType(); + + if (updateFields == null) + throw new ArgumentNullException(nameof(updateFields)); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateFields.ToFilterType()); var q = dbCmd.GetDialectProvider().SqlExpression(); - q.Where(expression); - var sql = q.ToUpdateStatement(item); - return dbCmd.ExecuteSqlAsync(sql, token); + q.Where(where); + q.PrepareUpdateStatement(dbCmd, updateFields); + return dbCmd.UpdateAndVerifyAsync(commandFilter, updateFields.ContainsKey(ModelDefinition.RowVersionName), token); } - internal static Task UpdateAsync(this IDbCommand dbCmd, object updateOnly, Expression> where, CancellationToken token) + public static Task UpdateOnlyAsync(this IDbCommand dbCmd, + Dictionary updateFields, + Action commandFilter = null, + CancellationToken token = default) { - var updateSql = WriteExpressionCommandExtensions.UpdateSql(dbCmd.GetDialectProvider(), updateOnly, where); - return dbCmd.ExecuteSqlAsync(updateSql, token); + OrmLiteUtils.AssertNotAnonType(); + + var whereExpr = dbCmd.GetDialectProvider().GetUpdateOnlyWhereExpression(updateFields, out var exprArgs); + dbCmd.PrepareUpdateOnly(updateFields, whereExpr, exprArgs); + return dbCmd.UpdateAndVerifyAsync(commandFilter, updateFields.ContainsKey(ModelDefinition.RowVersionName), token); } - internal static Task UpdateFmtAsync(this IDbCommand dbCmd, string set, string where, CancellationToken token) + public static Task UpdateOnlyAsync(this IDbCommand dbCmd, + Dictionary updateFields, + string whereExpression, + object[] whereParams, + Action commandFilter = null, + CancellationToken token = default) { - return dbCmd.UpdateFmtAsync(typeof(T).GetModelDefinition().ModelName, set, where, token); + OrmLiteUtils.AssertNotAnonType(); + + if (updateFields == null) + throw new ArgumentNullException(nameof(updateFields)); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateFields.ToFilterType()); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(whereExpression, whereParams); + q.PrepareUpdateStatement(dbCmd, updateFields); + return dbCmd.UpdateAndVerifyAsync(commandFilter, updateFields.ContainsKey(ModelDefinition.RowVersionName), token); } - internal static Task UpdateFmtAsync(this IDbCommand dbCmd, string table, string set, string where, CancellationToken token) + internal static Task UpdateNonDefaultsAsync(this IDbCommand dbCmd, T item, Expression> obj, CancellationToken token) { - var sql = WriteExpressionCommandExtensions.UpdateFmtSql(dbCmd.GetDialectProvider(), table, set, @where); - return dbCmd.ExecuteSqlAsync(sql.ToString(), token); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, item); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(obj); + q.PrepareUpdateStatement(dbCmd, item, excludeDefaults: true); + return dbCmd.ExecNonQueryAsync(token); } - internal static Task InsertOnlyAsync(this IDbCommand dbCmd, T obj, Func, SqlExpression> onlyFields, CancellationToken token) + internal static Task UpdateAsync(this IDbCommand dbCmd, T item, Expression> expression, Action commandFilter, CancellationToken token) { - return dbCmd.InsertOnlyAsync(obj, onlyFields(dbCmd.GetDialectProvider().SqlExpression()), token); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, item); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(expression); + q.PrepareUpdateStatement(dbCmd, item); + commandFilter?.Invoke(dbCmd); + return dbCmd.ExecNonQueryAsync(token); } - internal static Task InsertOnlyAsync(this IDbCommand dbCmd, T obj, SqlExpression onlyFields, CancellationToken token) + internal static Task UpdateAsync(this IDbCommand dbCmd, object updateOnly, Expression> where, Action commandFilter, CancellationToken token) { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, obj); + OrmLiteUtils.AssertNotAnonType(); - var sql = dbCmd.GetDialectProvider().ToInsertRowStatement(dbCmd, obj, onlyFields.InsertFields); - return dbCmd.ExecuteSqlAsync(sql, token); + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateOnly.ToFilterType()); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + var whereSql = q.Where(where).WhereExpression; + q.CopyParamsTo(dbCmd); + dbCmd.PrepareUpdateAnonSql(dbCmd.GetDialectProvider(), updateOnly, whereSql); + commandFilter?.Invoke(dbCmd); + + return dbCmd.ExecNonQueryAsync(token); } - internal static Task DeleteAsync(this IDbCommand dbCmd, Expression> where, CancellationToken token) + internal static Task InsertOnlyAsync(this IDbCommand dbCmd, T obj, string[] onlyFields, CancellationToken token) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Where(where); - return dbCmd.DeleteAsync(ev, token); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); + + var dialectProvider = dbCmd.GetDialectProvider(); + var sql = dialectProvider.ToInsertRowStatement(dbCmd, obj, onlyFields); + + dialectProvider.SetParameterValues(dbCmd, obj); + + return dbCmd.ExecuteSqlAsync(sql, token); } - internal static Task DeleteAsync(this IDbCommand dbCmd, Func, SqlExpression> where, CancellationToken token) + public static Task InsertOnlyAsync(this IDbCommand dbCmd, Expression> insertFields, CancellationToken token) { - return dbCmd.DeleteAsync(where(dbCmd.GetDialectProvider().SqlExpression()), token); + OrmLiteUtils.AssertNotAnonType(); + + return dbCmd.InitInsertOnly(insertFields).ExecNonQueryAsync(token); } - internal static Task DeleteAsync(this IDbCommand dbCmd, SqlExpression where, CancellationToken token) + internal static Task DeleteAsync(this IDbCommand dbCmd, Expression> where, + Action commandFilter, CancellationToken token) { - var sql = where.ToDeleteRowStatement(); - return dbCmd.ExecuteSqlAsync(sql, token); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(where); + return dbCmd.DeleteAsync(q, commandFilter, token); } - internal static Task DeleteFmtAsync(this IDbCommand dbCmd, string where, CancellationToken token) + internal static Task DeleteAsync(this IDbCommand dbCmd, SqlExpression q, + Action commandFilter, CancellationToken token) { - return dbCmd.DeleteFmtAsync(typeof(T).GetModelDefinition().ModelName, where, token); + var sql = q.ToDeleteRowStatement(); + return dbCmd.ExecuteSqlAsync(sql, q.Params, commandFilter, token); } - internal static Task DeleteFmtAsync(this IDbCommand dbCmd, string table, string where, CancellationToken token) + internal static Task DeleteWhereAsync(this IDbCommand dbCmd, string whereFilter, object[] whereParams, + Action commandFilter, CancellationToken token) { - var sql = WriteExpressionCommandExtensions.DeleteFmtSql(dbCmd.GetDialectProvider(), table, @where); - return dbCmd.ExecuteSqlAsync(sql.ToString(), token); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(whereFilter, whereParams); + var sql = q.ToDeleteRowStatement(); + return dbCmd.ExecuteSqlAsync(sql, q.Params, commandFilter, token); } } } + #endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/ColumnSchema.cs b/src/ServiceStack.OrmLite/ColumnSchema.cs new file mode 100644 index 000000000..7d258d6c2 --- /dev/null +++ b/src/ServiceStack.OrmLite/ColumnSchema.cs @@ -0,0 +1,98 @@ +using System; +using System.Text; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite +{ + public class ColumnSchema + { + public string ColumnName { get; set; } + public int ColumnOrdinal { get; set; } + public int ColumnSize { get; set; } + public int NumericPrecision { get; set; } + public int NumericScale { get; set; } + public bool IsUnique { get; set; } + public bool IsKey { get; set; } + public string BaseServerName { get; set; } + public string BaseCatalogName { get; set; } + public string BaseColumnName { get; set; } + public string BaseSchemaName { get; set; } + public string BaseTableName { get; set; } + public Type DataType { get; set; } + public bool AllowDBNull { get; set; } + public int ProviderType { get; set; } + public bool IsAliased { get; set; } + public bool IsExpression { get; set; } + public bool IsAutoIncrement { get; set; } + public bool IsRowVersion { get; set; } + public bool IsHidden { get; set; } + public bool IsLong { get; set; } + public bool IsReadOnly { get; set; } + public Type ProviderSpecificDataType { get; set; } + public object DefaultValue { get; set; } + public string DataTypeName { get; set; } + public string CollationType { get; set; } + + public override string ToString() + { + var sql = StringBuilderCache.Allocate(); + + sql.Append(ColumnName.PadRight(20, ' ')).Append(' '); + AppendDefinition(sql); + + return StringBuilderCache.ReturnAndFree(sql); + } + + public string ColumnDefinition => + StringBuilderCache.ReturnAndFree(AppendDefinition(StringBuilderCache.Allocate())); + + private StringBuilder AppendDefinition(StringBuilder sql) + { + sql.Append(DataTypeName.ToUpper()); + if (DataType.IsRealNumberType() && NumericPrecision > 0) + { + sql.Append("("); + sql.Append(NumericPrecision); + if (NumericScale > 0) + { + sql.Append(","); + sql.Append(NumericScale); + } + + sql.Append(")"); + } + else if (!DataType.IsNumericType() && ColumnSize > 0) + { + sql.Append("("); + sql.Append(ColumnSize); + sql.Append(")"); + } + + if (IsKey) + { + sql.Append(" PRIMARY KEY"); + if (IsAutoIncrement) + { + sql.Append(" ").Append("AUTOINCREMENT"); + } + } + else + { + sql.Append(AllowDBNull ? " NULL" : " NOT NULL"); + + if (IsUnique) + { + sql.Append(" UNIQUE"); + } + } + + if (DefaultValue != null) + { + sql.AppendFormat(" DEFAULT ({0})", DefaultValue); + } + + return sql; + } + } + +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/BoolConverter.cs b/src/ServiceStack.OrmLite/Converters/BoolConverter.cs new file mode 100644 index 000000000..3029dae4a --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/BoolConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Converters +{ + public class BoolConverter : NativeValueOrmLiteConverter + { + public override string ColumnDefinition => "BOOL"; + public override DbType DbType => DbType.Boolean; + + //Also support coercing 0 != int as Bool + public override object FromDbValue(Type fieldType, object value) + { + if (value is bool) + return value; + + return 0 != (long)this.ConvertNumber(typeof(long), value); + } + } + + public class BoolAsIntConverter : BoolConverter + { + public override object ToDbValue(Type fieldType, object value) + { + if (value is bool) + return value; + + return 0 != (long)this.ConvertNumber(typeof(long), value); + } + + public override string ToQuotedString(Type fieldType, object value) + { + var boolValue = (bool)value; + return base.DialectProvider.GetQuotedValue(boolValue ? 1 : 0, typeof(int)); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/ByteArrayConverter.cs b/src/ServiceStack.OrmLite/Converters/ByteArrayConverter.cs new file mode 100644 index 000000000..779894643 --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/ByteArrayConverter.cs @@ -0,0 +1,10 @@ +using System.Data; + +namespace ServiceStack.OrmLite.Converters +{ + public class ByteArrayConverter : OrmLiteConverter + { + public override string ColumnDefinition => "BLOB"; + public override DbType DbType => DbType.Binary; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/DateOnlyConverter.cs b/src/ServiceStack.OrmLite/Converters/DateOnlyConverter.cs new file mode 100644 index 000000000..54c97b483 --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/DateOnlyConverter.cs @@ -0,0 +1,30 @@ +using System; + +#if NET6_0 +namespace ServiceStack.OrmLite.Converters +{ + public class DateOnlyConverter : DateTimeConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + var dateOnly = (DateOnly)value; + return DateTimeFmt(dateOnly.ToDateTime(default, DateTimeKind.Local), "yyyy-MM-dd HH:mm:ss.fff"); + } + + public override object ToDbValue(Type fieldType, object value) + { + var dateOnly = (DateOnly)value; + return base.ToDbValue(typeof(DateTime), dateOnly.ToDateTime(default, DateTimeKind.Local)); + } + + public override object FromDbValue(object value) + { + var dateTime = (DateTime)base.FromDbValue(value); + if (dateTime.Kind != DateTimeKind.Local) + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + var dateOnly = DateOnly.FromDateTime(dateTime); + return dateOnly; + } + } +} +#endif diff --git a/src/ServiceStack.OrmLite/Converters/DateTimeConverter.cs b/src/ServiceStack.OrmLite/Converters/DateTimeConverter.cs new file mode 100644 index 000000000..2740b736b --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/DateTimeConverter.cs @@ -0,0 +1,77 @@ +using System; +using System.Data; +using System.Globalization; +using ServiceStack.Logging; +using ServiceStack.Text.Common; + +namespace ServiceStack.OrmLite.Converters +{ + public class DateTimeConverter : OrmLiteConverter + { + public override string ColumnDefinition => "DATETIME"; + + public override DbType DbType => DbType.DateTime; + + public DateTimeKind DateStyle { get; set; } + + public override string ToQuotedString(Type fieldType, object value) + { + var dateTime = (DateTime)value; + return DateTimeFmt(dateTime, "yyyy-MM-dd HH:mm:ss.fff"); + } + + public virtual string DateTimeFmt(DateTime dateTime, string dateTimeFormat) + { + if (DateStyle == DateTimeKind.Utc && dateTime.Kind == DateTimeKind.Local) + dateTime = dateTime.ToUniversalTime(); + + if (DateStyle == DateTimeKind.Local && dateTime.Kind != DateTimeKind.Local) + dateTime = dateTime.ToLocalTime(); + + return DialectProvider.GetQuotedValue(dateTime.ToString(dateTimeFormat, CultureInfo.InvariantCulture), typeof(string)); + } + + public override object ToDbValue(Type fieldType, object value) + { + var dateTime = (DateTime)value; + if (DateStyle == DateTimeKind.Utc && dateTime.Kind == DateTimeKind.Local) + { + dateTime = dateTime.ToUniversalTime(); + } + else if (DateStyle == DateTimeKind.Local && dateTime.Kind != DateTimeKind.Local) + { + dateTime = dateTime.Kind == DateTimeKind.Utc + ? dateTime.ToLocalTime() + : DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime(); + } + + return dateTime; + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is string strValue) + { + value = DateTimeSerializer.ParseShortestXsdDateTime(strValue); + } + + return FromDbValue(value); + } + + public virtual object FromDbValue(object value) + { + var dateTime = (DateTime)value; + if (DateStyle == DateTimeKind.Utc) + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); + + if (DateStyle == DateTimeKind.Local && dateTime.Kind != DateTimeKind.Local) + { + dateTime = dateTime.Kind == DateTimeKind.Utc + ? dateTime.ToLocalTime() + : DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + } + + return dateTime; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/DateTimeOffsetConverter.cs b/src/ServiceStack.OrmLite/Converters/DateTimeOffsetConverter.cs new file mode 100644 index 000000000..e56f8f4ad --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/DateTimeOffsetConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Data; +using System.Globalization; + +namespace ServiceStack.OrmLite.Converters +{ + public class DateTimeOffsetConverter : OrmLiteConverter + { + public override string ColumnDefinition => "DATETIMEOFFSET"; + public override DbType DbType => DbType.DateTimeOffset; + + //From OrmLiteDialectProviderBase: + public override object FromDbValue(Type fieldType, object value) + { + var strValue = value as string; + if (strValue != null) + { + var moment = DateTimeOffset.Parse(strValue, null, DateTimeStyles.RoundtripKind); + return moment; + } + if (value.GetType() == fieldType) + { + return value; + } + if (value is DateTime) + { + return new DateTimeOffset((DateTime)value); + } + var convertedValue = DialectProvider.StringSerializer.DeserializeFromString(value.ToString(), fieldType); + return convertedValue; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/FloatConverters.cs b/src/ServiceStack.OrmLite/Converters/FloatConverters.cs new file mode 100644 index 000000000..7bb0780dd --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/FloatConverters.cs @@ -0,0 +1,67 @@ +using System; +using System.Data; +using System.Globalization; + +namespace ServiceStack.OrmLite.Converters +{ + public class FloatConverter : NativeValueOrmLiteConverter + { + public override string ColumnDefinition => "DOUBLE"; + public override DbType DbType => DbType.Single; + + public override object ToDbValue(Type fieldType, object value) + { + return this.ConvertNumber(fieldType, value); + } + + public override object FromDbValue(Type fieldType, object value) + { + return this.ConvertNumber(fieldType, value); + } + + public override string ToQuotedString(Type fieldType, object value) + { + var typeCode = fieldType.GetTypeCode(); + switch (typeCode) + { + case TypeCode.Single: + return Convert.ToSingle(value).ToString(CultureInfo.InvariantCulture); + case TypeCode.Double: + return Convert.ToDouble(value).ToString(CultureInfo.InvariantCulture); + case TypeCode.Decimal: + return Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture); + } + + return base.ToQuotedString(fieldType, value); + } + } + + public class DoubleConverter : FloatConverter + { + public override DbType DbType => DbType.Double; + } + + public class DecimalConverter : FloatConverter, IHasColumnDefinitionPrecision + { + public int Precision { get; set; } + public int Scale { get; set; } + + public DecimalConverter() + : this(18, 12) {} + + public DecimalConverter(int precision, int scale) + { + Precision = precision; + Scale = scale; + } + + public override string ColumnDefinition => GetColumnDefinition(Precision, Scale); + + public override DbType DbType => DbType.Decimal; + + public virtual string GetColumnDefinition(int? precision, int? scale) + { + return $"DECIMAL({precision.GetValueOrDefault(Precision)},{scale.GetValueOrDefault(Scale)})"; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/GuidConverter.cs b/src/ServiceStack.OrmLite/Converters/GuidConverter.cs new file mode 100644 index 000000000..cf247d76f --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/GuidConverter.cs @@ -0,0 +1,11 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Converters +{ + public class GuidConverter : OrmLiteConverter + { + public override string ColumnDefinition => "GUID"; + public override DbType DbType => DbType.Guid; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/IntegerConverters.cs b/src/ServiceStack.OrmLite/Converters/IntegerConverters.cs new file mode 100644 index 000000000..9cbcbdb7c --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/IntegerConverters.cs @@ -0,0 +1,61 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Converters +{ + public abstract class IntegerConverter : NativeValueOrmLiteConverter + { + public override string ColumnDefinition => "INTEGER"; + public override DbType DbType => DbType.Int32; + + public override object ToDbValue(Type fieldType, object value) + { + return this.ConvertNumber(fieldType, value); + } + + public override object FromDbValue(Type fieldType, object value) + { + return this.ConvertNumber(fieldType, value); + } + } + + public class ByteConverter : IntegerConverter + { + public override DbType DbType => DbType.Byte; + } + + public class SByteConverter : IntegerConverter + { + public override DbType DbType => DbType.SByte; + } + + public class Int16Converter : IntegerConverter + { + public override DbType DbType => DbType.Int16; + } + + public class UInt16Converter : IntegerConverter + { + public override DbType DbType => DbType.UInt16; + } + + public class Int32Converter : IntegerConverter {} + + public class UInt32Converter : IntegerConverter + { + public override DbType DbType => DbType.UInt32; + } + + public class Int64Converter : IntegerConverter + { + public override DbType DbType => DbType.Int64; + public override string ColumnDefinition => "BIGINT"; + } + + public class UInt64Converter : IntegerConverter + { + public override DbType DbType => DbType.UInt64; + public override string ColumnDefinition => "BIGINT"; + } + +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/SpecialConverters.cs b/src/ServiceStack.OrmLite/Converters/SpecialConverters.cs new file mode 100644 index 000000000..c58ee5507 --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/SpecialConverters.cs @@ -0,0 +1,271 @@ +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Reflection; +using System.Runtime.Serialization; +using ServiceStack.DataAnnotations; +#if NETCORE +using System.Globalization; +#endif + +namespace ServiceStack.OrmLite.Converters +{ + public enum EnumKind + { + String, + Int, + Char, + EnumMember, + } + + public class EnumConverter : StringConverter + { + public EnumConverter() : base(255) {} + + static Dictionary enumTypeCache = new Dictionary(); + + public static EnumKind GetEnumKind(Type enumType) + { + if (enumTypeCache.TryGetValue(enumType, out var enumKind)) + return enumKind; + + enumKind = IsIntEnum(enumType) + ? EnumKind.Int + : enumType.HasAttributeCached() + ? EnumKind.Char + : HasEnumMembers(enumType) + ? EnumKind.EnumMember + : EnumKind.String; + + Dictionary snapshot, newCache; + do + { + snapshot = enumTypeCache; + newCache = new Dictionary(enumTypeCache) { + [enumType] = enumKind + }; + } while (!ReferenceEquals( + System.Threading.Interlocked.CompareExchange(ref enumTypeCache, newCache, snapshot), snapshot)); + + return enumKind; + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + var enumKind = GetEnumKind(fieldType); + + p.DbType = enumKind == EnumKind.Int + ? Enum.GetUnderlyingType(fieldType) == typeof(long) + ? DbType.Int64 + : DbType.Int32 + : DbType; + } + + public override string ToQuotedString(Type fieldType, object value) + { + var enumKind = GetEnumKind(fieldType); + if (enumKind == EnumKind.Int) + return this.ConvertNumber(Enum.GetUnderlyingType(fieldType), value).ToString(); + + if (enumKind == EnumKind.Char) + return DialectProvider.GetQuotedValue(ToCharValue(value).ToString()); + + var isEnumFlags = fieldType.IsEnumFlags() || + (!fieldType.IsEnum && fieldType.IsNumericType()); //i.e. is real int && not Enum + + if (!isEnumFlags && long.TryParse(value.ToString(), out var enumValue)) + value = Enum.ToObject(fieldType, enumValue); + + var enumString = enumKind == EnumKind.EnumMember + ? value.ToString() + : DialectProvider.StringSerializer.SerializeToString(value); + if (enumString == null || enumString == "null") + enumString = value.ToString(); + + return !isEnumFlags + ? DialectProvider.GetQuotedValue(enumString.Trim('"')) + : enumString; + } + + public override object ToDbValue(Type fieldType, object value) + { + var enumKind = GetEnumKind(fieldType); + + if (value.GetType().IsEnum) + { + if (enumKind == EnumKind.Int) + return Convert.ChangeType(value, Enum.GetUnderlyingType(fieldType)); + + if (enumKind == EnumKind.Char) + return Convert.ChangeType(value, typeof(char)); + } + + if (enumKind == EnumKind.Char) + { + var charValue = ToCharValue(value); + return charValue; + } + + if (long.TryParse(value.ToString(), out var enumValue)) + { + if (enumKind == EnumKind.Int) + return enumValue; + + value = Enum.ToObject(fieldType, enumValue); + } + + if (enumKind == EnumKind.EnumMember) // Don't use serialized Enum Value + return value.ToString(); + + var enumString = DialectProvider.StringSerializer.SerializeToString(value); + return enumString != null && enumString != "null" + ? enumString.Trim('"') + : value.ToString(); + } + + public static char ToCharValue(object value) + { + var charValue = value is char c + ? c + : value is string s && s.Length == 1 + ? s[0] + : value is int i + ? (char) i + : (char) Convert.ChangeType(value, typeof(char)); + return charValue; + } + + //cache expensive to calculate operation + static readonly ConcurrentDictionary intEnums = new(); + + public static bool IsIntEnum(Type fieldType) + { + var isIntEnum = intEnums.GetOrAdd(fieldType, type => + type.IsEnumFlags() || + type.HasAttributeCached() || + !type.IsEnum && + type.IsNumericType()); //i.e. is real int && not Enum) + + return isIntEnum; + } + + public static bool HasEnumMembers(Type enumType) + { + var enumMembers = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); + foreach (var fi in enumMembers) + { + var enumMemberAttr = fi.FirstAttribute(); + if (enumMemberAttr?.Value != null) + return true; + } + return false; + } + + public override object FromDbValue(Type fieldType, object value) + { + var enumKind = GetEnumKind(fieldType); + + if (enumKind == EnumKind.Char) + return Enum.ToObject(fieldType, (int)ToCharValue(value)); + + if (value is string strVal) + return Enum.Parse(fieldType, strVal, ignoreCase:true); + + return Enum.ToObject(fieldType, value); + } + } + + public class RowVersionConverter : OrmLiteConverter + { + public override string ColumnDefinition => "BIGINT"; + + public override DbType DbType => DbType.Int64; + + public override object FromDbValue(Type fieldType, object value) + { + if (value is byte[] bytes) + { + if (fieldType == typeof(byte[])) return bytes; + if (fieldType == typeof(ulong)) return OrmLiteUtils.ConvertToULong(bytes); + + // an SQL row version has to be declared as either byte[] OR ulong... + throw new Exception("Rowversion property must be declared as either byte[] or ulong"); + } + + return value != null + ? this.ConvertNumber(typeof(ulong), value) + : null; + } + } + + public class ReferenceTypeConverter : StringConverter + { + public override string ColumnDefinition => DialectProvider.GetStringConverter().MaxColumnDefinition; + + public override string MaxColumnDefinition => DialectProvider.GetStringConverter().MaxColumnDefinition; + + public override string GetColumnDefinition(int? stringLength) + { + return stringLength != null + ? base.GetColumnDefinition(stringLength) + : MaxColumnDefinition; + } + + public override string ToQuotedString(Type fieldType, object value) + { + return DialectProvider.GetQuotedValue(DialectProvider.StringSerializer.SerializeToString(value)); + } + + public override object ToDbValue(Type fieldType, object value) + { + //Let ADO.NET providers handle byte[] + return fieldType == typeof(byte[]) + ? value + : DialectProvider.StringSerializer.SerializeToString(value); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is string str) + return DialectProvider.StringSerializer.DeserializeFromString(str, fieldType); + + var convertedValue = value.ConvertTo(fieldType); + return convertedValue; + } + } + + public class ValueTypeConverter : StringConverter + { + public override string ColumnDefinition => DialectProvider.GetStringConverter().MaxColumnDefinition; + public override string MaxColumnDefinition => DialectProvider.GetStringConverter().MaxColumnDefinition; + + public override string GetColumnDefinition(int? stringLength) + { + return stringLength != null + ? base.GetColumnDefinition(stringLength) + : MaxColumnDefinition; + } + + public override string ToQuotedString(Type fieldType, object value) + { + return DialectProvider.GetQuotedValue(DialectProvider.StringSerializer.SerializeToString(value)); + } + + public override object ToDbValue(Type fieldType, object value) + { + var convertedValue = DialectProvider.StringSerializer.DeserializeFromString(value.ToString(), fieldType); + return convertedValue; + } + + public override object FromDbValue(Type fieldType, object value) + { + if (fieldType.IsInstanceOfType(value)) + return value; + + var convertedValue = DialectProvider.StringSerializer.DeserializeFromString(value.ToString(), fieldType); + return convertedValue; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/StringConverter.cs b/src/ServiceStack.OrmLite/Converters/StringConverter.cs new file mode 100644 index 000000000..828917849 --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/StringConverter.cs @@ -0,0 +1,123 @@ +using System; +using System.Data; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Converters +{ + public class StringConverter : OrmLiteConverter, IHasColumnDefinitionLength + { + public StringConverter() : this(8000) {} + + public StringConverter(int stringLength) + { + StringLength = stringLength; + } + + public bool UseUnicode { get; set; } + + public int StringLength { get; set; } + + public virtual int MaxVarCharLength => UseUnicode ? 8000 : 4000; + + protected string maxColumnDefinition; + public virtual string MaxColumnDefinition + { + get => maxColumnDefinition ?? ColumnDefinition; + set => maxColumnDefinition = value; + } + + public override string ColumnDefinition => GetColumnDefinition(StringLength); + + public virtual string GetColumnDefinition(int? stringLength) + { + if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText) + return MaxColumnDefinition; + + return UseUnicode + ? $"NVARCHAR({stringLength.GetValueOrDefault(StringLength)})" + : $"VARCHAR({stringLength.GetValueOrDefault(StringLength)})"; + } + + public override void InitDbParam(IDbDataParameter p, Type fieldType) + { + base.InitDbParam(p, fieldType); + + if (p.Size == default && fieldType == typeof(string)) + { + p.Size = UseUnicode + ? Math.Min(StringLength, 4000) + : StringLength; + } + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is string strValue) + { + if (OrmLiteConfig.StringFilter != null) + return OrmLiteConfig.StringFilter(strValue); + } + + return value.ToString(); + } + } + + public class CharConverter : StringConverter + { + public override string ColumnDefinition => "CHAR(1)"; + + public override DbType DbType => DbType.StringFixedLength; + + public override string GetColumnDefinition(int? stringLength) + { + return ColumnDefinition; + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is char) + return value; + + if (value is string strValue) + return strValue[0]; + + if (value.GetType().IsIntegerType()) + return (char) (int) this.ConvertNumber(typeof(int), value); + + return (char)value; + } + + public override object ToDbValue(Type fieldType, object value) + { + if (value != null && value.GetType().IsEnum) + return EnumConverter.ToCharValue(value); + if (value is int i) + return (char)i; + + return base.ToDbValue(fieldType, value); + } + } + + public class CharArrayConverter : StringConverter + { + public CharArrayConverter() {} + public CharArrayConverter(int stringLength) : base(stringLength) {} + + public override object ToDbValue(Type fieldType, object value) + { + var chars = (char[]) value; + return new string(chars); + } + + public override object FromDbValue(Type fieldType, object value) + { + if (value is char[]) + return value; + + if (value is string strValue) + return strValue.ToCharArray(); + + return (char[])value; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Converters/TimeOnlyConverter.cs b/src/ServiceStack.OrmLite/Converters/TimeOnlyConverter.cs new file mode 100644 index 000000000..5fae7f878 --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/TimeOnlyConverter.cs @@ -0,0 +1,29 @@ +using System; +using System.Globalization; + +#if NET6_0 +namespace ServiceStack.OrmLite.Converters +{ + public class TimeOnlyConverter : TimeSpanAsIntConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + return ((TimeOnly)value).Ticks.ToString(CultureInfo.InvariantCulture); + } + + public override object ToDbValue(Type fieldType, object value) + { + var timespan = (TimeOnly)value; + return timespan.Ticks; + } + + public override object FromDbValue(Type fieldType, object value) + { + var ticks = (long)this.ConvertNumber(typeof(long), value); + var timeSpan = TimeSpan.FromTicks(ticks); + return TimeOnly.FromTimeSpan(timeSpan); + } + } +} + +#endif diff --git a/src/ServiceStack.OrmLite/Converters/TimeSpanAsIntConverter.cs b/src/ServiceStack.OrmLite/Converters/TimeSpanAsIntConverter.cs new file mode 100644 index 000000000..d5a6fab8a --- /dev/null +++ b/src/ServiceStack.OrmLite/Converters/TimeSpanAsIntConverter.cs @@ -0,0 +1,29 @@ +using System; +using System.Data; +using System.Globalization; + +namespace ServiceStack.OrmLite.Converters +{ + public class TimeSpanAsIntConverter : OrmLiteConverter + { + public override string ColumnDefinition => "BIGINT"; + public override DbType DbType => DbType.Int64; + + public override string ToQuotedString(Type fieldType, object value) + { + return ((TimeSpan)value).Ticks.ToString(CultureInfo.InvariantCulture); + } + + public override object ToDbValue(Type fieldType, object value) + { + var timespan = (TimeSpan)value; + return timespan.Ticks; + } + + public override object FromDbValue(Type fieldType, object value) + { + var ticks = (long)this.ConvertNumber(typeof(long), value); + return TimeSpan.FromTicks(ticks); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Dapper/CommandDefinition.cs b/src/ServiceStack.OrmLite/Dapper/CommandDefinition.cs new file mode 100644 index 000000000..92f507741 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/CommandDefinition.cs @@ -0,0 +1,185 @@ +using System; +using System.Data; +using System.Reflection; +using System.Reflection.Emit; +using System.Threading; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Represents the key aspects of a sql operation + /// + public struct CommandDefinition + { + internal static CommandDefinition ForCallback(object parameters) + { + if (parameters is DynamicParameters) + { + return new CommandDefinition(parameters); + } + else + { + return default(CommandDefinition); + } + } + + internal void OnCompleted() + { + (Parameters as SqlMapper.IParameterCallbacks)?.OnCompleted(); + } + + /// + /// The command (sql or a stored-procedure name) to execute + /// + public string CommandText { get; } + + /// + /// The parameters associated with the command + /// + public object Parameters { get; } + + /// + /// The active transaction for the command + /// + public IDbTransaction Transaction { get; } + + /// + /// The effective timeout for the command + /// + public int? CommandTimeout { get; } + + /// + /// The type of command that the command-text represents + /// + public CommandType? CommandType { get; } + + /// + /// Should data be buffered before returning? + /// + public bool Buffered => (Flags & CommandFlags.Buffered) != 0; + + /// + /// Should the plan for this query be cached? + /// + internal bool AddToCache => (Flags & CommandFlags.NoCache) == 0; + + /// + /// Additional state flags against this command + /// + public CommandFlags Flags { get; } + + /// + /// Can async queries be pipelined? + /// + public bool Pipelined => (Flags & CommandFlags.Pipelined) != 0; + + /// + /// Initialize the command definition + /// + /// The text for this command. + /// The parameters for this command. + /// The transaction for this command to participate in. + /// The timeout (in seconds) for this command. + /// The for this command. + /// The behavior flags for this command. + /// The cancellation token for this command. + public CommandDefinition(string commandText, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null, + CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered + , CancellationToken cancellationToken = default(CancellationToken) + ) + { + CommandText = commandText; + Parameters = parameters; + Transaction = transaction; + CommandTimeout = commandTimeout; + CommandType = commandType; + Flags = flags; + CancellationToken = cancellationToken; + } + + private CommandDefinition(object parameters) : this() + { + Parameters = parameters; + } + + /// + /// For asynchronous operations, the cancellation-token + /// + public CancellationToken CancellationToken { get; } + + internal IDbCommand SetupCommand(IDbConnection cnn, Action paramReader) + { + var cmd = cnn.CreateCommand(); + var init = GetInit(cmd.GetType()); + init?.Invoke(cmd); + if (Transaction != null) + cmd.Transaction = Transaction; + cmd.CommandText = CommandText; + if (CommandTimeout.HasValue) + { + cmd.CommandTimeout = CommandTimeout.Value; + } + else if (SqlMapper.Settings.CommandTimeout.HasValue) + { + cmd.CommandTimeout = SqlMapper.Settings.CommandTimeout.Value; + } + if (CommandType.HasValue) + cmd.CommandType = CommandType.Value; + paramReader?.Invoke(cmd, Parameters); + return cmd; + } + + private static SqlMapper.Link> commandInitCache; + + private static Action GetInit(Type commandType) + { + if (commandType == null) + return null; // GIGO + if (SqlMapper.Link>.TryGet(commandInitCache, commandType, out Action action)) + { + return action; + } + var bindByName = GetBasicPropertySetter(commandType, "BindByName", typeof(bool)); + var initialLongFetchSize = GetBasicPropertySetter(commandType, "InitialLONGFetchSize", typeof(int)); + + action = null; + if (bindByName != null || initialLongFetchSize != null) + { + var method = new DynamicMethod(commandType.Name + "_init", null, new Type[] { typeof(IDbCommand) }); + var il = method.GetILGenerator(); + + if (bindByName != null) + { + // .BindByName = true + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Castclass, commandType); + il.Emit(OpCodes.Ldc_I4_1); + il.EmitCall(OpCodes.Callvirt, bindByName, null); + } + if (initialLongFetchSize != null) + { + // .InitialLONGFetchSize = -1 + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Castclass, commandType); + il.Emit(OpCodes.Ldc_I4_M1); + il.EmitCall(OpCodes.Callvirt, initialLongFetchSize, null); + } + il.Emit(OpCodes.Ret); + action = (Action)method.CreateDelegate(typeof(Action)); + } + // cache it + SqlMapper.Link>.TryAdd(ref commandInitCache, commandType, ref action); + return action; + } + + private static MethodInfo GetBasicPropertySetter(Type declaringType, string name, Type expectedType) + { + var prop = declaringType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance); + if (prop?.CanWrite == true && prop.PropertyType == expectedType && prop.GetIndexParameters().Length == 0) + { + return prop.GetSetMethod(); + } + return null; + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/CommandFlags.cs b/src/ServiceStack.OrmLite/Dapper/CommandFlags.cs new file mode 100644 index 000000000..d54726c5c --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/CommandFlags.cs @@ -0,0 +1,28 @@ +using System; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Additional state flags that control command behaviour + /// + [Flags] + public enum CommandFlags + { + /// + /// No additional flags + /// + None = 0, + /// + /// Should data be buffered before returning? + /// + Buffered = 1, + /// + /// Can async queries be pipelined? + /// + Pipelined = 2, + /// + /// Should the plan cache be bypassed? + /// + NoCache = 4, + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/CustomPropertyTypeMap.cs b/src/ServiceStack.OrmLite/Dapper/CustomPropertyTypeMap.cs new file mode 100644 index 000000000..f4443d65c --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/CustomPropertyTypeMap.cs @@ -0,0 +1,62 @@ +using System; +using System.Reflection; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Implements custom property mapping by user provided criteria (usually presence of some custom attribute with column to member mapping) + /// + public sealed class CustomPropertyTypeMap : SqlMapper.ITypeMap + { + private readonly Type _type; + private readonly Func _propertySelector; + + /// + /// Creates custom property mapping + /// + /// Target entity type + /// Property selector based on target type and DataReader column name + public CustomPropertyTypeMap(Type type, Func propertySelector) + { + _type = type ?? throw new ArgumentNullException(nameof(type)); + _propertySelector = propertySelector ?? throw new ArgumentNullException(nameof(propertySelector)); + } + + /// + /// Always returns default constructor + /// + /// DataReader column names + /// DataReader column types + /// Default constructor + public ConstructorInfo FindConstructor(string[] names, Type[] types) => + _type.GetConstructor(new Type[0]); + + /// + /// Always returns null + /// + /// + public ConstructorInfo FindExplicitConstructor() => null; + + /// + /// Not implemented as far as default constructor used for all cases + /// + /// + /// + /// + public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName) + { + throw new NotSupportedException(); + } + + /// + /// Returns property based on selector strategy + /// + /// DataReader column name + /// Poperty member map + public SqlMapper.IMemberMap GetMember(string columnName) + { + var prop = _propertySelector(_type, columnName); + return prop != null ? new SimpleMemberMap(columnName, prop) : null; + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/DataTableHandler.cs b/src/ServiceStack.OrmLite/Dapper/DataTableHandler.cs new file mode 100644 index 000000000..ea716b7cb --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/DataTableHandler.cs @@ -0,0 +1,17 @@ +using System; +using System.Data; +namespace ServiceStack.OrmLite.Dapper +{ + internal sealed class DataTableHandler : SqlMapper.ITypeHandler + { + public object Parse(Type destinationType, object value) + { + throw new NotImplementedException(); + } + + public void SetValue(IDbDataParameter parameter, object value) + { + TableValuedParameter.Set(parameter, value as DataTable, null); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/DbString.cs b/src/ServiceStack.OrmLite/Dapper/DbString.cs new file mode 100644 index 000000000..17db4d0f5 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/DbString.cs @@ -0,0 +1,87 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar + /// + public sealed class DbString : SqlMapper.ICustomQueryParameter + { + /// + /// Default value for IsAnsi. + /// + public static bool IsAnsiDefault { get; set; } + + /// + /// A value to set the default value of strings + /// going through Dapper. Default is 4000, any value larger than this + /// field will not have the default value applied. + /// + public const int DefaultLength = 4000; + + /// + /// Create a new DbString + /// + public DbString() + { + Length = -1; + IsAnsi = IsAnsiDefault; + } + /// + /// Ansi vs Unicode + /// + public bool IsAnsi { get; set; } + /// + /// Fixed length + /// + public bool IsFixedLength { get; set; } + /// + /// Length of the string -1 for max + /// + public int Length { get; set; } + /// + /// The value of the string + /// + public string Value { get; set; } + /// + /// Add the parameter to the command... internal use only + /// + /// + /// + public void AddParameter(IDbCommand command, string name) + { + if (IsFixedLength && Length == -1) + { + throw new InvalidOperationException("If specifying IsFixedLength, a Length must also be specified"); + } + bool add = !command.Parameters.Contains(name); + IDbDataParameter param; + if (add) + { + param = command.CreateParameter(); + param.ParameterName = name; + } + else + { + param = (IDbDataParameter)command.Parameters[name]; + } +#pragma warning disable 0618 + param.Value = SqlMapper.SanitizeParameterValue(Value); +#pragma warning restore 0618 + if (Length == -1 && Value != null && Value.Length <= DefaultLength) + { + param.Size = DefaultLength; + } + else + { + param.Size = Length; + } + param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String); + if (add) + { + command.Parameters.Add(param); + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/DefaultTypeMap.cs b/src/ServiceStack.OrmLite/Dapper/DefaultTypeMap.cs new file mode 100644 index 000000000..bd643ac94 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/DefaultTypeMap.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Represents default type mapping strategy used by Dapper + /// + public sealed class DefaultTypeMap : SqlMapper.ITypeMap + { + private readonly List _fields; + private readonly Type _type; + + /// + /// Creates default type map + /// + /// Entity type + public DefaultTypeMap(Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + + _fields = GetSettableFields(type); + Properties = GetSettableProps(type); + _type = type; + } + + internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo, Type type) + { + if (propertyInfo.DeclaringType == type) return propertyInfo.GetSetMethod(true); + + return propertyInfo.DeclaringType.GetProperty( + propertyInfo.Name, + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, + Type.DefaultBinder, + propertyInfo.PropertyType, + propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(), + null).GetSetMethod(true); + } + + internal static List GetSettableProps(Type t) + { + return t + .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .Where(p => GetPropertySetter(p, t) != null) + .ToList(); + } + + internal static List GetSettableFields(Type t) + { + return t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToList(); + } + + /// + /// Finds best constructor + /// + /// DataReader column names + /// DataReader column types + /// Matching constructor or default one + public ConstructorInfo FindConstructor(string[] names, Type[] types) + { + var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + foreach (ConstructorInfo ctor in constructors.OrderBy(c => c.IsPublic ? 0 : (c.IsPrivate ? 2 : 1)).ThenBy(c => c.GetParameters().Length)) + { + ParameterInfo[] ctorParameters = ctor.GetParameters(); + if (ctorParameters.Length == 0) + return ctor; + + if (ctorParameters.Length != types.Length) + continue; + + int i = 0; + for (; i < ctorParameters.Length; i++) + { + if (!string.Equals(ctorParameters[i].Name, names[i], StringComparison.OrdinalIgnoreCase)) + break; + if (types[i] == typeof(byte[]) && ctorParameters[i].ParameterType.FullName == SqlMapper.LinqBinary) + continue; + var unboxedType = Nullable.GetUnderlyingType(ctorParameters[i].ParameterType) ?? ctorParameters[i].ParameterType; + if ((unboxedType != types[i] && !SqlMapper.HasTypeHandler(unboxedType)) + && !(unboxedType.IsEnum && Enum.GetUnderlyingType(unboxedType) == types[i]) + && !(unboxedType == typeof(char) && types[i] == typeof(string)) + && !(unboxedType.IsEnum && types[i] == typeof(string))) + { + break; + } + } + + if (i == ctorParameters.Length) + return ctor; + } + + return null; + } + + /// + /// Returns the constructor, if any, that has the ExplicitConstructorAttribute on it. + /// + public ConstructorInfo FindExplicitConstructor() + { + var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + var withAttr = constructors.Where(c => c.GetCustomAttributes(typeof(ExplicitConstructorAttribute), true).Length > 0).ToList(); + + if (withAttr.Count == 1) + { + return withAttr[0]; + } + + return null; + } + + /// + /// Gets mapping for constructor parameter + /// + /// Constructor to resolve + /// DataReader column name + /// Mapping implementation + public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName) + { + var parameters = constructor.GetParameters(); + + return new SimpleMemberMap(columnName, parameters.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase))); + } + + /// + /// Gets member mapping for column + /// + /// DataReader column name + /// Mapping implementation + public SqlMapper.IMemberMap GetMember(string columnName) + { + var property = Properties.Find(p => string.Equals(p.Name, columnName, StringComparison.Ordinal)) + ?? Properties.Find(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase)); + + if (property == null && MatchNamesWithUnderscores) + { + property = Properties.Find(p => string.Equals(p.Name, columnName.Replace("_", ""), StringComparison.Ordinal)) + ?? Properties.Find(p => string.Equals(p.Name, columnName.Replace("_", ""), StringComparison.OrdinalIgnoreCase)); + } + + if (property != null) + return new SimpleMemberMap(columnName, property); + + // roslyn automatically implemented properties, in particular for get-only properties: <{Name}>k__BackingField; + var backingFieldName = "<" + columnName + ">k__BackingField"; + + // preference order is: + // exact match over underscre match, exact case over wrong case, backing fields over regular fields, match-inc-underscores over match-exc-underscores + var field = _fields.Find(p => string.Equals(p.Name, columnName, StringComparison.Ordinal)) + ?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.Ordinal)) + ?? _fields.Find(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase)) + ?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.OrdinalIgnoreCase)); + + if (field == null && MatchNamesWithUnderscores) + { + var effectiveColumnName = columnName.Replace("_", ""); + backingFieldName = "<" + effectiveColumnName + ">k__BackingField"; + + field = _fields.Find(p => string.Equals(p.Name, effectiveColumnName, StringComparison.Ordinal)) + ?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.Ordinal)) + ?? _fields.Find(p => string.Equals(p.Name, effectiveColumnName, StringComparison.OrdinalIgnoreCase)) + ?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.OrdinalIgnoreCase)); + } + + if (field != null) + return new SimpleMemberMap(columnName, field); + + return null; + } + /// + /// Should column names like User_Id be allowed to match properties/fields like UserId ? + /// + public static bool MatchNamesWithUnderscores { get; set; } + + /// + /// The settable properties for this typemap + /// + public List Properties { get; } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/DynamicParameters.CachedOutputSetters.cs b/src/ServiceStack.OrmLite/Dapper/DynamicParameters.CachedOutputSetters.cs new file mode 100644 index 000000000..3e03c99cd --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/DynamicParameters.CachedOutputSetters.cs @@ -0,0 +1,16 @@ +using System.Collections; + +namespace ServiceStack.OrmLite.Dapper +{ + public partial class DynamicParameters + { + // The type here is used to differentiate the cache by type via generics + // ReSharper disable once UnusedTypeParameter + internal static class CachedOutputSetters + { + // Intentional, abusing generics to get our cache splits + // ReSharper disable once StaticMemberInGenericType + public static readonly Hashtable Cache = new Hashtable(); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/DynamicParameters.ParamInfo.cs b/src/ServiceStack.OrmLite/Dapper/DynamicParameters.ParamInfo.cs new file mode 100644 index 000000000..a00d9402e --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/DynamicParameters.ParamInfo.cs @@ -0,0 +1,24 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public partial class DynamicParameters + { + private sealed class ParamInfo + { + public string Name { get; set; } + public object Value { get; set; } + public ParameterDirection ParameterDirection { get; set; } + public DbType? DbType { get; set; } + public int? Size { get; set; } + public IDbDataParameter AttachedParam { get; set; } + internal Action OutputCallback { get; set; } + internal object OutputTarget { get; set; } + internal bool CameFromTemplate { get; set; } + + public byte? Precision { get; set; } + public byte? Scale { get; set; } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/DynamicParameters.cs b/src/ServiceStack.OrmLite/Dapper/DynamicParameters.cs new file mode 100644 index 000000000..da1cbeb66 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/DynamicParameters.cs @@ -0,0 +1,499 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// A bag of parameters that can be passed to the Dapper Query and Execute methods + /// + public partial class DynamicParameters : SqlMapper.IDynamicParameters, SqlMapper.IParameterLookup, SqlMapper.IParameterCallbacks + { + internal const DbType EnumerableMultiParameter = (DbType)(-1); + private static readonly Dictionary> paramReaderCache = new Dictionary>(); + private readonly Dictionary parameters = new Dictionary(); + private List templates; + + object SqlMapper.IParameterLookup.this[string name] => + parameters.TryGetValue(name, out ParamInfo param) ? param.Value : null; + + /// + /// construct a dynamic parameter bag + /// + public DynamicParameters() + { + RemoveUnused = true; + } + + /// + /// construct a dynamic parameter bag + /// + /// can be an anonymous type or a DynamicParameters bag + public DynamicParameters(object template) + { + RemoveUnused = true; + AddDynamicParams(template); + } + + /// + /// Append a whole object full of params to the dynamic + /// EG: AddDynamicParams(new {A = 1, B = 2}) // will add property A and B to the dynamic + /// + /// + public void AddDynamicParams(object param) + { + var obj = param; + if (obj != null) + { + var subDynamic = obj as DynamicParameters; + if (subDynamic == null) + { + var dictionary = obj as IEnumerable>; + if (dictionary == null) + { + templates = templates ?? new List(); + templates.Add(obj); + } + else + { + foreach (var kvp in dictionary) + { + Add(kvp.Key, kvp.Value, null, null, null); + } + } + } + else + { + if (subDynamic.parameters != null) + { + foreach (var kvp in subDynamic.parameters) + { + parameters.Add(kvp.Key, kvp.Value); + } + } + + if (subDynamic.templates != null) + { + templates = templates ?? new List(); + foreach (var t in subDynamic.templates) + { + templates.Add(t); + } + } + } + } + } + + /// + /// Add a parameter to this dynamic parameter list. + /// + /// The name of the parameter. + /// The value of the parameter. + /// The type of the parameter. + /// The in or out direction of the parameter. + /// The size of the parameter. + public void Add(string name, object value, DbType? dbType, ParameterDirection? direction, int? size) + { + parameters[Clean(name)] = new ParamInfo + { + Name = name, + Value = value, + ParameterDirection = direction ?? ParameterDirection.Input, + DbType = dbType, + Size = size + }; + } + + /// + /// Add a parameter to this dynamic parameter list. + /// + /// The name of the parameter. + /// The value of the parameter. + /// The type of the parameter. + /// The in or out direction of the parameter. + /// The size of the parameter. + /// The precision of the parameter. + /// The scale of the parameter. + public void Add(string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null, byte? precision = null, byte? scale = null) + { + parameters[Clean(name)] = new ParamInfo + { + Name = name, + Value = value, + ParameterDirection = direction ?? ParameterDirection.Input, + DbType = dbType, + Size = size, + Precision = precision, + Scale = scale + }; + } + + private static string Clean(string name) + { + if (!string.IsNullOrEmpty(name)) + { + switch (name[0]) + { + case '@': + case ':': + case '?': + return name.Substring(1); + } + } + return name; + } + + void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Identity identity) + { + AddParameters(command, identity); + } + + /// + /// If true, the command-text is inspected and only values that are clearly used are included on the connection + /// + public bool RemoveUnused { get; set; } + + /// + /// Add all the parameters needed to the command just before it executes + /// + /// The raw command prior to execution + /// Information about the query + protected void AddParameters(IDbCommand command, SqlMapper.Identity identity) + { + var literals = SqlMapper.GetLiteralTokens(identity.sql); + + if (templates != null) + { + foreach (var template in templates) + { + var newIdent = identity.ForDynamicParameters(template.GetType()); + Action appender; + + lock (paramReaderCache) + { + if (!paramReaderCache.TryGetValue(newIdent, out appender)) + { + appender = SqlMapper.CreateParamInfoGenerator(newIdent, true, RemoveUnused, literals); + paramReaderCache[newIdent] = appender; + } + } + + appender(command, template); + } + + // The parameters were added to the command, but not the + // DynamicParameters until now. + foreach (IDbDataParameter param in command.Parameters) + { + // If someone makes a DynamicParameters with a template, + // then explicitly adds a parameter of a matching name, + // it will already exist in 'parameters'. + if (!parameters.ContainsKey(param.ParameterName)) + { + parameters.Add(param.ParameterName, new ParamInfo + { + AttachedParam = param, + CameFromTemplate = true, + DbType = param.DbType, + Name = param.ParameterName, + ParameterDirection = param.Direction, + Size = param.Size, + Value = param.Value + }); + } + } + + // Now that the parameters are added to the command, let's place our output callbacks + var tmp = outputCallbacks; + if (tmp != null) + { + foreach (var generator in tmp) + { + generator(); + } + } + } + + foreach (var param in parameters.Values) + { + if (param.CameFromTemplate) continue; + + var dbType = param.DbType; + var val = param.Value; + string name = Clean(param.Name); + var isCustomQueryParameter = val is SqlMapper.ICustomQueryParameter; + + SqlMapper.ITypeHandler handler = null; + if (dbType == null && val != null && !isCustomQueryParameter) + { +#pragma warning disable 618 + dbType = SqlMapper.LookupDbType(val.GetType(), name, true, out handler); +#pragma warning disable 618 + } + if (isCustomQueryParameter) + { + ((SqlMapper.ICustomQueryParameter)val).AddParameter(command, name); + } + else if (dbType == EnumerableMultiParameter) + { +#pragma warning disable 612, 618 + SqlMapper.PackListParameters(command, name, val); +#pragma warning restore 612, 618 + } + else + { + bool add = !command.Parameters.Contains(name); + IDbDataParameter p; + if (add) + { + p = command.CreateParameter(); + p.ParameterName = name; + } + else + { + p = (IDbDataParameter)command.Parameters[name]; + } + + p.Direction = param.ParameterDirection; + if (handler == null) + { +#pragma warning disable 0618 + p.Value = SqlMapper.SanitizeParameterValue(val); +#pragma warning restore 0618 + if (dbType != null && p.DbType != dbType) + { + p.DbType = dbType.Value; + } + var s = val as string; + if (s?.Length <= DbString.DefaultLength) + { + p.Size = DbString.DefaultLength; + } + if (param.Size != null) p.Size = param.Size.Value; + if (param.Precision != null) p.Precision = param.Precision.Value; + if (param.Scale != null) p.Scale = param.Scale.Value; + } + else + { + if (dbType != null) p.DbType = dbType.Value; + if (param.Size != null) p.Size = param.Size.Value; + if (param.Precision != null) p.Precision = param.Precision.Value; + if (param.Scale != null) p.Scale = param.Scale.Value; + handler.SetValue(p, val ?? DBNull.Value); + } + + if (add) + { + command.Parameters.Add(p); + } + param.AttachedParam = p; + } + } + + // note: most non-priveleged implementations would use: this.ReplaceLiterals(command); + if (literals.Count != 0) SqlMapper.ReplaceLiterals(this, command, literals); + } + + /// + /// All the names of the param in the bag, use Get to yank them out + /// + public IEnumerable ParameterNames => parameters.Select(p => p.Key); + + /// + /// Get the value of a parameter + /// + /// + /// + /// The value, note DBNull.Value is not returned, instead the value is returned as null + public T Get(string name) + { + var paramInfo = parameters[Clean(name)]; + var attachedParam = paramInfo.AttachedParam; + object val = attachedParam == null ? paramInfo.Value : attachedParam.Value; + if (val == DBNull.Value) + { + if (default(T) != null) + { + throw new ApplicationException("Attempting to cast a DBNull to a non nullable type! Note that out/return parameters will not have updated values until the data stream completes (after the 'foreach' for Query(..., buffered: false), or after the GridReader has been disposed for QueryMultiple)"); + } + return default(T); + } + return (T)val; + } + + /// + /// Allows you to automatically populate a target property/field from output parameters. It actually + /// creates an InputOutput parameter, so you can still pass data in. + /// + /// + /// The object whose property/field you wish to populate. + /// A MemberExpression targeting a property/field of the target (or descendant thereof.) + /// + /// The size to set on the parameter. Defaults to 0, or DbString.DefaultLength in case of strings. + /// The DynamicParameters instance + public DynamicParameters Output(T target, Expression> expression, DbType? dbType = null, int? size = null) + { + var failMessage = "Expression must be a property/field chain off of a(n) {0} instance"; + failMessage = string.Format(failMessage, typeof(T).Name); + Action @throw = () => throw new InvalidOperationException(failMessage); + + // Is it even a MemberExpression? + var lastMemberAccess = expression.Body as MemberExpression; + + if (lastMemberAccess == null + || (!(lastMemberAccess.Member is PropertyInfo) + && !(lastMemberAccess.Member is FieldInfo))) + { + if (expression.Body.NodeType == ExpressionType.Convert + && expression.Body.Type == typeof(object) + && ((UnaryExpression)expression.Body).Operand is MemberExpression) + { + // It's got to be unboxed + lastMemberAccess = (MemberExpression)((UnaryExpression)expression.Body).Operand; + } + else + { + @throw(); + } + } + + // Does the chain consist of MemberExpressions leading to a ParameterExpression of type T? + MemberExpression diving = lastMemberAccess; + // Retain a list of member names and the member expressions so we can rebuild the chain. + List names = new List(); + List chain = new List(); + + do + { + // Insert the names in the right order so expression + // "Post.Author.Name" becomes parameter "PostAuthorName" + names.Insert(0, diving?.Member.Name); + chain.Insert(0, diving); + + var constant = diving?.Expression as ParameterExpression; + diving = diving?.Expression as MemberExpression; + + if (constant != null && constant.Type == typeof(T)) + { + break; + } + else if (diving == null + || (!(diving.Member is PropertyInfo) + && !(diving.Member is FieldInfo))) + { + @throw(); + } + } + while (diving != null); + + var dynamicParamName = string.Concat(names.ToArray()); + + // Before we get all emitty... + var lookup = string.Join("|", names.ToArray()); + + var cache = CachedOutputSetters.Cache; + var setter = (Action)cache[lookup]; + if (setter != null) goto MAKECALLBACK; + + // Come on let's build a method, let's build it, let's build it now! + var dm = new DynamicMethod("ExpressionParam" + Guid.NewGuid().ToString(), null, new[] { typeof(object), GetType() }, true); + var il = dm.GetILGenerator(); + + il.Emit(OpCodes.Ldarg_0); // [object] + il.Emit(OpCodes.Castclass, typeof(T)); // [T] + + // Count - 1 to skip the last member access + for (var i = 0; i < chain.Count - 1; i++) + { + var member = chain[i].Member; + + if (member is PropertyInfo) + { + var get = ((PropertyInfo)member).GetGetMethod(true); + il.Emit(OpCodes.Callvirt, get); // [Member{i}] + } + else // Else it must be a field! + { + il.Emit(OpCodes.Ldfld, (FieldInfo)member); // [Member{i}] + } + } + + var paramGetter = GetType().GetMethod("Get", new Type[] { typeof(string) }).MakeGenericMethod(lastMemberAccess.Type); + + il.Emit(OpCodes.Ldarg_1); // [target] [DynamicParameters] + il.Emit(OpCodes.Ldstr, dynamicParamName); // [target] [DynamicParameters] [ParamName] + il.Emit(OpCodes.Callvirt, paramGetter); // [target] [value], it's already typed thanks to generic method + + // GET READY + var lastMember = lastMemberAccess.Member; + if (lastMember is PropertyInfo) + { + var set = ((PropertyInfo)lastMember).GetSetMethod(true); + il.Emit(OpCodes.Callvirt, set); // SET + } + else + { + il.Emit(OpCodes.Stfld, (FieldInfo)lastMember); // SET + } + + il.Emit(OpCodes.Ret); // GO + + setter = (Action)dm.CreateDelegate(typeof(Action)); + lock (cache) + { + cache[lookup] = setter; + } + + // Queue the preparation to be fired off when adding parameters to the DbCommand + MAKECALLBACK: + (outputCallbacks ??= new List()).Add(() => + { + // Finally, prep the parameter and attach the callback to it + var targetMemberType = lastMemberAccess?.Type; + int sizeToSet = (!size.HasValue && targetMemberType == typeof(string)) ? DbString.DefaultLength : size ?? 0; + + if (parameters.TryGetValue(dynamicParamName, out ParamInfo parameter)) + { + parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput; + + if (parameter.AttachedParam.Size == 0) + { + parameter.Size = parameter.AttachedParam.Size = sizeToSet; + } + } + else + { + dbType = (!dbType.HasValue) +#pragma warning disable 618 + ? SqlMapper.LookupDbType(targetMemberType, targetMemberType?.Name, true, out SqlMapper.ITypeHandler handler) +#pragma warning restore 618 + : dbType; + + // CameFromTemplate property would not apply here because this new param + // Still needs to be added to the command + Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet); + } + + parameter = parameters[dynamicParamName]; + parameter.OutputCallback = setter; + parameter.OutputTarget = target; + }); + + return this; + } + + private List outputCallbacks; + + void SqlMapper.IParameterCallbacks.OnCompleted() + { + foreach (var param in from p in parameters select p.Value) + { + param.OutputCallback?.Invoke(param.OutputTarget, this); + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/ExplicitConstructorAttribute.cs b/src/ServiceStack.OrmLite/Dapper/ExplicitConstructorAttribute.cs new file mode 100644 index 000000000..7028aece2 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/ExplicitConstructorAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Tell Dapper to use an explicit constructor, passing nulls or 0s for all parameters + /// + [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)] + public sealed class ExplicitConstructorAttribute : Attribute + { + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/Extensions.cs b/src/ServiceStack.OrmLite/Dapper/Extensions.cs new file mode 100644 index 000000000..f3cf59943 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/Extensions.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Dapper +{ + internal static class Extensions + { + /// + /// Creates a with a less specific generic parameter that perfectly mirrors the + /// state of the specified . + /// + internal static Task CastResult(this Task task) + where TFrom : TTo + { + if (task is null) throw new ArgumentNullException(nameof(task)); + + if (task.Status == TaskStatus.RanToCompletion) + return Task.FromResult((TTo)task.Result); + + var source = new TaskCompletionSource(); + task.ContinueWith(OnTaskCompleted, state: source, TaskContinuationOptions.ExecuteSynchronously); + return source.Task; + } + + private static void OnTaskCompleted(Task completedTask, object state) + where TFrom : TTo + { + var source = (TaskCompletionSource)state; + + switch (completedTask.Status) + { + case TaskStatus.RanToCompletion: + source.SetResult(completedTask.Result); + break; + case TaskStatus.Canceled: + source.SetCanceled(); + break; + case TaskStatus.Faulted: + source.SetException(completedTask.Exception.InnerExceptions); + break; + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/FeatureSupport.cs b/src/ServiceStack.OrmLite/Dapper/FeatureSupport.cs new file mode 100644 index 000000000..fb6662a81 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/FeatureSupport.cs @@ -0,0 +1,36 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Handles variances in features per DBMS + /// + internal class FeatureSupport + { + private static readonly FeatureSupport + Default = new FeatureSupport(false), + Postgres = new FeatureSupport(true); + + /// + /// Gets the feature set based on the passed connection + /// + /// The connection to get supported features for. + public static FeatureSupport Get(IDbConnection connection) + { + string name = connection?.GetType().Name; + if (string.Equals(name, "npgsqlconnection", StringComparison.OrdinalIgnoreCase)) return Postgres; + return Default; + } + + private FeatureSupport(bool arrays) + { + Arrays = arrays; + } + + /// + /// True if the db supports array columns e.g. Postgresql + /// + public bool Arrays { get; } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SimpleMemberMap.cs b/src/ServiceStack.OrmLite/Dapper/SimpleMemberMap.cs new file mode 100644 index 000000000..8abaa3026 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SimpleMemberMap.cs @@ -0,0 +1,69 @@ +using System; +using System.Reflection; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Represents simple member map for one of target parameter or property or field to source DataReader column + /// + internal sealed class SimpleMemberMap : SqlMapper.IMemberMap + { + /// + /// Creates instance for simple property mapping + /// + /// DataReader column name + /// Target property + public SimpleMemberMap(string columnName, PropertyInfo property) + { + ColumnName = columnName ?? throw new ArgumentNullException(nameof(columnName)); + Property = property ?? throw new ArgumentNullException(nameof(property)); + } + + /// + /// Creates instance for simple field mapping + /// + /// DataReader column name + /// Target property + public SimpleMemberMap(string columnName, FieldInfo field) + { + ColumnName = columnName ?? throw new ArgumentNullException(nameof(columnName)); + Field = field ?? throw new ArgumentNullException(nameof(field)); + } + + /// + /// Creates instance for simple constructor parameter mapping + /// + /// DataReader column name + /// Target constructor parameter + public SimpleMemberMap(string columnName, ParameterInfo parameter) + { + ColumnName = columnName ?? throw new ArgumentNullException(nameof(columnName)); + Parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); + } + + /// + /// DataReader column name + /// + public string ColumnName { get; } + + /// + /// Target member type + /// + public Type MemberType => Field?.FieldType ?? Property?.PropertyType ?? Parameter?.ParameterType; + + /// + /// Target property + /// + public PropertyInfo Property { get; } + + /// + /// Target field + /// + public FieldInfo Field { get; } + + /// + /// Target constructor parameter + /// + public ParameterInfo Parameter { get; } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlDataRecordHandler.cs b/src/ServiceStack.OrmLite/Dapper/SqlDataRecordHandler.cs new file mode 100644 index 000000000..4e9e89421 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlDataRecordHandler.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + internal sealed class SqlDataRecordHandler : SqlMapper.ITypeHandler + where T : IDataRecord + { + public object Parse(Type destinationType, object value) + { + throw new NotSupportedException(); + } + + public void SetValue(IDbDataParameter parameter, object value) + { + SqlDataRecordListTVPParameter.Set(parameter, value as IEnumerable, null); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlDataRecordListTVPParameter.cs b/src/ServiceStack.OrmLite/Dapper/SqlDataRecordListTVPParameter.cs new file mode 100644 index 000000000..b4c6784e0 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlDataRecordListTVPParameter.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Used to pass a IEnumerable<SqlDataRecord> as a SqlDataRecordListTVPParameter + /// + internal sealed class SqlDataRecordListTVPParameter : SqlMapper.ICustomQueryParameter + where T : IDataRecord + { + private readonly IEnumerable data; + private readonly string typeName; + /// + /// Create a new instance of . + /// + /// The data records to convert into TVPs. + /// The parameter type name. + public SqlDataRecordListTVPParameter(IEnumerable data, string typeName) + { + this.data = data; + this.typeName = typeName; + } + + void SqlMapper.ICustomQueryParameter.AddParameter(IDbCommand command, string name) + { + var param = command.CreateParameter(); + param.ParameterName = name; + Set(param, data, typeName); + command.Parameters.Add(param); + } + + internal static void Set(IDbDataParameter parameter, IEnumerable data, string typeName) + { + parameter.Value = data != null && data.Any() ? data : null; + StructuredHelper.ConfigureTVP(parameter, typeName); + } + } + static class StructuredHelper + { + private static readonly Hashtable s_udt = new Hashtable(), s_tvp = new Hashtable(); + + private static Action GetUDT(Type type) + => (Action)s_udt[type] ?? SlowGetHelper(type, s_udt, "UdtTypeName", 29); // 29 = SqlDbType.Udt (avoiding ref) + private static Action GetTVP(Type type) + => (Action)s_tvp[type] ?? SlowGetHelper(type, s_tvp, "TypeName", 30); // 30 = SqlDbType.Structured (avoiding ref) + + static Action SlowGetHelper(Type type, Hashtable hashtable, string nameProperty, int sqlDbType) + { + lock (hashtable) + { + var helper = (Action)hashtable[type]; + if (helper == null) + { + helper = CreateFor(type, nameProperty, sqlDbType); + hashtable.Add(type, helper); + } + return helper; + } + } + + static Action CreateFor(Type type, string nameProperty, int sqlDbType) + { + var name = type.GetProperty(nameProperty, BindingFlags.Public | BindingFlags.Instance); + if (name == null || !name.CanWrite) + { + return (p, n) => { }; + } + + var dbType = type.GetProperty("SqlDbType", BindingFlags.Public | BindingFlags.Instance); + if (dbType != null && !dbType.CanWrite) dbType = null; + + var dm = new DynamicMethod(nameof(CreateFor) + "_" + type.Name, null, + new[] { typeof(IDbDataParameter), typeof(string) }, true); + var il = dm.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Castclass, type); + il.Emit(OpCodes.Ldarg_1); + il.EmitCall(OpCodes.Callvirt, name.GetSetMethod(), null); + + if (dbType != null) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Castclass, type); + il.Emit(OpCodes.Ldc_I4, sqlDbType); + il.EmitCall(OpCodes.Callvirt, dbType.GetSetMethod(), null); + } + + il.Emit(OpCodes.Ret); + return (Action)dm.CreateDelegate(typeof(Action)); + + } + + // this needs to be done per-provider; "dynamic" doesn't work well on all runtimes, although that + // would be a fair option otherwise + internal static void ConfigureUDT(IDbDataParameter parameter, string typeName) + => GetUDT(parameter.GetType())(parameter, typeName); + internal static void ConfigureTVP(IDbDataParameter parameter, string typeName) + => GetTVP(parameter.GetType())(parameter, typeName); + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.Async.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Async.cs new file mode 100644 index 000000000..ceab3c75c --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Async.cs @@ -0,0 +1,1258 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Execute a query asynchronously using Task. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static Task> QueryAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryAsync(cnn, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); + + /// + /// Execute a query asynchronously using Task. + /// + /// The connection to query on. + /// The command used to query on this connection. + /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command) => + QueryAsync(cnn, typeof(DapperRow), command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The command used to query on this connection. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static Task QueryFirstAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.First, typeof(DapperRow), command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The command used to query on this connection. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.FirstOrDefault, typeof(DapperRow), command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The command used to query on this connection. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static Task QuerySingleAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.Single, typeof(DapperRow), command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The command used to query on this connection. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.SingleOrDefault, typeof(DapperRow), command); + + /// + /// Execute a query asynchronously using Task. + /// + /// The type of results to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of ; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static Task> QueryAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryAsync(cnn, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QueryFirstAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.First, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.FirstOrDefault, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QuerySingleAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.Single, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.SingleOrDefault, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QueryFirstAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.First, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.FirstOrDefault, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QuerySingleAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.Single, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.SingleOrDefault, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + + /// + /// Execute a query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + public static Task> QueryAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return QueryAsync(cnn, type, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); + } + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + public static Task QueryFirstAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return QueryRowAsync(cnn, Row.First, type, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + } + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return QueryRowAsync(cnn, Row.FirstOrDefault, type, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + } + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + public static Task QuerySingleAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return QueryRowAsync(cnn, Row.Single, type, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + } + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return QueryRowAsync(cnn, Row.SingleOrDefault, type, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + } + + /// + /// Execute a query asynchronously using Task. + /// + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A sequence of data of ; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command) => + QueryAsync(cnn, typeof(T), command); + + /// + /// Execute a query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task> QueryAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryAsync(cnn, type, command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QueryFirstAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.First, type, command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QueryFirstAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.First, typeof(T), command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.FirstOrDefault, type, command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.FirstOrDefault, typeof(T), command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QuerySingleAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.Single, type, command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QuerySingleAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.Single, typeof(T), command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.SingleOrDefault, type, command); + + /// + /// Execute a single-row query asynchronously using Task. + /// + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.SingleOrDefault, typeof(T), command); + + private static Task ExecuteReaderWithFlagsFallbackAsync(DbCommand cmd, bool wasClosed, CommandBehavior behavior, CancellationToken cancellationToken) + { + var task = cmd.ExecuteReaderAsync(GetBehavior(wasClosed, behavior), cancellationToken); + if (task.Status == TaskStatus.Faulted && Settings.DisableCommandBehaviorOptimizations(behavior, task.Exception.InnerException)) + { // we can retry; this time it will have different flags + return cmd.ExecuteReaderAsync(GetBehavior(wasClosed, behavior), cancellationToken); + } + return task; + } + + /// + /// Attempts to open a connection asynchronously, with a better error message for unsupported usages. + /// + private static Task TryOpenAsync(this IDbConnection cnn, CancellationToken cancel) + { + if (cnn is DbConnection dbConn) + { + return dbConn.OpenAsync(cancel); + } + else + { + throw new InvalidOperationException("Async operations require use of a DbConnection or an already-open IDbConnection"); + } + } + + /// + /// Attempts setup a on a , with a better error message for unsupported usages. + /// + private static DbCommand TrySetupAsyncCommand(this CommandDefinition command, IDbConnection cnn, Action paramReader) + { + if (command.SetupCommand(cnn, paramReader) is DbCommand dbCommand) + { + return dbCommand; + } + else + { + throw new InvalidOperationException("Async operations require use of a DbConnection or an IDbConnection where .CreateCommand() returns a DbCommand"); + } + } + + private static async Task> QueryAsync(this IDbConnection cnn, Type effectiveType, CommandDefinition command) + { + object param = command.Parameters; + var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType()); + var info = GetCacheInfo(identity, param, command.AddToCache); + bool wasClosed = cnn.State == ConnectionState.Closed; + var cancel = command.CancellationToken; + using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) + { + DbDataReader reader = null; + try + { + if (wasClosed) await cnn.TryOpenAsync(cancel).ConfigureAwait(false); + reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult, cancel).ConfigureAwait(false); + + var tuple = info.Deserializer; + int hash = GetColumnHash(reader); + if (tuple.Func == null || tuple.Hash != hash) + { + if (reader.FieldCount == 0) + return Enumerable.Empty(); + tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(effectiveType, reader, 0, -1, false)); + if (command.AddToCache) SetQueryCache(identity, info); + } + + var func = tuple.Func; + + if (command.Buffered) + { + var buffer = new List(); + var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; + while (await reader.ReadAsync(cancel).ConfigureAwait(false)) + { + object val = func(reader); + if (val == null || val is T) + { + buffer.Add((T)val); + } + else + { + buffer.Add((T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture)); + } + } + while (await reader.NextResultAsync(cancel).ConfigureAwait(false)) { /* ignore subsequent result sets */ } + command.OnCompleted(); + return buffer; + } + else + { + // can't use ReadAsync / cancellation; but this will have to do + wasClosed = false; // don't close if handing back an open reader; rely on the command-behavior + var deferred = ExecuteReaderSync(reader, func, command.Parameters); + reader = null; // to prevent it being disposed before the caller gets to see it + return deferred; + } + } + finally + { + using (reader) { /* dispose if non-null */ } + if (wasClosed) cnn.Close(); + } + } + } + + private static async Task QueryRowAsync(this IDbConnection cnn, Row row, Type effectiveType, CommandDefinition command) + { + object param = command.Parameters; + var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType()); + var info = GetCacheInfo(identity, param, command.AddToCache); + bool wasClosed = cnn.State == ConnectionState.Closed; + var cancel = command.CancellationToken; + using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) + { + DbDataReader reader = null; + try + { + if (wasClosed) await cnn.TryOpenAsync(cancel).ConfigureAwait(false); + reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, (row & Row.Single) != 0 + ? CommandBehavior.SequentialAccess | CommandBehavior.SingleResult // need to allow multiple rows, to check fail condition + : CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow, cancel).ConfigureAwait(false); + + T result = default(T); + if (await reader.ReadAsync(cancel).ConfigureAwait(false) && reader.FieldCount != 0) + { + var tuple = info.Deserializer; + int hash = GetColumnHash(reader); + if (tuple.Func == null || tuple.Hash != hash) + { + tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(effectiveType, reader, 0, -1, false)); + if (command.AddToCache) SetQueryCache(identity, info); + } + + var func = tuple.Func; + + object val = func(reader); + if (val == null || val is T) + { + result = (T)val; + } + else + { + var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; + result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); + } + if ((row & Row.Single) != 0 && await reader.ReadAsync(cancel).ConfigureAwait(false)) ThrowMultipleRows(row); + while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { /* ignore rows after the first */ } + } + else if ((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one + { + ThrowZeroRows(row); + } + while (await reader.NextResultAsync(cancel).ConfigureAwait(false)) { /* ignore result sets after the first */ } + return result; + } + finally + { + using (reader) { /* dispose if non-null */ } + if (wasClosed) cnn.Close(); + } + } + } + + /// + /// Execute a command asynchronously using Task. + /// + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The number of rows affected. + public static Task ExecuteAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); + + /// + /// Execute a command asynchronously using Task. + /// + /// The connection to execute on. + /// The command to execute on this connection. + /// The number of rows affected. + public static Task ExecuteAsync(this IDbConnection cnn, CommandDefinition command) + { + object param = command.Parameters; + IEnumerable multiExec = GetMultiExec(param); + if (multiExec != null) + { + return ExecuteMultiImplAsync(cnn, command, multiExec); + } + else + { + return ExecuteImplAsync(cnn, command, param); + } + } + + private struct AsyncExecState + { + public readonly DbCommand Command; + public readonly Task Task; + public AsyncExecState(DbCommand command, Task task) + { + Command = command; + Task = task; + } + } + + private static async Task ExecuteMultiImplAsync(IDbConnection cnn, CommandDefinition command, IEnumerable multiExec) + { + bool isFirst = true; + int total = 0; + bool wasClosed = cnn.State == ConnectionState.Closed; + try + { + if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); + + CacheInfo info = null; + string masterSql = null; + if ((command.Flags & CommandFlags.Pipelined) != 0) + { + const int MAX_PENDING = 100; + var pending = new Queue(MAX_PENDING); + DbCommand cmd = null; + try + { + foreach (var obj in multiExec) + { + if (isFirst) + { + isFirst = false; + cmd = command.TrySetupAsyncCommand(cnn, null); + masterSql = cmd.CommandText; + var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType()); + info = GetCacheInfo(identity, obj, command.AddToCache); + } + else if (pending.Count >= MAX_PENDING) + { + var recycled = pending.Dequeue(); + total += await recycled.Task.ConfigureAwait(false); + cmd = recycled.Command; + cmd.CommandText = masterSql; // because we do magic replaces on "in" etc + cmd.Parameters.Clear(); // current code is Add-tastic + } + else + { + cmd = command.TrySetupAsyncCommand(cnn, null); + } + info.ParamReader(cmd, obj); + + var task = cmd.ExecuteNonQueryAsync(command.CancellationToken); + pending.Enqueue(new AsyncExecState(cmd, task)); + cmd = null; // note the using in the finally: this avoids a double-dispose + } + while (pending.Count != 0) + { + var pair = pending.Dequeue(); + using (pair.Command) { /* dispose commands */ } + total += await pair.Task.ConfigureAwait(false); + } + } + finally + { + // this only has interesting work to do if there are failures + using (cmd) { /* dispose commands */ } + while (pending.Count != 0) + { // dispose tasks even in failure + using (pending.Dequeue().Command) { /* dispose commands */ } + } + } + } + else + { + using (var cmd = command.TrySetupAsyncCommand(cnn, null)) + { + foreach (var obj in multiExec) + { + if (isFirst) + { + masterSql = cmd.CommandText; + isFirst = false; + var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType()); + info = GetCacheInfo(identity, obj, command.AddToCache); + } + else + { + cmd.CommandText = masterSql; // because we do magic replaces on "in" etc + cmd.Parameters.Clear(); // current code is Add-tastic + } + info.ParamReader(cmd, obj); + total += await cmd.ExecuteNonQueryAsync(command.CancellationToken).ConfigureAwait(false); + } + } + } + + command.OnCompleted(); + } + finally + { + if (wasClosed) cnn.Close(); + } + return total; + } + + private static async Task ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, object param) + { + var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param?.GetType()); + var info = GetCacheInfo(identity, param, command.AddToCache); + bool wasClosed = cnn.State == ConnectionState.Closed; + using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) + { + try + { + if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); + var result = await cmd.ExecuteNonQueryAsync(command.CancellationToken).ConfigureAwait(false); + command.OnCompleted(); + return result; + } + finally + { + if (wasClosed) cnn.Close(); + } + } + } + + /// + /// Perform a asynchronous multi-mapping query with 2 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, + new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 2 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 3 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, + new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 3 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 4 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, + new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 4 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 5 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, + new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 5 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 6 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, + new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 6 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); + + /// + /// Perform a asynchronous multi-mapping query with 7 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The seventh type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, + new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); + + /// + /// Perform an asynchronous multi-mapping query with 7 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The seventh type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); + + private static async Task> MultiMapAsync(this IDbConnection cnn, CommandDefinition command, Delegate map, string splitOn) + { + object param = command.Parameters; + var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param?.GetType()); + var info = GetCacheInfo(identity, param, command.AddToCache); + bool wasClosed = cnn.State == ConnectionState.Closed; + try + { + if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); + using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) + using (var reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult, command.CancellationToken).ConfigureAwait(false)) + { + if (!command.Buffered) wasClosed = false; // handing back open reader; rely on command-behavior + var results = MultiMapImpl(null, CommandDefinition.ForCallback(command.Parameters), map, splitOn, reader, identity, true); + return command.Buffered ? results.ToList() : results; + } + } + finally + { + if (wasClosed) cnn.Close(); + } + } + + /// + /// Perform a asynchronous multi-mapping query with an arbitrary number of input types. + /// This returns a single type, combined from the raw types via . + /// + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// Array of types in the recordset. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Type[] types, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) + { + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)); + return MultiMapAsync(cnn, command, types, map, splitOn); + } + + private static async Task> MultiMapAsync(this IDbConnection cnn, CommandDefinition command, Type[] types, Func map, string splitOn) + { + if (types.Length < 1) + { + throw new ArgumentException("you must provide at least one type to deserialize"); + } + + object param = command.Parameters; + var identity = new IdentityWithTypes(command.CommandText, command.CommandType, cnn, types[0], param?.GetType(), types); + var info = GetCacheInfo(identity, param, command.AddToCache); + bool wasClosed = cnn.State == ConnectionState.Closed; + try + { + if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); + using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) + using (var reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult, command.CancellationToken).ConfigureAwait(false)) + { + var results = MultiMapImpl(null, default(CommandDefinition), types, map, splitOn, reader, identity, true); + return command.Buffered ? results.ToList() : results; + } + } + finally + { + if (wasClosed) cnn.Close(); + } + } + + private static IEnumerable ExecuteReaderSync(IDataReader reader, Func func, object parameters) + { + using (reader) + { + while (reader.Read()) + { + yield return (T)func(reader); + } + while (reader.NextResult()) { /* ignore subsequent result sets */ } + (parameters as IParameterCallbacks)?.OnCompleted(); + } + } + + /// + /// Execute a command that returns multiple result sets, and access each in turn. + /// + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + public static Task QueryMultipleAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryMultipleAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered)); + + /// + /// Execute a command that returns multiple result sets, and access each in turn. + /// + /// The connection to query on. + /// The command to execute for this query. + public static async Task QueryMultipleAsync(this IDbConnection cnn, CommandDefinition command) + { + object param = command.Parameters; + var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param?.GetType()); + CacheInfo info = GetCacheInfo(identity, param, command.AddToCache); + + DbCommand cmd = null; + IDataReader reader = null; + bool wasClosed = cnn.State == ConnectionState.Closed; + try + { + if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); + cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader); + reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false); + + var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache, command.CancellationToken); + wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader + // with the CloseConnection flag, so the reader will deal with the connection; we + // still need something in the "finally" to ensure that broken SQL still results + // in the connection closing itself + return result; + } + catch + { + if (reader != null) + { + if (!reader.IsClosed) + { + try { cmd.Cancel(); } + catch + { /* don't spoil the existing exception */ + } + } + reader.Dispose(); + } + cmd?.Dispose(); + if (wasClosed) cnn.Close(); + throw; + } + } + + /// + /// Execute parameterized SQL and return an . + /// + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An that can be used to iterate over the results of the SQL query. + /// + /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a + /// or . + /// + /// + /// + /// + /// + /// + public static Task ExecuteReaderAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteWrappedReaderImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered), CommandBehavior.Default).CastResult(); + + /// + /// Execute parameterized SQL and return a . + /// + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + public static Task ExecuteReaderAsync(this DbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteWrappedReaderImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered), CommandBehavior.Default); + + /// + /// Execute parameterized SQL and return an . + /// + /// The connection to execute on. + /// The command to execute. + /// An that can be used to iterate over the results of the SQL query. + /// + /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a + /// or . + /// + public static Task ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command) => + ExecuteWrappedReaderImplAsync(cnn, command, CommandBehavior.Default).CastResult(); + + /// + /// Execute parameterized SQL and return a . + /// + /// The connection to execute on. + /// The command to execute. + public static Task ExecuteReaderAsync(this DbConnection cnn, CommandDefinition command) => + ExecuteWrappedReaderImplAsync(cnn, command, CommandBehavior.Default); + + /// + /// Execute parameterized SQL and return an . + /// + /// The connection to execute on. + /// The command to execute. + /// The flags for this reader. + /// An that can be used to iterate over the results of the SQL query. + /// + /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a + /// or . + /// + public static Task ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) => + ExecuteWrappedReaderImplAsync(cnn, command, commandBehavior).CastResult(); + + /// + /// Execute parameterized SQL and return a . + /// + /// The connection to execute on. + /// The command to execute. + /// The flags for this reader. + public static Task ExecuteReaderAsync(this DbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) => + ExecuteWrappedReaderImplAsync(cnn, command, commandBehavior); + + private static async Task ExecuteWrappedReaderImplAsync(IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) + { + Action paramReader = GetParameterReader(cnn, ref command); + + DbCommand cmd = null; + bool wasClosed = cnn.State == ConnectionState.Closed, disposeCommand = true; + try + { + cmd = command.TrySetupAsyncCommand(cnn, paramReader); + if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); + var reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, commandBehavior, command.CancellationToken).ConfigureAwait(false); + wasClosed = false; + disposeCommand = false; + return WrappedReader.Create(cmd, reader); + } + finally + { + if (wasClosed) cnn.Close(); + if (cmd != null && disposeCommand) cmd.Dispose(); + } + } + + /// + /// Execute parameterized SQL that selects a single value. + /// + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell returned, as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteScalarImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered)); + + /// + /// Execute parameterized SQL that selects a single value. + /// + /// The type to return. + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell returned, as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteScalarImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered)); + + /// + /// Execute parameterized SQL that selects a single value. + /// + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, CommandDefinition command) => + ExecuteScalarImplAsync(cnn, command); + + /// + /// Execute parameterized SQL that selects a single value. + /// + /// The type to return. + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, CommandDefinition command) => + ExecuteScalarImplAsync(cnn, command); + + private static async Task ExecuteScalarImplAsync(IDbConnection cnn, CommandDefinition command) + { + Action paramReader = null; + object param = command.Parameters; + if (param != null) + { + var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType()); + paramReader = GetCacheInfo(identity, command.Parameters, command.AddToCache).ParamReader; + } + + DbCommand cmd = null; + bool wasClosed = cnn.State == ConnectionState.Closed; + object result; + try + { + cmd = command.TrySetupAsyncCommand(cnn, paramReader); + if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); + result = await cmd.ExecuteScalarAsync(command.CancellationToken).ConfigureAwait(false); + command.OnCompleted(); + } + finally + { + if (wasClosed) cnn.Close(); + cmd?.Dispose(); + } + return Parse(result); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.CacheInfo.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.CacheInfo.cs new file mode 100644 index 000000000..31491013e --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.CacheInfo.cs @@ -0,0 +1,19 @@ +using System; +using System.Data; +using System.Threading; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + private class CacheInfo + { + public DeserializerState Deserializer { get; set; } + public Func[] OtherDeserializers { get; set; } + public Action ParamReader { get; set; } + private int hitCount; + public int GetHitCount() { return Interlocked.CompareExchange(ref hitCount, 0, 0); } + public void RecordHit() { Interlocked.Increment(ref hitCount); } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRow.Descriptor.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRow.Descriptor.cs new file mode 100644 index 000000000..bf2a183d0 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRow.Descriptor.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + [TypeDescriptionProvider(typeof(DapperRowTypeDescriptionProvider))] + private sealed partial class DapperRow + { + private sealed class DapperRowTypeDescriptionProvider : TypeDescriptionProvider + { + public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance) + => new DapperRowTypeDescriptor(instance); + public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) + => new DapperRowTypeDescriptor(instance); + } + + //// in theory we could implement this for zero-length results to bind; would require + //// additional changes, though, to capture a table even when no rows - so not currently provided + //internal sealed class DapperRowList : List, ITypedList + //{ + // private readonly DapperTable _table; + // public DapperRowList(DapperTable table) { _table = table; } + // PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) + // { + // if (listAccessors != null && listAccessors.Length != 0) return PropertyDescriptorCollection.Empty; + + // return DapperRowTypeDescriptor.GetProperties(_table); + // } + + // string ITypedList.GetListName(PropertyDescriptor[] listAccessors) => null; + //} + + private sealed class DapperRowTypeDescriptor : ICustomTypeDescriptor + { + private readonly DapperRow _row; + public DapperRowTypeDescriptor(object instance) + => _row = (DapperRow)instance; + + AttributeCollection ICustomTypeDescriptor.GetAttributes() + => AttributeCollection.Empty; + + string ICustomTypeDescriptor.GetClassName() => typeof(DapperRow).FullName; + + string ICustomTypeDescriptor.GetComponentName() => null; + + private static readonly TypeConverter s_converter = new ExpandableObjectConverter(); + TypeConverter ICustomTypeDescriptor.GetConverter() => s_converter; + + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() => null; + + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() => null; + + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) => null; + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => EventDescriptorCollection.Empty; + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) => EventDescriptorCollection.Empty; + + internal static PropertyDescriptorCollection GetProperties(DapperRow row) => GetProperties(row?.table, row); + internal static PropertyDescriptorCollection GetProperties(DapperTable table, IDictionary row = null) + { + string[] names = table?.FieldNames; + if (names == null || names.Length == 0) return PropertyDescriptorCollection.Empty; + var arr = new PropertyDescriptor[names.Length]; + for (int i = 0; i < arr.Length; i++) + { + var type = row != null && row.TryGetValue(names[i], out var value) && value != null + ? value.GetType() : typeof(object); + arr[i] = new RowBoundPropertyDescriptor(type, names[i], i); + } + return new PropertyDescriptorCollection(arr, true); + } + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() => GetProperties(_row); + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) => GetProperties(_row); + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) => _row; + } + + private sealed class RowBoundPropertyDescriptor : PropertyDescriptor + { + private readonly Type _type; + private readonly int _index; + public RowBoundPropertyDescriptor(Type type, string name, int index) : base(name, null) + { + _type = type; + _index = index; + } + public override bool CanResetValue(object component) => true; + public override void ResetValue(object component) => ((DapperRow)component).Remove(_index); + public override bool IsReadOnly => false; + public override bool ShouldSerializeValue(object component) => ((DapperRow)component).TryGetValue(_index, out _); + public override Type ComponentType => typeof(DapperRow); + public override Type PropertyType => _type; + public override object GetValue(object component) + => ((DapperRow)component).TryGetValue(_index, out var val) ? (val ?? DBNull.Value): DBNull.Value; + public override void SetValue(object component, object value) + => ((DapperRow)component).SetValue(_index, value is DBNull ? null : value); + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRow.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRow.cs new file mode 100644 index 000000000..01f9feafa --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRow.cs @@ -0,0 +1,250 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + private sealed partial class DapperRow + : IDictionary + , IReadOnlyDictionary + { + private readonly DapperTable table; + private object[] values; + + public DapperRow(DapperTable table, object[] values) + { + this.table = table ?? throw new ArgumentNullException(nameof(table)); + this.values = values ?? throw new ArgumentNullException(nameof(values)); + } + + private sealed class DeadValue + { + public static readonly DeadValue Default = new DeadValue(); + private DeadValue() { /* hiding constructor */ } + } + + int ICollection>.Count + { + get + { + int count = 0; + for (int i = 0; i < values.Length; i++) + { + if (!(values[i] is DeadValue)) count++; + } + return count; + } + } + + public bool TryGetValue(string key, out object value) + => TryGetValue(table.IndexOfName(key), out value); + + internal bool TryGetValue(int index, out object value) + { + if (index < 0) + { // doesn't exist + value = null; + return false; + } + // exists, **even if** we don't have a value; consider table rows heterogeneous + value = index < values.Length ? values[index] : null; + if (value is DeadValue) + { // pretend it isn't here + value = null; + return false; + } + return true; + } + + public override string ToString() + { + var sb = GetStringBuilder().Append("{DapperRow"); + foreach (var kv in this) + { + var value = kv.Value; + sb.Append(", ").Append(kv.Key); + if (value != null) + { + sb.Append(" = '").Append(kv.Value).Append('\''); + } + else + { + sb.Append(" = NULL"); + } + } + + return sb.Append('}').__ToStringRecycle(); + } + + public IEnumerator> GetEnumerator() + { + var names = table.FieldNames; + for (var i = 0; i < names.Length; i++) + { + object value = i < values.Length ? values[i] : null; + if (!(value is DeadValue)) + { + yield return new KeyValuePair(names[i], value); + } + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #region Implementation of ICollection> + + void ICollection>.Add(KeyValuePair item) + { + IDictionary dic = this; + dic.Add(item.Key, item.Value); + } + + void ICollection>.Clear() + { // removes values for **this row**, but doesn't change the fundamental table + for (int i = 0; i < values.Length; i++) + values[i] = DeadValue.Default; + } + + bool ICollection>.Contains(KeyValuePair item) + { + return TryGetValue(item.Key, out object value) && Equals(value, item.Value); + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + foreach (var kv in this) + { + array[arrayIndex++] = kv; // if they didn't leave enough space; not our fault + } + } + + bool ICollection>.Remove(KeyValuePair item) + { + IDictionary dic = this; + return dic.Remove(item.Key); + } + + bool ICollection>.IsReadOnly => false; + #endregion + + #region Implementation of IDictionary + + bool IDictionary.ContainsKey(string key) + { + int index = table.IndexOfName(key); + if (index < 0 || index >= values.Length || values[index] is DeadValue) return false; + return true; + } + + void IDictionary.Add(string key, object value) + { + SetValue(key, value, true); + } + + bool IDictionary.Remove(string key) + => Remove(table.IndexOfName(key)); + + internal bool Remove(int index) + { + if (index < 0 || index >= values.Length || values[index] is DeadValue) return false; + values[index] = DeadValue.Default; + return true; + } + + object IDictionary.this[string key] + { + get { TryGetValue(key, out object val); return val; } + set { SetValue(key, value, false); } + } + + public object SetValue(string key, object value) + { + return SetValue(key, value, false); + } + + private object SetValue(string key, object value, bool isAdd) + { + if (key == null) throw new ArgumentNullException(nameof(key)); + int index = table.IndexOfName(key); + if (index < 0) + { + index = table.AddField(key); + } + else if (isAdd && index < values.Length && !(values[index] is DeadValue)) + { + // then semantically, this value already exists + throw new ArgumentException("An item with the same key has already been added", nameof(key)); + } + return SetValue(index, value); + } + internal object SetValue(int index, object value) + { + int oldLength = values.Length; + if (oldLength <= index) + { + // we'll assume they're doing lots of things, and + // grow it to the full width of the table + Array.Resize(ref values, table.FieldCount); + for (int i = oldLength; i < values.Length; i++) + { + values[i] = DeadValue.Default; + } + } + return values[index] = value; + } + + ICollection IDictionary.Keys + { + get { return this.Select(kv => kv.Key).ToArray(); } + } + + ICollection IDictionary.Values + { + get { return this.Select(kv => kv.Value).ToArray(); } + } + + #endregion + + + #region Implementation of IReadOnlyDictionary + + + int IReadOnlyCollection>.Count + { + get + { + return values.Count(t => !(t is DeadValue)); + } + } + + bool IReadOnlyDictionary.ContainsKey(string key) + { + int index = table.IndexOfName(key); + return index >= 0 && index < values.Length && !(values[index] is DeadValue); + } + + object IReadOnlyDictionary.this[string key] + { + get { TryGetValue(key, out object val); return val; } + } + + IEnumerable IReadOnlyDictionary.Keys + { + get { return this.Select(kv => kv.Key); } + } + + IEnumerable IReadOnlyDictionary.Values + { + get { return this.Select(kv => kv.Value); } + } + + #endregion + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRowMetaObject.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRowMetaObject.cs new file mode 100644 index 000000000..f36a4c2e0 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperRowMetaObject.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + private sealed partial class DapperRow : System.Dynamic.IDynamicMetaObjectProvider + { + System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject( + System.Linq.Expressions.Expression parameter) + { + return new DapperRowMetaObject(parameter, System.Dynamic.BindingRestrictions.Empty, this); + } + } + + private sealed class DapperRowMetaObject : System.Dynamic.DynamicMetaObject + { + private static readonly MethodInfo getValueMethod = typeof(IDictionary).GetProperty("Item").GetGetMethod(); + private static readonly MethodInfo setValueMethod = typeof(DapperRow).GetMethod("SetValue", new Type[] { typeof(string), typeof(object) }); + + public DapperRowMetaObject( + System.Linq.Expressions.Expression expression, + System.Dynamic.BindingRestrictions restrictions + ) + : base(expression, restrictions) + { + } + + public DapperRowMetaObject( + System.Linq.Expressions.Expression expression, + System.Dynamic.BindingRestrictions restrictions, + object value + ) + : base(expression, restrictions, value) + { + } + + private System.Dynamic.DynamicMetaObject CallMethod( + MethodInfo method, + System.Linq.Expressions.Expression[] parameters + ) + { + var callMethod = new System.Dynamic.DynamicMetaObject( + System.Linq.Expressions.Expression.Call( + System.Linq.Expressions.Expression.Convert(Expression, LimitType), + method, + parameters), + System.Dynamic.BindingRestrictions.GetTypeRestriction(Expression, LimitType) + ); + return callMethod; + } + + public override System.Dynamic.DynamicMetaObject BindGetMember(System.Dynamic.GetMemberBinder binder) + { + var parameters = new System.Linq.Expressions.Expression[] + { + System.Linq.Expressions.Expression.Constant(binder.Name) + }; + + var callMethod = CallMethod(getValueMethod, parameters); + + return callMethod; + } + + // Needed for Visual basic dynamic support + public override System.Dynamic.DynamicMetaObject BindInvokeMember(System.Dynamic.InvokeMemberBinder binder, System.Dynamic.DynamicMetaObject[] args) + { + var parameters = new System.Linq.Expressions.Expression[] + { + System.Linq.Expressions.Expression.Constant(binder.Name) + }; + + var callMethod = CallMethod(getValueMethod, parameters); + + return callMethod; + } + + public override System.Dynamic.DynamicMetaObject BindSetMember(System.Dynamic.SetMemberBinder binder, System.Dynamic.DynamicMetaObject value) + { + var parameters = new System.Linq.Expressions.Expression[] + { + System.Linq.Expressions.Expression.Constant(binder.Name), + value.Expression, + }; + + var callMethod = CallMethod(setValueMethod, parameters); + + return callMethod; + } + + static readonly string[] s_nixKeys = new string[0]; + public override IEnumerable GetDynamicMemberNames() + { + if(HasValue && Value is IDictionary lookup) return lookup.Keys; + return s_nixKeys; + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperTable.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperTable.cs new file mode 100644 index 000000000..6e124bd48 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DapperTable.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + private sealed class DapperTable + { + private string[] fieldNames; + private readonly Dictionary fieldNameLookup; + + internal string[] FieldNames => fieldNames; + + public DapperTable(string[] fieldNames) + { + this.fieldNames = fieldNames ?? throw new ArgumentNullException(nameof(fieldNames)); + + fieldNameLookup = new Dictionary(fieldNames.Length, StringComparer.Ordinal); + // if there are dups, we want the **first** key to be the "winner" - so iterate backwards + for (int i = fieldNames.Length - 1; i >= 0; i--) + { + string key = fieldNames[i]; + if (key != null) fieldNameLookup[key] = i; + } + } + + internal int IndexOfName(string name) + { + return (name != null && fieldNameLookup.TryGetValue(name, out int result)) ? result : -1; + } + + internal int AddField(string name) + { + if (name == null) throw new ArgumentNullException(nameof(name)); + if (fieldNameLookup.ContainsKey(name)) throw new InvalidOperationException("Field already exists: " + name); + int oldLen = fieldNames.Length; + Array.Resize(ref fieldNames, oldLen + 1); // yes, this is sub-optimal, but this is not the expected common case + fieldNames[oldLen] = name; + fieldNameLookup[name] = oldLen; + return oldLen; + } + + internal bool FieldExists(string key) => key != null && fieldNameLookup.ContainsKey(key); + + public int FieldCount => fieldNames.Length; + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.DeserializerState.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DeserializerState.cs new file mode 100644 index 000000000..148d74382 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DeserializerState.cs @@ -0,0 +1,20 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + private struct DeserializerState + { + public readonly int Hash; + public readonly Func Func; + + public DeserializerState(int hash, Func func) + { + Hash = hash; + Func = func; + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.DontMap.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DontMap.cs new file mode 100644 index 000000000..0b5d2ba08 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.DontMap.cs @@ -0,0 +1,10 @@ +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Dummy type for excluding from multi-map + /// + private class DontMap { /* hiding constructor */ } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.GridReader.Async.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.GridReader.Async.cs new file mode 100644 index 000000000..7dfd25c89 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.GridReader.Async.cs @@ -0,0 +1,247 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + public partial class GridReader + { + private readonly CancellationToken cancel; + internal GridReader(IDbCommand command, IDataReader reader, Identity identity, DynamicParameters dynamicParams, bool addToCache, CancellationToken cancel) + : this(command, reader, identity, dynamicParams, addToCache) + { + this.cancel = cancel; + } + + /// + /// Read the next grid of results, returned as a dynamic object + /// + /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + /// Whether to buffer the results. + public Task> ReadAsync(bool buffered = true) => ReadAsyncImpl(typeof(DapperRow), buffered); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public Task ReadFirstAsync() => ReadRowAsyncImpl(typeof(DapperRow), Row.First); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public Task ReadFirstOrDefaultAsync() => ReadRowAsyncImpl(typeof(DapperRow), Row.FirstOrDefault); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public Task ReadSingleAsync() => ReadRowAsyncImpl(typeof(DapperRow), Row.Single); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public Task ReadSingleOrDefaultAsync() => ReadRowAsyncImpl(typeof(DapperRow), Row.SingleOrDefault); + + /// + /// Read the next grid of results + /// + /// The type to read. + /// Whether to buffer the results. + /// is null. + public Task> ReadAsync(Type type, bool buffered = true) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadAsyncImpl(type, buffered); + } + + /// + /// Read an individual row of the next grid of results + /// + /// The type to read. + /// is null. + public Task ReadFirstAsync(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRowAsyncImpl(type, Row.First); + } + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + /// is null. + public Task ReadFirstOrDefaultAsync(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRowAsyncImpl(type, Row.FirstOrDefault); + } + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + /// is null. + public Task ReadSingleAsync(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRowAsyncImpl(type, Row.Single); + } + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + /// is null. + public Task ReadSingleOrDefaultAsync(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRowAsyncImpl(type, Row.SingleOrDefault); + } + + /// + /// Read the next grid of results. + /// + /// The type to read. + /// Whether the results should be buffered in memory. + public Task> ReadAsync(bool buffered = true) => ReadAsyncImpl(typeof(T), buffered); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public Task ReadFirstAsync() => ReadRowAsyncImpl(typeof(T), Row.First); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public Task ReadFirstOrDefaultAsync() => ReadRowAsyncImpl(typeof(T), Row.FirstOrDefault); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public Task ReadSingleAsync() => ReadRowAsyncImpl(typeof(T), Row.Single); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public Task ReadSingleOrDefaultAsync() => ReadRowAsyncImpl(typeof(T), Row.SingleOrDefault); + + private async Task NextResultAsync() + { + if (await ((DbDataReader)reader).NextResultAsync(cancel).ConfigureAwait(false)) + { + readCount++; + gridIndex++; + IsConsumed = false; + } + else + { + // happy path; close the reader cleanly - no + // need for "Cancel" etc + reader.Dispose(); + reader = null; + callbacks?.OnCompleted(); + Dispose(); + } + } + + private Task> ReadAsyncImpl(Type type, bool buffered) + { + if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); + if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); + var typedIdentity = identity.ForGrid(type, gridIndex); + CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache); + var deserializer = cache.Deserializer; + + int hash = GetColumnHash(reader); + if (deserializer.Func == null || deserializer.Hash != hash) + { + deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); + cache.Deserializer = deserializer; + } + IsConsumed = true; + if (buffered && reader is DbDataReader) + { + return ReadBufferedAsync(gridIndex, deserializer.Func); + } + else + { + var result = ReadDeferred(gridIndex, deserializer.Func, type); + if (buffered) result = result.ToList(); // for the "not a DbDataReader" scenario + return Task.FromResult(result); + } + } + + private Task ReadRowAsyncImpl(Type type, Row row) + { + if (reader is DbDataReader dbReader) return ReadRowAsyncImplViaDbReader(dbReader, type, row); + + // no async API available; use non-async and fake it + return Task.FromResult(ReadRow(type, row)); + } + + private async Task ReadRowAsyncImplViaDbReader(DbDataReader reader, Type type, Row row) + { + if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); + if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); + + IsConsumed = true; + T result = default(T); + if (await reader.ReadAsync(cancel).ConfigureAwait(false) && reader.FieldCount != 0) + { + var typedIdentity = identity.ForGrid(type, gridIndex); + CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache); + var deserializer = cache.Deserializer; + + int hash = GetColumnHash(reader); + if (deserializer.Func == null || deserializer.Hash != hash) + { + deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); + cache.Deserializer = deserializer; + } + result = (T)deserializer.Func(reader); + if ((row & Row.Single) != 0 && await reader.ReadAsync(cancel).ConfigureAwait(false)) ThrowMultipleRows(row); + while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { /* ignore subsequent rows */ } + } + else if ((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one + { + ThrowZeroRows(row); + } + await NextResultAsync().ConfigureAwait(false); + return result; + } + + private async Task> ReadBufferedAsync(int index, Func deserializer) + { + try + { + var reader = (DbDataReader)this.reader; + var buffer = new List(); + while (index == gridIndex && await reader.ReadAsync(cancel).ConfigureAwait(false)) + { + buffer.Add((T)deserializer(reader)); + } + return buffer; + } + finally // finally so that First etc progresses things even when multiple rows + { + if (index == gridIndex) + { + await NextResultAsync().ConfigureAwait(false); + } + } + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.GridReader.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.GridReader.cs new file mode 100644 index 000000000..cfc057d92 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.GridReader.cs @@ -0,0 +1,437 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Globalization; +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// The grid reader provides interfaces for reading multiple result sets from a Dapper query + /// + public partial class GridReader : IDisposable + { + private IDataReader reader; + private readonly Identity identity; + private readonly bool addToCache; + + internal GridReader(IDbCommand command, IDataReader reader, Identity identity, IParameterCallbacks callbacks, bool addToCache) + { + Command = command; + this.reader = reader; + this.identity = identity; + this.callbacks = callbacks; + this.addToCache = addToCache; + } + + /// + /// Read the next grid of results, returned as a dynamic object. + /// + /// Whether the results should be buffered in memory. + /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public IEnumerable Read(bool buffered = true) => ReadImpl(typeof(DapperRow), buffered); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object. + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public dynamic ReadFirst() => ReadRow(typeof(DapperRow), Row.First); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object. + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public dynamic ReadFirstOrDefault() => ReadRow(typeof(DapperRow), Row.FirstOrDefault); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object. + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public dynamic ReadSingle() => ReadRow(typeof(DapperRow), Row.Single); + + /// + /// Read an individual row of the next grid of results, returned as a dynamic object. + /// + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public dynamic ReadSingleOrDefault() => ReadRow(typeof(DapperRow), Row.SingleOrDefault); + + /// + /// Read the next grid of results. + /// + /// The type to read. + /// Whether the results should be buffered in memory. + public IEnumerable Read(bool buffered = true) => ReadImpl(typeof(T), buffered); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public T ReadFirst() => ReadRow(typeof(T), Row.First); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public T ReadFirstOrDefault() => ReadRow(typeof(T), Row.FirstOrDefault); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public T ReadSingle() => ReadRow(typeof(T), Row.Single); + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + public T ReadSingleOrDefault() => ReadRow(typeof(T), Row.SingleOrDefault); + + /// + /// Read the next grid of results. + /// + /// The type to read. + /// Whether to buffer the results. + /// is null. + public IEnumerable Read(Type type, bool buffered = true) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadImpl(type, buffered); + } + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + /// is null. + public object ReadFirst(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRow(type, Row.First); + } + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + /// is null. + public object ReadFirstOrDefault(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRow(type, Row.FirstOrDefault); + } + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + /// is null. + public object ReadSingle(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRow(type, Row.Single); + } + + /// + /// Read an individual row of the next grid of results. + /// + /// The type to read. + /// is null. + public object ReadSingleOrDefault(Type type) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + return ReadRow(type, Row.SingleOrDefault); + } + + private IEnumerable ReadImpl(Type type, bool buffered) + { + if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); + if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); + var typedIdentity = identity.ForGrid(type, gridIndex); + CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache); + var deserializer = cache.Deserializer; + + int hash = GetColumnHash(reader); + if (deserializer.Func == null || deserializer.Hash != hash) + { + deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); + cache.Deserializer = deserializer; + } + IsConsumed = true; + var result = ReadDeferred(gridIndex, deserializer.Func, type); + return buffered ? result.ToList() : result; + } + + private T ReadRow(Type type, Row row) + { + if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); + if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); + IsConsumed = true; + + T result = default(T); + if (reader.Read() && reader.FieldCount != 0) + { + var typedIdentity = identity.ForGrid(type, gridIndex); + CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache); + var deserializer = cache.Deserializer; + + int hash = GetColumnHash(reader); + if (deserializer.Func == null || deserializer.Hash != hash) + { + deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); + cache.Deserializer = deserializer; + } + object val = deserializer.Func(reader); + if (val == null || val is T) + { + result = (T)val; + } + else + { + var convertToType = Nullable.GetUnderlyingType(type) ?? type; + result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); + } + if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row); + while (reader.Read()) { /* ignore subsequent rows */ } + } + else if ((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one + { + ThrowZeroRows(row); + } + NextResult(); + return result; + } + + private IEnumerable MultiReadInternal(Delegate func, string splitOn) + { + var identity = this.identity.ForGrid(typeof(TReturn), gridIndex); + + IsConsumed = true; + + try + { + foreach (var r in MultiMapImpl(null, default(CommandDefinition), func, splitOn, reader, identity, false)) + { + yield return r; + } + } + finally + { + NextResult(); + } + } + + private IEnumerable MultiReadInternal(Type[] types, Func map, string splitOn) + { + var identity = this.identity.ForGrid(typeof(TReturn), types, gridIndex); + try + { + foreach (var r in MultiMapImpl(null, default(CommandDefinition), types, map, splitOn, reader, identity, false)) + { + yield return r; + } + } + finally + { + NextResult(); + } + } + + /// + /// Read multiple objects from a single record set on the grid. + /// + /// The first type in the record set. + /// The second type in the record set. + /// The type to return from the record set. + /// The mapping function from the read types to the return type. + /// The field(s) we should split and read the second object from (defaults to "id") + /// Whether to buffer results in memory. + public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) + { + var result = MultiReadInternal(func, splitOn); + return buffered ? result.ToList() : result; + } + + /// + /// Read multiple objects from a single record set on the grid. + /// + /// The first type in the record set. + /// The second type in the record set. + /// The third type in the record set. + /// The type to return from the record set. + /// The mapping function from the read types to the return type. + /// The field(s) we should split and read the second object from (defaults to "id") + /// Whether to buffer results in memory. + public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) + { + var result = MultiReadInternal(func, splitOn); + return buffered ? result.ToList() : result; + } + + /// + /// Read multiple objects from a single record set on the grid + /// + /// The first type in the record set. + /// The second type in the record set. + /// The third type in the record set. + /// The fourth type in the record set. + /// The type to return from the record set. + /// The mapping function from the read types to the return type. + /// The field(s) we should split and read the second object from (defaults to "id") + /// Whether to buffer results in memory. + public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) + { + var result = MultiReadInternal(func, splitOn); + return buffered ? result.ToList() : result; + } + + /// + /// Read multiple objects from a single record set on the grid + /// + /// The first type in the record set. + /// The second type in the record set. + /// The third type in the record set. + /// The fourth type in the record set. + /// The fifth type in the record set. + /// The type to return from the record set. + /// The mapping function from the read types to the return type. + /// The field(s) we should split and read the second object from (defaults to "id") + /// Whether to buffer results in memory. + public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) + { + var result = MultiReadInternal(func, splitOn); + return buffered ? result.ToList() : result; + } + + /// + /// Read multiple objects from a single record set on the grid + /// + /// The first type in the record set. + /// The second type in the record set. + /// The third type in the record set. + /// The fourth type in the record set. + /// The fifth type in the record set. + /// The sixth type in the record set. + /// The type to return from the record set. + /// The mapping function from the read types to the return type. + /// The field(s) we should split and read the second object from (defaults to "id") + /// Whether to buffer results in memory. + public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) + { + var result = MultiReadInternal(func, splitOn); + return buffered ? result.ToList() : result; + } + + /// + /// Read multiple objects from a single record set on the grid + /// + /// The first type in the record set. + /// The second type in the record set. + /// The third type in the record set. + /// The fourth type in the record set. + /// The fifth type in the record set. + /// The sixth type in the record set. + /// The seventh type in the record set. + /// The type to return from the record set. + /// The mapping function from the read types to the return type. + /// The field(s) we should split and read the second object from (defaults to "id") + /// Whether to buffer results in memory. + public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) + { + var result = MultiReadInternal(func, splitOn); + return buffered ? result.ToList() : result; + } + + /// + /// Read multiple objects from a single record set on the grid + /// + /// The type to return from the record set. + /// The types to read from the result set. + /// The mapping function from the read types to the return type. + /// The field(s) we should split and read the second object from (defaults to "id") + /// Whether to buffer results in memory. + public IEnumerable Read(Type[] types, Func map, string splitOn = "id", bool buffered = true) + { + var result = MultiReadInternal(types, map, splitOn); + return buffered ? result.ToList() : result; + } + + private IEnumerable ReadDeferred(int index, Func deserializer, Type effectiveType) + { + try + { + var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; + while (index == gridIndex && reader.Read()) + { + object val = deserializer(reader); + if (val == null || val is T) + { + yield return (T)val; + } + else + { + yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); + } + } + } + finally // finally so that First etc progresses things even when multiple rows + { + if (index == gridIndex) + { + NextResult(); + } + } + } + + private int gridIndex, readCount; + private readonly IParameterCallbacks callbacks; + + /// + /// Has the underlying reader been consumed? + /// + public bool IsConsumed { get; private set; } + + /// + /// The command associated with the reader + /// + public IDbCommand Command { get; set; } + + private void NextResult() + { + if (reader.NextResult()) + { + readCount++; + gridIndex++; + IsConsumed = false; + } + else + { + // happy path; close the reader cleanly - no + // need for "Cancel" etc + reader.Dispose(); + reader = null; + callbacks?.OnCompleted(); + Dispose(); + } + } + + /// + /// Dispose the grid, closing and disposing both the underlying reader and command. + /// + public void Dispose() + { + if (reader != null) + { + if (!reader.IsClosed) Command?.Cancel(); + reader.Dispose(); + reader = null; + } + if (Command != null) + { + Command.Dispose(); + Command = null; + } + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.ICustomQueryParameter.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.ICustomQueryParameter.cs new file mode 100644 index 000000000..95bfcd20b --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.ICustomQueryParameter.cs @@ -0,0 +1,20 @@ +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Implement this interface to pass an arbitrary db specific parameter to Dapper + /// + public interface ICustomQueryParameter + { + /// + /// Add the parameter needed to the command before it executes + /// + /// The raw command prior to execution + /// Parameter name + void AddParameter(IDbCommand command, string name); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.IDataReader.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IDataReader.cs new file mode 100644 index 000000000..7acfe1a63 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IDataReader.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Parses a data reader to a sequence of data of the supplied type. Used for deserializing a reader without a connection, etc. + /// + /// The type to parse from the . + /// The data reader to parse results from. + public static IEnumerable Parse(this IDataReader reader) + { + if (reader.Read()) + { + var effectiveType = typeof(T); + var deser = GetDeserializer(effectiveType, reader, 0, -1, false); + var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; + do + { + object val = deser(reader); + if (val == null || val is T) + { + yield return (T)val; + } + else + { + yield return (T)Convert.ChangeType(val, convertToType, System.Globalization.CultureInfo.InvariantCulture); + } + } while (reader.Read()); + } + } + + /// + /// Parses a data reader to a sequence of data of the supplied type (as object). Used for deserializing a reader without a connection, etc. + /// + /// The data reader to parse results from. + /// The type to parse from the . + public static IEnumerable Parse(this IDataReader reader, Type type) + { + if (reader.Read()) + { + var deser = GetDeserializer(type, reader, 0, -1, false); + do + { + yield return deser(reader); + } while (reader.Read()); + } + } + + /// + /// Parses a data reader to a sequence of dynamic. Used for deserializing a reader without a connection, etc. + /// + /// The data reader to parse results from. + public static IEnumerable Parse(this IDataReader reader) + { + if (reader.Read()) + { + var deser = GetDapperRowDeserializer(reader, 0, -1, false); + do + { + yield return deser(reader); + } while (reader.Read()); + } + } + + /// + /// Gets the row parser for a specific row on a data reader. This allows for type switching every row based on, for example, a TypeId column. + /// You could return a collection of the base type but have each more specific. + /// + /// The data reader to get the parser for the current row from + /// The type to get the parser for + /// The start column index of the object (default 0) + /// The length of columns to read (default -1 = all fields following startIndex) + /// Return null if we can't find the first column? (default false) + /// A parser for this specific object from this row. + public static Func GetRowParser(this IDataReader reader, Type type, + int startIndex = 0, int length = -1, bool returnNullIfFirstMissing = false) + { + return GetDeserializer(type, reader, startIndex, length, returnNullIfFirstMissing); + } + + /// + /// Gets the row parser for a specific row on a data reader. This allows for type switching every row based on, for example, a TypeId column. + /// You could return a collection of the base type but have each more specific. + /// + /// The type of results to return. + /// The data reader to get the parser for the current row from. + /// The type to get the parser for. + /// The start column index of the object (default: 0). + /// The length of columns to read (default: -1 = all fields following startIndex). + /// Return null if we can't find the first column? (default: false). + /// A parser for this specific object from this row. + /// + /// var result = new List<BaseType>(); + /// using (var reader = connection.ExecuteReader(@" + /// select 'abc' as Name, 1 as Type, 3.0 as Value + /// union all + /// select 'def' as Name, 2 as Type, 4.0 as Value")) + /// { + /// if (reader.Read()) + /// { + /// var toFoo = reader.GetRowParser<BaseType>(typeof(Foo)); + /// var toBar = reader.GetRowParser<BaseType>(typeof(Bar)); + /// var col = reader.GetOrdinal("Type"); + /// do + /// { + /// switch (reader.GetInt32(col)) + /// { + /// case 1: + /// result.Add(toFoo(reader)); + /// break; + /// case 2: + /// result.Add(toBar(reader)); + /// break; + /// } + /// } while (reader.Read()); + /// } + /// } + /// + /// abstract class BaseType + /// { + /// public abstract int Type { get; } + /// } + /// class Foo : BaseType + /// { + /// public string Name { get; set; } + /// public override int Type => 1; + /// } + /// class Bar : BaseType + /// { + /// public float Value { get; set; } + /// public override int Type => 2; + /// } + /// + public static Func GetRowParser(this IDataReader reader, Type concreteType = null, + int startIndex = 0, int length = -1, bool returnNullIfFirstMissing = false) + { + concreteType = concreteType ?? typeof(T); + var func = GetDeserializer(concreteType, reader, startIndex, length, returnNullIfFirstMissing); + if (concreteType.IsValueType) + { + return _ => (T)func(_); + } + else + { + return (Func)(Delegate)func; + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.IDynamicParameters.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IDynamicParameters.cs new file mode 100644 index 000000000..288aa6604 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IDynamicParameters.cs @@ -0,0 +1,20 @@ +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Implement this interface to pass an arbitrary db specific set of parameters to Dapper + /// + public interface IDynamicParameters + { + /// + /// Add all the parameters needed to the command just before it executes + /// + /// The raw command prior to execution + /// Information about the query + void AddParameters(IDbCommand command, Identity identity); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.IMemberMap.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IMemberMap.cs new file mode 100644 index 000000000..ddf68592e --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IMemberMap.cs @@ -0,0 +1,39 @@ +using System; +using System.Reflection; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Implements this interface to provide custom member mapping + /// + public interface IMemberMap + { + /// + /// Source DataReader column name + /// + string ColumnName { get; } + + /// + /// Target member type + /// + Type MemberType { get; } + + /// + /// Target property + /// + PropertyInfo Property { get; } + + /// + /// Target field + /// + FieldInfo Field { get; } + + /// + /// Target constructor parameter + /// + ParameterInfo Parameter { get; } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.IParameterCallbacks.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IParameterCallbacks.cs new file mode 100644 index 000000000..027054efe --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IParameterCallbacks.cs @@ -0,0 +1,16 @@ +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Extends IDynamicParameters with facilities for executing callbacks after commands have completed + /// + public interface IParameterCallbacks : IDynamicParameters + { + /// + /// Invoked when the command has executed + /// + void OnCompleted(); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.IParameterLookup.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IParameterLookup.cs new file mode 100644 index 000000000..ea22ff545 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.IParameterLookup.cs @@ -0,0 +1,17 @@ +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Extends IDynamicParameters providing by-name lookup of parameter values + /// + public interface IParameterLookup : IDynamicParameters + { + /// + /// Get the value of the specified parameter (return null if not found) + /// + /// The name of the parameter to get. + object this[string name] { get; } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.ITypeHandler.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.ITypeHandler.cs new file mode 100644 index 000000000..6d4609bdc --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.ITypeHandler.cs @@ -0,0 +1,29 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Implement this interface to perform custom type-based parameter handling and value parsing + /// + public interface ITypeHandler + { + /// + /// Assign the value of a parameter before a command executes + /// + /// The parameter to configure + /// Parameter value + void SetValue(IDbDataParameter parameter, object value); + + /// + /// Parse a database value back to a typed value + /// + /// The value from the database + /// The type to parse to + /// The typed value + object Parse(Type destinationType, object value); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.ITypeMap.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.ITypeMap.cs new file mode 100644 index 000000000..25d7c7b72 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.ITypeMap.cs @@ -0,0 +1,46 @@ +using System; +using System.Reflection; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Implement this interface to change default mapping of reader columns to type members + /// + public interface ITypeMap + { + /// + /// Finds best constructor + /// + /// DataReader column names + /// DataReader column types + /// Matching constructor or default one + ConstructorInfo FindConstructor(string[] names, Type[] types); + + /// + /// Returns a constructor which should *always* be used. + /// + /// Parameters will be default values, nulls for reference types and zero'd for value types. + /// + /// Use this class to force object creation away from parameterless constructors you don't control. + /// + ConstructorInfo FindExplicitConstructor(); + + /// + /// Gets mapping for constructor parameter + /// + /// Constructor to resolve + /// DataReader column name + /// Mapping implementation + IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName); + + /// + /// Gets member mapping for column + /// + /// DataReader column name + /// Mapping implementation + IMemberMap GetMember(string columnName); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.Identity.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Identity.cs new file mode 100644 index 000000000..7f728ec6e --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Identity.cs @@ -0,0 +1,228 @@ +using System; +using System.Data; +using System.Runtime.CompilerServices; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + internal sealed class Identity : Identity + { + private static readonly int s_typeHash; + private static readonly int s_typeCount = CountNonTrivial(out s_typeHash); + + internal Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, int gridIndex = 0) + : base(sql, commandType, connectionString, type, parametersType, s_typeHash, gridIndex) + {} + internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, int gridIndex = 0) + : base(sql, commandType, connection.ConnectionString, type, parametersType, s_typeHash, gridIndex) + { } + + static int CountNonTrivial(out int hashCode) + { + int hashCodeLocal = 0; + int count = 0; + bool Map() + { + if(typeof(T) != typeof(DontMap)) + { + count++; + hashCodeLocal = (hashCodeLocal * 23) + (typeof(T).GetHashCode()); + return true; + } + return false; + } + _ = Map() && Map() && Map() + && Map() && Map() && Map() + && Map(); + hashCode = hashCodeLocal; + return count; + } + internal override int TypeCount => s_typeCount; + internal override Type GetType(int index) + { + switch (index) + { + case 0: return typeof(TFirst); + case 1: return typeof(TSecond); + case 2: return typeof(TThird); + case 3: return typeof(TFourth); + case 4: return typeof(TFifth); + case 5: return typeof(TSixth); + case 6: return typeof(TSeventh); + default: return base.GetType(index); + } + } + } + internal sealed class IdentityWithTypes : Identity + { + private readonly Type[] _types; + + internal IdentityWithTypes(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex = 0) + : base(sql, commandType, connectionString, type, parametersType, HashTypes(otherTypes), gridIndex) + { + _types = otherTypes ?? Type.EmptyTypes; + } + internal IdentityWithTypes(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, Type[] otherTypes, int gridIndex = 0) + : base(sql, commandType, connection.ConnectionString, type, parametersType, HashTypes(otherTypes), gridIndex) + { + _types = otherTypes ?? Type.EmptyTypes; + } + + internal override int TypeCount => _types.Length; + + internal override Type GetType(int index) => _types[index]; + + static int HashTypes(Type[] types) + { + var hashCode = 0; + if (types != null) + { + foreach (var t in types) + { + hashCode = (hashCode * 23) + (t?.GetHashCode() ?? 0); + } + } + return hashCode; + } + } + + /// + /// Identity of a cached query in Dapper, used for extensibility. + /// + public class Identity : IEquatable + { + internal virtual int TypeCount => 0; + + internal virtual Type GetType(int index) => throw new IndexOutOfRangeException(nameof(index)); + + internal Identity ForGrid(Type primaryType, int gridIndex) => + new Identity(sql, commandType, connectionString, primaryType, parametersType, gridIndex); + + internal Identity ForGrid(Type primaryType, int gridIndex) => + new Identity(sql, commandType, connectionString, primaryType, parametersType, 0, gridIndex); + + internal Identity ForGrid(Type primaryType, Type[] otherTypes, int gridIndex) => + (otherTypes == null || otherTypes.Length == 0) + ? new Identity(sql, commandType, connectionString, primaryType, parametersType, 0, gridIndex) + : new IdentityWithTypes(sql, commandType, connectionString, primaryType, parametersType, otherTypes, gridIndex); + + /// + /// Create an identity for use with DynamicParameters, internal use only. + /// + /// The parameters type to create an for. + /// + public Identity ForDynamicParameters(Type type) => + new Identity(sql, commandType, connectionString, this.type, type, 0, -1); + + internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType) + : this(sql, commandType, connection.ConnectionString, type, parametersType, 0, 0) { /* base call */ } + + private protected Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, int otherTypesHash, int gridIndex) + { + this.sql = sql; + this.commandType = commandType; + this.connectionString = connectionString; + this.type = type; + this.parametersType = parametersType; + this.gridIndex = gridIndex; + unchecked + { + hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this + hashCode = (hashCode * 23) + commandType.GetHashCode(); + hashCode = (hashCode * 23) + gridIndex.GetHashCode(); + hashCode = (hashCode * 23) + (sql?.GetHashCode() ?? 0); + hashCode = (hashCode * 23) + (type?.GetHashCode() ?? 0); + hashCode = (hashCode * 23) + otherTypesHash; + hashCode = (hashCode * 23) + (connectionString == null ? 0 : connectionStringComparer.GetHashCode(connectionString)); + hashCode = (hashCode * 23) + (parametersType?.GetHashCode() ?? 0); + } + } + + /// + /// Whether this equals another. + /// + /// The other to compare to. + public override bool Equals(object obj) => Equals(obj as Identity); + + /// + /// The raw SQL command. + /// + public readonly string sql; + + /// + /// The SQL command type. + /// + public readonly CommandType? commandType; + + /// + /// The hash code of this Identity. + /// + public readonly int hashCode; + + /// + /// The grid index (position in the reader) of this Identity. + /// + public readonly int gridIndex; + + /// + /// This of this Identity. + /// + public readonly Type type; + + /// + /// The connection string for this Identity. + /// + public readonly string connectionString; + + /// + /// The type of the parameters object for this Identity. + /// + public readonly Type parametersType; + + /// + /// Gets the hash code for this identity. + /// + /// + public override int GetHashCode() => hashCode; + + /// + /// See object.ToString() + /// + public override string ToString() => sql; + + /// + /// Compare 2 Identity objects + /// + /// The other object to compare. + /// Whether the two are equal + public bool Equals(Identity other) + { + if (ReferenceEquals(this, other)) return true; + if (ReferenceEquals(other, null)) return false; + + int typeCount; + return gridIndex == other.gridIndex + && type == other.type + && sql == other.sql + && commandType == other.commandType + && connectionStringComparer.Equals(connectionString, other.connectionString) + && parametersType == other.parametersType + && (typeCount = TypeCount) == other.TypeCount + && (typeCount == 0 || TypesEqual(this, other, typeCount)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool TypesEqual(Identity x, Identity y, int count) + { + if (y.TypeCount != count) return false; + for(int i = 0; i < count; i++) + { + if (x.GetType(i) != y.GetType(i)) + return false; + } + return true; + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.Link.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Link.cs new file mode 100644 index 000000000..e49ae7e93 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Link.cs @@ -0,0 +1,61 @@ +using System.Threading; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), + /// and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** + /// equality. The type is fully thread-safe. + /// + /// The type to cache. + /// The value type of the cache. + internal class Link where TKey : class + { + public static bool TryGet(Link link, TKey key, out TValue value) + { + while (link != null) + { + if ((object)key == (object)link.Key) + { + value = link.Value; + return true; + } + link = link.Tail; + } + value = default(TValue); + return false; + } + + public static bool TryAdd(ref Link head, TKey key, ref TValue value) + { + bool tryAgain; + do + { + var snapshot = Interlocked.CompareExchange(ref head, null, null); + if (TryGet(snapshot, key, out TValue found)) + { // existing match; report the existing value instead + value = found; + return false; + } + var newNode = new Link(key, value, snapshot); + // did somebody move our cheese? + tryAgain = Interlocked.CompareExchange(ref head, newNode, snapshot) != snapshot; + } while (tryAgain); + return true; + } + + private Link(TKey key, TValue value, Link tail) + { + Key = key; + Value = value; + Tail = tail; + } + + public TKey Key { get; } + public TValue Value { get; } + public Link Tail { get; } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.LiteralToken.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.LiteralToken.cs new file mode 100644 index 000000000..45a04468a --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.LiteralToken.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Represents a placeholder for a value that should be replaced as a literal value in the resulting sql + /// + internal struct LiteralToken + { + /// + /// The text in the original command that should be replaced + /// + public string Token { get; } + + /// + /// The name of the member referred to by the token + /// + public string Member { get; } + + internal LiteralToken(string token, string member) + { + Token = token; + Member = member; + } + + internal static readonly IList None = new LiteralToken[0]; + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.Settings.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Settings.cs new file mode 100644 index 000000000..f010e84d1 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.Settings.cs @@ -0,0 +1,98 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Permits specifying certain SqlMapper values globally. + /// + public static class Settings + { + // disable single result by default; prevents errors AFTER the select being detected properly + private const CommandBehavior DefaultAllowedCommandBehaviors = ~CommandBehavior.SingleResult; + internal static CommandBehavior AllowedCommandBehaviors { get; private set; } = DefaultAllowedCommandBehaviors; + private static void SetAllowedCommandBehaviors(CommandBehavior behavior, bool enabled) + { + if (enabled) AllowedCommandBehaviors |= behavior; + else AllowedCommandBehaviors &= ~behavior; + } + /// + /// Gets or sets whether Dapper should use the CommandBehavior.SingleResult optimization + /// + /// Note that a consequence of enabling this option is that errors that happen after the first select may not be reported + public static bool UseSingleResultOptimization + { + get { return (AllowedCommandBehaviors & CommandBehavior.SingleResult) != 0; } + set { SetAllowedCommandBehaviors(CommandBehavior.SingleResult, value); } + } + /// + /// Gets or sets whether Dapper should use the CommandBehavior.SingleRow optimization + /// + /// Note that on some DB providers this optimization can have adverse performance impact + public static bool UseSingleRowOptimization + { + get { return (AllowedCommandBehaviors & CommandBehavior.SingleRow) != 0; } + set { SetAllowedCommandBehaviors(CommandBehavior.SingleRow, value); } + } + + internal static bool DisableCommandBehaviorOptimizations(CommandBehavior behavior, Exception ex) + { + if (AllowedCommandBehaviors == DefaultAllowedCommandBehaviors + && (behavior & (CommandBehavior.SingleResult | CommandBehavior.SingleRow)) != 0) + { + if (ex.Message.Contains(nameof(CommandBehavior.SingleResult)) + || ex.Message.Contains(nameof(CommandBehavior.SingleRow))) + { // some providers just just allow these, so: try again without them and stop issuing them + SetAllowedCommandBehaviors(CommandBehavior.SingleResult | CommandBehavior.SingleRow, false); + return true; + } + } + return false; + } + + static Settings() + { + SetDefaults(); + } + + /// + /// Resets all Settings to their default values + /// + public static void SetDefaults() + { + CommandTimeout = null; + ApplyNullValues = false; + } + + /// + /// Specifies the default Command Timeout for all Queries + /// + public static int? CommandTimeout { get; set; } + + /// + /// Indicates whether nulls in data are silently ignored (default) vs actively applied and assigned to members + /// + public static bool ApplyNullValues { get; set; } + + /// + /// Should list expansions be padded with null-valued parameters, to prevent query-plan saturation? For example, + /// an 'in @foo' expansion with 7, 8 or 9 values will be sent as a list of 10 values, with 3, 2 or 1 of them null. + /// The padding size is relative to the size of the list; "next 10" under 150, "next 50" under 500, + /// "next 100" under 1500, etc. + /// + /// + /// Caution: this should be treated with care if your DB provider (or the specific configuration) allows for null + /// equality (aka "ansi nulls off"), as this may change the intent of your query; as such, this is disabled by + /// default and must be enabled. + /// + public static bool PadListExpansions { get; set; } + /// + /// If set (non-negative), when performing in-list expansions of integer types ("where id in @ids", etc), switch to a string_split based + /// operation if there are more than this many elements. Note that this feautre requires SQL Server 2016 / compatibility level 130 (or above). + /// + public static int InListStringSplitCount { get; set; } = -1; + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeDeserializerCache.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeDeserializerCache.cs new file mode 100644 index 000000000..1a5e83bb8 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeDeserializerCache.cs @@ -0,0 +1,163 @@ +using System; +using System.Data; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + private class TypeDeserializerCache + { + private TypeDeserializerCache(Type type) + { + this.type = type; + } + + private static readonly Hashtable byType = new Hashtable(); + private readonly Type type; + internal static void Purge(Type type) + { + lock (byType) + { + byType.Remove(type); + } + } + + internal static void Purge() + { + lock (byType) + { + byType.Clear(); + } + } + + internal static Func GetReader(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing) + { + var found = (TypeDeserializerCache)byType[type]; + if (found == null) + { + lock (byType) + { + found = (TypeDeserializerCache)byType[type]; + if (found == null) + { + byType[type] = found = new TypeDeserializerCache(type); + } + } + } + return found.GetReader(reader, startBound, length, returnNullIfFirstMissing); + } + + private readonly Dictionary> readers = new Dictionary>(); + + private struct DeserializerKey : IEquatable + { + private readonly int startBound, length; + private readonly bool returnNullIfFirstMissing; + private readonly IDataReader reader; + private readonly string[] names; + private readonly Type[] types; + private readonly int hashCode; + + public DeserializerKey(int hashCode, int startBound, int length, bool returnNullIfFirstMissing, IDataReader reader, bool copyDown) + { + this.hashCode = hashCode; + this.startBound = startBound; + this.length = length; + this.returnNullIfFirstMissing = returnNullIfFirstMissing; + + if (copyDown) + { + this.reader = null; + names = new string[length]; + types = new Type[length]; + int index = startBound; + for (int i = 0; i < length; i++) + { + names[i] = reader.GetName(index); + types[i] = reader.GetFieldType(index++); + } + } + else + { + this.reader = reader; + names = null; + types = null; + } + } + + public override int GetHashCode() => hashCode; + + public override string ToString() + { // only used in the debugger + if (names != null) + { + return string.Join(", ", names); + } + if (reader != null) + { + var sb = new StringBuilder(); + int index = startBound; + for (int i = 0; i < length; i++) + { + if (i != 0) sb.Append(", "); + sb.Append(reader.GetName(index++)); + } + return sb.ToString(); + } + return base.ToString(); + } + + public override bool Equals(object obj) + { + return obj is DeserializerKey && Equals((DeserializerKey)obj); + } + + public bool Equals(DeserializerKey other) + { + if (hashCode != other.hashCode + || startBound != other.startBound + || length != other.length + || returnNullIfFirstMissing != other.returnNullIfFirstMissing) + { + return false; // clearly different + } + for (int i = 0; i < length; i++) + { + if ((names?[i] ?? reader?.GetName(startBound + i)) != (other.names?[i] ?? other.reader?.GetName(startBound + i)) + || + (types?[i] ?? reader?.GetFieldType(startBound + i)) != (other.types?[i] ?? other.reader?.GetFieldType(startBound + i)) + ) + { + return false; // different column name or type + } + } + return true; + } + } + + private Func GetReader(IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing) + { + if (length < 0) length = reader.FieldCount - startBound; + int hash = GetColumnHash(reader, startBound, length); + if (returnNullIfFirstMissing) hash *= -27; + // get a cheap key first: false means don't copy the values down + var key = new DeserializerKey(hash, startBound, length, returnNullIfFirstMissing, reader, false); + Func deser; + lock (readers) + { + if (readers.TryGetValue(key, out deser)) return deser; + } + deser = GetTypeDeserializerImpl(type, reader, startBound, length, returnNullIfFirstMissing); + // get a more expensive key: true means copy the values down so it can be used as a key later + key = new DeserializerKey(hash, startBound, length, returnNullIfFirstMissing, reader, true); + lock (readers) + { + return readers[key] = deser; + } + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeHandler.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeHandler.cs new file mode 100644 index 000000000..2b8fb9955 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeHandler.cs @@ -0,0 +1,86 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Base-class for simple type-handlers + /// + /// This this handler is for. + public abstract class TypeHandler : ITypeHandler + { + /// + /// Assign the value of a parameter before a command executes + /// + /// The parameter to configure + /// Parameter value + public abstract void SetValue(IDbDataParameter parameter, T value); + + /// + /// Parse a database value back to a typed value + /// + /// The value from the database + /// The typed value + public abstract T Parse(object value); + + void ITypeHandler.SetValue(IDbDataParameter parameter, object value) + { + if (value is DBNull) + { + parameter.Value = value; + } + else + { + SetValue(parameter, (T)value); + } + } + + object ITypeHandler.Parse(Type destinationType, object value) + { + return Parse(value); + } + } + + /// + /// Base-class for simple type-handlers that are based around strings + /// + /// This this handler is for. + public abstract class StringTypeHandler : TypeHandler + { + /// + /// Parse a string into the expected type (the string will never be null) + /// + /// The string to parse. + protected abstract T Parse(string xml); + + /// + /// Format an instace into a string (the instance will never be null) + /// + /// The string to format. + protected abstract string Format(T xml); + + /// + /// Assign the value of a parameter before a command executes + /// + /// The parameter to configure + /// Parameter value + public override void SetValue(IDbDataParameter parameter, T value) + { + parameter.Value = value == null ? (object)DBNull.Value : Format(value); + } + + /// + /// Parse a database value back to a typed value + /// + /// The value from the database + /// The typed value + public override T Parse(object value) + { + if (value == null || value is DBNull) return default(T); + return Parse((string)value); + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeHandlerCache.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeHandlerCache.cs new file mode 100644 index 000000000..d7eebd764 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.TypeHandlerCache.cs @@ -0,0 +1,43 @@ +using System; +using System.ComponentModel; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// Not intended for direct usage + /// + /// The type to have a cache for. + [Obsolete(ObsoleteInternalUsageOnly, false)] + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public static class TypeHandlerCache + { + /// + /// Not intended for direct usage. + /// + /// The object to parse. + [Obsolete(ObsoleteInternalUsageOnly, true)] + public static T Parse(object value) => (T)handler.Parse(typeof(T), value); + + /// + /// Not intended for direct usage. + /// + /// The parameter to set a value for. + /// The value to set. + [Obsolete(ObsoleteInternalUsageOnly, true)] + public static void SetValue(IDbDataParameter parameter, object value) => handler.SetValue(parameter, value); + + internal static void SetHandler(ITypeHandler handler) + { +#pragma warning disable 618 + TypeHandlerCache.handler = handler; +#pragma warning restore 618 + } + + private static ITypeHandler handler; + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/SqlMapper.cs b/src/ServiceStack.OrmLite/Dapper/SqlMapper.cs index c6e7289b8..d7b7f45d7 100644 --- a/src/ServiceStack.OrmLite/Dapper/SqlMapper.cs +++ b/src/ServiceStack.OrmLite/Dapper/SqlMapper.cs @@ -1,9 +1,6 @@ -/* - License: http://www.apache.org/licenses/LICENSE-2.0 - Home page: http://code.google.com/p/dapper-dot-net/ - - Note: to build on C# 3.0 + .NET 3.5, include the CSHARP30 compiler symbol (and yes, - I know the difference between language and runtime versions; this is a compromise). +/* + License: http://www.apache.org/licenses/LICENSE-2.0 + Home page: https://github.com/StackExchange/dapper-dot-net */ using System; @@ -11,515 +8,41 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Text; -using System.Threading; using System.Text.RegularExpressions; -using System.Diagnostics; -using System.Globalization; -using System.Linq.Expressions; +using System.Threading; +using System.Xml; +using System.Xml.Linq; namespace ServiceStack.OrmLite.Dapper { - [AssemblyNeutral, AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] - internal sealed class AssemblyNeutralAttribute : Attribute { } - - /// - /// Additional state flags that control command behaviour - /// - [Flags] - public enum CommandFlags - { - /// - /// No additonal flags - /// - None = 0, - /// - /// Should data be buffered before returning? - /// - Buffered = 1, - /// - /// Can async queries be pipelined? - /// - Pipelined = 2, - /// - /// Should the plan cache be bypassed? - /// - NoCache = 4, - } - /// - /// Represents the key aspects of a sql operation - /// - public struct CommandDefinition - { - internal static CommandDefinition ForCallback(object parameters) - { - if (parameters is DynamicParameters) - { - return new CommandDefinition(parameters); - } - else - { - return default(CommandDefinition); - } - } - private readonly string commandText; - private readonly object parameters; - private readonly IDbTransaction transaction; - private readonly int? commandTimeout; - private readonly CommandType? commandType; - private readonly CommandFlags flags; - - - internal void OnCompleted() - { - if (parameters is SqlMapper.IParameterCallbacks) - { - ((SqlMapper.IParameterCallbacks)parameters).OnCompleted(); - } - } - /// - /// The command (sql or a stored-procedure name) to execute - /// - public string CommandText { get { return commandText; } } - /// - /// The parameters associated with the command - /// - public object Parameters { get { return parameters; } } - /// - /// The active transaction for the command - /// - public IDbTransaction Transaction { get { return transaction; } } - /// - /// The effective timeout for the command - /// - public int? CommandTimeout { get { return commandTimeout; } } - /// - /// The type of command that the command-text represents - /// - public CommandType? CommandType { get { return commandType; } } - - /// - /// Should data be buffered before returning? - /// - public bool Buffered { get { return (flags & CommandFlags.Buffered) != 0; } } - - /// - /// Should the plan for this query be cached? - /// - internal bool AddToCache { get { return (flags & CommandFlags.NoCache) == 0; } } - - /// - /// Additional state flags against this command - /// - public CommandFlags Flags { get { return flags; } } - - /// - /// Can async queries be pipelined? - /// - public bool Pipelined { get { return (flags & CommandFlags.Pipelined) != 0; } } - - /// - /// Initialize the command definition - /// -#if CSHARP30 - public CommandDefinition(string commandText, object parameters, IDbTransaction transaction, int? commandTimeout, - CommandType? commandType, CommandFlags flags) -#else - public CommandDefinition(string commandText, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null, - CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered -#if ASYNC - , CancellationToken cancellationToken = default(CancellationToken) -#endif -) -#endif - { - this.commandText = commandText; - this.parameters = parameters; - this.transaction = transaction; - this.commandTimeout = commandTimeout; - this.commandType = commandType; - this.flags = flags; -#if ASYNC - this.cancellationToken = cancellationToken; -#endif - } - - private CommandDefinition(object parameters) - : this() - { - this.parameters = parameters; - } - -#if ASYNC - private readonly CancellationToken cancellationToken; - /// - /// For asynchronous operations, the cancellation-token - /// - public CancellationToken CancellationToken { get { return cancellationToken; } } -#endif - - - internal IDbCommand SetupCommand(IDbConnection cnn, Action paramReader) - { - var cmd = cnn.CreateCommand(); - var init = GetInit(cmd.GetType()); - if (init != null) init(cmd); - if (transaction != null) - cmd.Transaction = transaction; - cmd.CommandText = commandText; - if (commandTimeout.HasValue) - cmd.CommandTimeout = commandTimeout.Value; - if (commandType.HasValue) - cmd.CommandType = commandType.Value; - if (paramReader != null) - { - paramReader(cmd, parameters); - } - return cmd; - } - - static SqlMapper.Link> commandInitCache; - static Action GetInit(Type commandType) - { - if (commandType == null) return null; // GIGO - Action action; - if (SqlMapper.Link>.TryGet(commandInitCache, commandType, out action)) - { - return action; - } - var bindByName = GetBasicPropertySetter(commandType, "BindByName", typeof(bool)); - var initialLongFetchSize = GetBasicPropertySetter(commandType, "InitialLONGFetchSize", typeof(int)); - - action = null; - if (bindByName != null || initialLongFetchSize != null) - { - var method = new DynamicMethod(commandType.Name + "_init", null, new Type[] { typeof(IDbCommand) }); - var il = method.GetILGenerator(); - - if (bindByName != null) - { - // .BindByName = true - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Castclass, commandType); - il.Emit(OpCodes.Ldc_I4_1); - il.EmitCall(OpCodes.Callvirt, bindByName, null); - } - if (initialLongFetchSize != null) - { - // .InitialLONGFetchSize = -1 - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Castclass, commandType); - il.Emit(OpCodes.Ldc_I4_M1); - il.EmitCall(OpCodes.Callvirt, initialLongFetchSize, null); - } - il.Emit(OpCodes.Ret); - action = (Action)method.CreateDelegate(typeof(Action)); - } - // cache it - SqlMapper.Link>.TryAdd(ref commandInitCache, commandType, ref action); - return action; - } - static MethodInfo GetBasicPropertySetter(Type declaringType, string name, Type expectedType) - { - var prop = declaringType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance); - ParameterInfo[] indexers; - if (prop != null && prop.CanWrite && prop.PropertyType == expectedType - && ((indexers = prop.GetIndexParameters()) == null || indexers.Length == 0)) - { - return prop.GetSetMethod(); - } - return null; - } - } - /// /// Dapper, a light weight object mapper for ADO.NET /// - static partial class SqlMapper + public static partial class SqlMapper { - /// - /// Implement this interface to pass an arbitrary db specific set of parameters to Dapper - /// - public partial interface IDynamicParameters - { - /// - /// Add all the parameters needed to the command just before it executes - /// - /// The raw command prior to execution - /// Information about the query - void AddParameters(IDbCommand command, Identity identity); - } - - /// - /// Extends IDynamicParameters providing by-name lookup of parameter values - /// - public interface IParameterLookup : IDynamicParameters - { - /// - /// Get the value of the specified parameter (return null if not found) - /// - object this[string name] { get; } - } - - /// - /// Extends IDynamicParameters with facitilies for executing callbacks after commands have completed - /// - public partial interface IParameterCallbacks : IDynamicParameters - { - /// - /// Invoked when the command has executed - /// - void OnCompleted(); - } - - /// - /// Implement this interface to pass an arbitrary db specific parameter to Dapper - /// - [AssemblyNeutral] - public interface ICustomQueryParameter - { - /// - /// Add the parameter needed to the command before it executes - /// - /// The raw command prior to execution - /// Parameter name - void AddParameter(IDbCommand command, string name); - } - - /// - /// Implement this interface to perform custom type-based parameter handling and value parsing - /// - [AssemblyNeutral] - public interface ITypeHandler - { - /// - /// Assign the value of a parameter before a command executes - /// - /// The parameter to configure - /// Parameter value - void SetValue(IDbDataParameter parameter, object value); - - /// - /// Parse a database value back to a typed value - /// - /// The value from the database - /// The type to parse to - /// The typed value - object Parse(Type destinationType, object value); - } - - /// - /// A type handler for data-types that are supported by the underlying provider, but which need - /// a well-known UdtTypeName to be specified - /// - public class UdtTypeHandler : ITypeHandler - { - private readonly string udtTypeName; - /// - /// Creates a new instance of UdtTypeHandler with the specified UdtTypeName - /// - public UdtTypeHandler(string udtTypeName) - { - if (string.IsNullOrEmpty(udtTypeName)) throw new ArgumentException("Cannot be null or empty", udtTypeName); - this.udtTypeName = udtTypeName; - } - object ITypeHandler.Parse(Type destinationType, object value) - { - return value is DBNull ? null : value; - } - - void ITypeHandler.SetValue(IDbDataParameter parameter, object value) - { - parameter.Value = ((object)value) ?? DBNull.Value; - if (parameter is System.Data.SqlClient.SqlParameter) - { - ((System.Data.SqlClient.SqlParameter)parameter).UdtTypeName = udtTypeName; - } - } - } - - /// - /// Base-class for simple type-handlers - /// - public abstract class TypeHandler : ITypeHandler - { - /// - /// Assign the value of a parameter before a command executes - /// - /// The parameter to configure - /// Parameter value - public abstract void SetValue(IDbDataParameter parameter, T value); - - /// - /// Parse a database value back to a typed value - /// - /// The value from the database - /// The typed value - public abstract T Parse(object value); - - void ITypeHandler.SetValue(IDbDataParameter parameter, object value) - { - if (value is DBNull) - { - parameter.Value = value; - } - else - { - SetValue(parameter, (T)value); - } - } - - object ITypeHandler.Parse(Type destinationType, object value) - { - return Parse(value); - } - } - - /// - /// Implement this interface to change default mapping of reader columns to type memebers - /// - public interface ITypeMap - { - /// - /// Finds best constructor - /// - /// DataReader column names - /// DataReader column types - /// Matching constructor or default one - ConstructorInfo FindConstructor(string[] names, Type[] types); - - /// - /// Gets mapping for constructor parameter - /// - /// Constructor to resolve - /// DataReader column name - /// Mapping implementation - IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName); - - /// - /// Gets member mapping for column - /// - /// DataReader column name - /// Mapping implementation - IMemberMap GetMember(string columnName); - } - - /// - /// Implements this interface to provide custom member mapping - /// - public interface IMemberMap - { - /// - /// Source DataReader column name - /// - string ColumnName { get; } - - /// - /// Target member type - /// - Type MemberType { get; } - - /// - /// Target property - /// - PropertyInfo Property { get; } - - /// - /// Target field - /// - FieldInfo Field { get; } - - /// - /// Target constructor parameter - /// - ParameterInfo Parameter { get; } - } - - /// - /// This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - /// and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - /// equality. The type is fully thread-safe. - /// - internal partial class Link where TKey : class - { - public static bool TryGet(Link link, TKey key, out TValue value) - { - while (link != null) - { - if ((object)key == (object)link.Key) - { - value = link.Value; - return true; - } - link = link.Tail; - } - value = default(TValue); - return false; - } - public static bool TryAdd(ref Link head, TKey key, ref TValue value) - { - bool tryAgain; - do - { - var snapshot = Interlocked.CompareExchange(ref head, null, null); - TValue found; - if (TryGet(snapshot, key, out found)) - { // existing match; report the existing value instead - value = found; - return false; - } - var newNode = new Link(key, value, snapshot); - // did somebody move our cheese? - tryAgain = Interlocked.CompareExchange(ref head, newNode, snapshot) != snapshot; - } while (tryAgain); - return true; - } - private Link(TKey key, TValue value, Link tail) - { - Key = key; - Value = value; - Tail = tail; - } - public TKey Key { get; private set; } - public TValue Value { get; private set; } - public Link Tail { get; private set; } - } - partial class CacheInfo + private class PropertyInfoByNameComparer : IComparer { - public DeserializerState Deserializer { get; set; } - public Func[] OtherDeserializers { get; set; } - public Action ParamReader { get; set; } - private int hitCount; - public int GetHitCount() { return Interlocked.CompareExchange(ref hitCount, 0, 0); } - public void RecordHit() { Interlocked.Increment(ref hitCount); } + public int Compare(PropertyInfo x, PropertyInfo y) => string.CompareOrdinal(x.Name, y.Name); } - static int GetColumnHash(IDataReader reader) + private static int GetColumnHash(IDataReader reader, int startBound = 0, int length = -1) { unchecked { - int colCount = reader.FieldCount, hash = colCount; - for (int i = 0; i < colCount; i++) - { // binding code is only interested in names - not types + int max = length < 0 ? reader.FieldCount : startBound + length; + int hash = (-37 * startBound) + max; + for (int i = startBound; i < max; i++) + { object tmp = reader.GetName(i); - hash = (hash * 31) + (tmp == null ? 0 : tmp.GetHashCode()); + hash = (-79 * ((hash * 31) + (tmp?.GetHashCode() ?? 0))) + (reader.GetFieldType(i)?.GetHashCode() ?? 0); } return hash; } } - struct DeserializerState - { - public readonly int Hash; - public readonly Func Func; - - public DeserializerState(int hash, Func func) - { - Hash = hash; - Func = func; - } - } /// /// Called if the query cache is purged via PurgeQueryCache @@ -528,42 +51,10 @@ public DeserializerState(int hash, Func func) private static void OnQueryCachePurged() { var handler = QueryCachePurged; - if (handler != null) handler(null, EventArgs.Empty); - } -#if CSHARP30 - private static readonly Dictionary _queryCache = new Dictionary(); - // note: conflicts between readers and writers are so short-lived that it isn't worth the overhead of - // ReaderWriterLockSlim etc; a simple lock is faster - private static void SetQueryCache(Identity key, CacheInfo value) - { - lock (_queryCache) { _queryCache[key] = value; } - } - private static bool TryGetQueryCache(Identity key, out CacheInfo value) - { - lock (_queryCache) { return _queryCache.TryGetValue(key, out value); } - } - private static void PurgeQueryCacheByType(Type type) - { - lock (_queryCache) - { - var toRemove = _queryCache.Keys.Where(id => id.type == type).ToArray(); - foreach (var key in toRemove) - _queryCache.Remove(key); - } - } - /// - /// Purge the query cache - /// - public static void PurgeQueryCache() - { - lock (_queryCache) - { - _queryCache.Clear(); - } - OnQueryCachePurged(); + handler?.Invoke(null, EventArgs.Empty); } -#else - static readonly System.Collections.Concurrent.ConcurrentDictionary _queryCache = new System.Collections.Concurrent.ConcurrentDictionary(); + + private static readonly System.Collections.Concurrent.ConcurrentDictionary _queryCache = new System.Collections.Concurrent.ConcurrentDictionary(); private static void SetQueryCache(Identity key, CacheInfo value) { if (Interlocked.Increment(ref collect) == COLLECT_PER_ITEMS) @@ -581,8 +72,7 @@ private static void CollectCacheGarbage() { if (pair.Value.GetHitCount() <= COLLECT_HIT_COUNT_MIN) { - CacheInfo cache; - _queryCache.TryRemove(pair.Key, out cache); + _queryCache.TryRemove(pair.Key, out CacheInfo cache); } } } @@ -607,11 +97,12 @@ private static bool TryGetQueryCache(Identity key, out CacheInfo value) } /// - /// Purge the query cache + /// Purge the query cache /// public static void PurgeQueryCache() { _queryCache.Clear(); + TypeDeserializerCache.Purge(); OnQueryCachePurged(); } @@ -619,14 +110,14 @@ private static void PurgeQueryCacheByType(Type type) { foreach (var entry in _queryCache) { - CacheInfo cache; if (entry.Key.type == type) - _queryCache.TryRemove(entry.Key, out cache); + _queryCache.TryRemove(entry.Key, out CacheInfo cache); } + TypeDeserializerCache.Purge(type); } /// - /// Return a count of all the cached queries by dapper + /// Return a count of all the cached queries by Dapper /// /// public static int GetCachedSQLCount() @@ -635,15 +126,16 @@ public static int GetCachedSQLCount() } /// - /// Return a list of all the queries cached by dapper + /// Return a list of all the queries cached by Dapper /// /// /// public static IEnumerable> GetCachedSQL(int ignoreHitCountAbove = int.MaxValue) { var data = _queryCache.Select(pair => Tuple.Create(pair.Key.connectionString, pair.Key.sql, pair.Value.GetHitCount())); - if (ignoreHitCountAbove < int.MaxValue) data = data.Where(tuple => tuple.Item3 <= ignoreHitCountAbove); - return data; + return (ignoreHitCountAbove < int.MaxValue) + ? data.Where(tuple => tuple.Item3 <= ignoreHitCountAbove) + : data; } /// @@ -655,8 +147,7 @@ public static IEnumerable> GetHashCollissions() var counts = new Dictionary(); foreach (var key in _queryCache.Keys) { - int count; - if (!counts.TryGetValue(key.hashCode, out count)) + if (!counts.TryGetValue(key.hashCode, out int count)) { counts.Add(key.hashCode, 1); } @@ -668,92 +159,119 @@ public static IEnumerable> GetHashCollissions() return from pair in counts where pair.Value > 1 select Tuple.Create(pair.Key, pair.Value); - } -#endif - - static Dictionary typeMap; + private static Dictionary typeMap; static SqlMapper() { - typeMap = new Dictionary(); - typeMap[typeof(byte)] = DbType.Byte; - typeMap[typeof(sbyte)] = DbType.SByte; - typeMap[typeof(short)] = DbType.Int16; - typeMap[typeof(ushort)] = DbType.UInt16; - typeMap[typeof(int)] = DbType.Int32; - typeMap[typeof(uint)] = DbType.UInt32; - typeMap[typeof(long)] = DbType.Int64; - typeMap[typeof(ulong)] = DbType.UInt64; - typeMap[typeof(float)] = DbType.Single; - typeMap[typeof(double)] = DbType.Double; - typeMap[typeof(decimal)] = DbType.Decimal; - typeMap[typeof(bool)] = DbType.Boolean; - typeMap[typeof(string)] = DbType.String; - typeMap[typeof(char)] = DbType.StringFixedLength; - typeMap[typeof(Guid)] = DbType.Guid; - typeMap[typeof(DateTime)] = DbType.DateTime; - typeMap[typeof(DateTimeOffset)] = DbType.DateTimeOffset; - typeMap[typeof(TimeSpan)] = DbType.Time; - typeMap[typeof(byte[])] = DbType.Binary; - typeMap[typeof(byte?)] = DbType.Byte; - typeMap[typeof(sbyte?)] = DbType.SByte; - typeMap[typeof(short?)] = DbType.Int16; - typeMap[typeof(ushort?)] = DbType.UInt16; - typeMap[typeof(int?)] = DbType.Int32; - typeMap[typeof(uint?)] = DbType.UInt32; - typeMap[typeof(long?)] = DbType.Int64; - typeMap[typeof(ulong?)] = DbType.UInt64; - typeMap[typeof(float?)] = DbType.Single; - typeMap[typeof(double?)] = DbType.Double; - typeMap[typeof(decimal?)] = DbType.Decimal; - typeMap[typeof(bool?)] = DbType.Boolean; - typeMap[typeof(char?)] = DbType.StringFixedLength; - typeMap[typeof(Guid?)] = DbType.Guid; - typeMap[typeof(DateTime?)] = DbType.DateTime; - typeMap[typeof(DateTimeOffset?)] = DbType.DateTimeOffset; - typeMap[typeof(TimeSpan?)] = DbType.Time; - typeMap[typeof(object)] = DbType.Object; + typeMap = new Dictionary + { + [typeof(byte)] = DbType.Byte, + [typeof(sbyte)] = DbType.SByte, + [typeof(short)] = DbType.Int16, + [typeof(ushort)] = DbType.UInt16, + [typeof(int)] = DbType.Int32, + [typeof(uint)] = DbType.UInt32, + [typeof(long)] = DbType.Int64, + [typeof(ulong)] = DbType.UInt64, + [typeof(float)] = DbType.Single, + [typeof(double)] = DbType.Double, + [typeof(decimal)] = DbType.Decimal, + [typeof(bool)] = DbType.Boolean, + [typeof(string)] = DbType.String, + [typeof(char)] = DbType.StringFixedLength, + [typeof(Guid)] = DbType.Guid, + [typeof(DateTime)] = DbType.DateTime, + [typeof(DateTimeOffset)] = DbType.DateTimeOffset, + [typeof(TimeSpan)] = DbType.Time, + [typeof(byte[])] = DbType.Binary, + [typeof(byte?)] = DbType.Byte, + [typeof(sbyte?)] = DbType.SByte, + [typeof(short?)] = DbType.Int16, + [typeof(ushort?)] = DbType.UInt16, + [typeof(int?)] = DbType.Int32, + [typeof(uint?)] = DbType.UInt32, + [typeof(long?)] = DbType.Int64, + [typeof(ulong?)] = DbType.UInt64, + [typeof(float?)] = DbType.Single, + [typeof(double?)] = DbType.Double, + [typeof(decimal?)] = DbType.Decimal, + [typeof(bool?)] = DbType.Boolean, + [typeof(char?)] = DbType.StringFixedLength, + [typeof(Guid?)] = DbType.Guid, + [typeof(DateTime?)] = DbType.DateTime, + [typeof(DateTimeOffset?)] = DbType.DateTimeOffset, + [typeof(TimeSpan?)] = DbType.Time, + [typeof(object)] = DbType.Object + }; + ResetTypeHandlers(false); } /// - /// Clear the registered type handlers + /// Clear the registered type handlers. /// - public static void ResetTypeHandlers() + public static void ResetTypeHandlers() => ResetTypeHandlers(true); + + private static void ResetTypeHandlers(bool clone) { typeHandlers = new Dictionary(); + AddTypeHandlerImpl(typeof(DataTable), new DataTableHandler(), clone); + AddTypeHandlerImpl(typeof(XmlDocument), new XmlDocumentHandler(), clone); + AddTypeHandlerImpl(typeof(XDocument), new XDocumentHandler(), clone); + AddTypeHandlerImpl(typeof(XElement), new XElementHandler(), clone); } + /// - /// Configire the specified type to be mapped to a given db-type + /// Configure the specified type to be mapped to a given db-type. /// + /// The type to map from. + /// The database type to map to. public static void AddTypeMap(Type type, DbType dbType) { // use clone, mutate, replace to avoid threading issues var snapshot = typeMap; - DbType oldValue; - if (snapshot.TryGetValue(type, out oldValue) && oldValue == dbType) return; // nothing to do + if (snapshot.TryGetValue(type, out DbType oldValue) && oldValue == dbType) return; // nothing to do - var newCopy = new Dictionary(snapshot); - newCopy[type] = dbType; - typeMap = newCopy; + typeMap = new Dictionary(snapshot) { [type] = dbType }; } /// - /// Configire the specified type to be processed by a custom handler + /// Removes the specified type from the Type/DbType mapping table. /// - public static void AddTypeHandler(Type type, ITypeHandler handler) + /// The type to remove from the current map. + public static void RemoveTypeMap(Type type) { - AddTypeHandlerImpl(type, handler, true); + // use clone, mutate, replace to avoid threading issues + var snapshot = typeMap; + + if (!snapshot.ContainsKey(type)) return; // nothing to do + + var newCopy = new Dictionary(snapshot); + newCopy.Remove(type); + + typeMap = newCopy; } /// - /// Configire the specified type to be processed by a custom handler + /// Configure the specified type to be processed by a custom handler. + /// + /// The type to handle. + /// The handler to process the . + public static void AddTypeHandler(Type type, ITypeHandler handler) => AddTypeHandlerImpl(type, handler, true); + + internal static bool HasTypeHandler(Type type) => typeHandlers.ContainsKey(type); + + /// + /// Configure the specified type to be processed by a custom handler. /// + /// The type to handle. + /// The handler to process the . + /// Whether to clone the current type handler map. public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clone) { - if (type == null) throw new ArgumentNullException("type"); + if (type == null) throw new ArgumentNullException(nameof(type)); Type secondary = null; if (type.IsValueType) @@ -772,16 +290,15 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clon } var snapshot = typeHandlers; - ITypeHandler oldValue; - if (snapshot.TryGetValue(type, out oldValue) && handler == oldValue) return; // nothing to do + if (snapshot.TryGetValue(type, out ITypeHandler oldValue) && handler == oldValue) return; // nothing to do var newCopy = clone ? new Dictionary(snapshot) : snapshot; #pragma warning disable 618 - typeof(TypeHandlerCache<>).MakeGenericType(type).GetMethod("SetHandler", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { handler }); + typeof(TypeHandlerCache<>).MakeGenericType(type).GetMethod(nameof(TypeHandlerCache.SetHandler), BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { handler }); if (secondary != null) { - typeof(TypeHandlerCache<>).MakeGenericType(secondary).GetMethod("SetHandler", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { handler }); + typeof(TypeHandlerCache<>).MakeGenericType(secondary).GetMethod(nameof(TypeHandlerCache.SetHandler), BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { handler }); } #pragma warning restore 618 if (handler == null) @@ -798,68 +315,44 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clon } /// - /// Configire the specified type to be processed by a custom handler - /// - public static void AddTypeHandler(TypeHandler handler) - { - AddTypeHandlerImpl(typeof(T), handler, true); - } - - /// - /// Not intended for direct usage + /// Configure the specified type to be processed by a custom handler. /// - [Obsolete("Not intended for direct usage", false)] - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - public static class TypeHandlerCache - { - /// - /// Not intended for direct usage - /// - [Obsolete("Not intended for direct usage", true)] - public static T Parse(object value) - { - return (T)handler.Parse(typeof(T), value); - - } - - /// - /// Not intended for direct usage - /// - [Obsolete("Not intended for direct usage", true)] - public static void SetValue(IDbDataParameter parameter, object value) - { - handler.SetValue(parameter, value); - } - - internal static void SetHandler(ITypeHandler handler) - { -#pragma warning disable 618 - TypeHandlerCache.handler = handler; -#pragma warning restore 618 - } - - private static ITypeHandler handler; - } + /// The type to handle. + /// The handler for the type . + public static void AddTypeHandler(TypeHandler handler) => AddTypeHandlerImpl(typeof(T), handler, true); - private static Dictionary typeHandlers = new Dictionary(); + private static Dictionary typeHandlers; internal const string LinqBinary = "System.Data.Linq.Binary"; + private const string ObsoleteInternalUsageOnly = "This method is for internal use only"; + /// - /// Get the DbType that maps to a given value + /// Get the DbType that maps to a given value. /// - [Obsolete("This method is for internal use only"), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + /// The object to get a corresponding database type for. + [Obsolete(ObsoleteInternalUsageOnly, false)] + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] public static DbType GetDbType(object value) { if (value == null || value is DBNull) return DbType.Object; - ITypeHandler handler; - return LookupDbType(value.GetType(), "n/a", false, out handler); - + return LookupDbType(value.GetType(), "n/a", false, out ITypeHandler handler); } - internal static DbType LookupDbType(Type type, string name, bool demand, out ITypeHandler handler) + + /// + /// OBSOLETE: For internal usage only. Lookup the DbType and handler for a given Type and member + /// + /// The type to lookup. + /// The name (for error messages). + /// Whether to demand a value (throw if missing). + /// The handler for . + [Obsolete(ObsoleteInternalUsageOnly, false)] + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public static DbType LookupDbType(Type type, string name, bool demand, out ITypeHandler handler) { - DbType dbType; handler = null; var nullUnderlyingType = Nullable.GetUnderlyingType(type); if (nullUnderlyingType != null) type = nullUnderlyingType; @@ -867,7 +360,7 @@ internal static DbType LookupDbType(Type type, string name, bool demand, out ITy { type = Enum.GetUnderlyingType(type); } - if (typeMap.TryGetValue(type, out dbType)) + if (typeMap.TryGetValue(type, out DbType dbType)) { return dbType; } @@ -875,370 +368,146 @@ internal static DbType LookupDbType(Type type, string name, bool demand, out ITy { return DbType.Binary; } + if (typeHandlers.TryGetValue(type, out handler)) + { + return DbType.Object; + } if (typeof(IEnumerable).IsAssignableFrom(type)) { + // auto-detect things like IEnumerable as a family + if (type.IsInterface && type.IsGenericType + && type.GetGenericTypeDefinition() == typeof(IEnumerable<>) + && typeof(IEnumerable).IsAssignableFrom(type)) + { + var argTypes = type.GetGenericArguments(); + if(typeof(IDataRecord).IsAssignableFrom(argTypes[0])) + { + try + { + handler = (ITypeHandler)Activator.CreateInstance( + typeof(SqlDataRecordHandler<>).MakeGenericType(argTypes)); + AddTypeHandlerImpl(type, handler, true); + return DbType.Object; + } + catch + { + handler = null; + } + } + } return DynamicParameters.EnumerableMultiParameter; } - if (typeHandlers.TryGetValue(type, out handler)) - { - return DbType.Object; - } - switch (type.FullName) + switch (type.FullName) { case "Microsoft.SqlServer.Types.SqlGeography": - AddTypeHandler(type, handler = new UdtTypeHandler("GEOGRAPHY")); + AddTypeHandler(type, handler = new UdtTypeHandler("geography")); return DbType.Object; case "Microsoft.SqlServer.Types.SqlGeometry": - AddTypeHandler(type, handler = new UdtTypeHandler("GEOMETRY")); + AddTypeHandler(type, handler = new UdtTypeHandler("geometry")); return DbType.Object; case "Microsoft.SqlServer.Types.SqlHierarchyId": - AddTypeHandler(type, handler = new UdtTypeHandler("HIERARCHYID")); + AddTypeHandler(type, handler = new UdtTypeHandler("hierarchyid")); return DbType.Object; } + if (demand) - throw new NotSupportedException(string.Format("The member {0} of type {1} cannot be used as a parameter value", name, type.FullName)); + throw new NotSupportedException($"The member {name} of type {type.FullName} cannot be used as a parameter value"); return DbType.Object; - - } - - /// - /// Identity of a cached query in Dapper, used for extensability - /// - public partial class Identity : IEquatable - { - internal Identity ForGrid(Type primaryType, int gridIndex) - { - return new Identity(sql, commandType, connectionString, primaryType, parametersType, null, gridIndex); - } - - internal Identity ForGrid(Type primaryType, Type[] otherTypes, int gridIndex) - { - return new Identity(sql, commandType, connectionString, primaryType, parametersType, otherTypes, gridIndex); - } - /// - /// Create an identity for use with DynamicParameters, internal use only - /// - /// - /// - public Identity ForDynamicParameters(Type type) - { - return new Identity(sql, commandType, connectionString, this.type, type, null, -1); - } - - internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, Type[] otherTypes) - : this(sql, commandType, connection.ConnectionString, type, parametersType, otherTypes, 0) - { } - private Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex) - { - this.sql = sql; - this.commandType = commandType; - this.connectionString = connectionString; - this.type = type; - this.parametersType = parametersType; - this.gridIndex = gridIndex; - unchecked - { - hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this - hashCode = hashCode * 23 + commandType.GetHashCode(); - hashCode = hashCode * 23 + gridIndex.GetHashCode(); - hashCode = hashCode * 23 + (sql == null ? 0 : sql.GetHashCode()); - hashCode = hashCode * 23 + (type == null ? 0 : type.GetHashCode()); - if (otherTypes != null) - { - foreach (var t in otherTypes) - { - hashCode = hashCode * 23 + (t == null ? 0 : t.GetHashCode()); - } - } - hashCode = hashCode * 23 + (connectionString == null ? 0 : SqlMapper.connectionStringComparer.GetHashCode(connectionString)); - hashCode = hashCode * 23 + (parametersType == null ? 0 : parametersType.GetHashCode()); - } - } - - /// - /// - /// - /// - /// - public override bool Equals(object obj) - { - return Equals(obj as Identity); - } - /// - /// The sql - /// - public readonly string sql; - /// - /// The command type - /// - public readonly CommandType? commandType; - - /// - /// - /// - public readonly int hashCode, gridIndex; - /// - /// - /// - public readonly Type type; - /// - /// - /// - public readonly string connectionString; - /// - /// - /// - public readonly Type parametersType; - /// - /// - /// - /// - public override int GetHashCode() - { - return hashCode; - } - /// - /// Compare 2 Identity objects - /// - /// - /// - public bool Equals(Identity other) - { - return - other != null && - gridIndex == other.gridIndex && - type == other.type && - sql == other.sql && - commandType == other.commandType && - SqlMapper.connectionStringComparer.Equals(connectionString, other.connectionString) && - parametersType == other.parametersType; - } - } - -#if CSHARP30 - /// - /// Execute parameterized SQL - /// - /// Number of rows affected - public static int Execute(this IDbConnection cnn, string sql, object param) - { - return Execute(cnn, sql, param, null, null, null); - } - - /// - /// Execute parameterized SQL - /// - /// Number of rows affected - public static int Execute(this IDbConnection cnn, string sql, object param, IDbTransaction transaction) - { - return Execute(cnn, sql, param, transaction, null, null); - } - - /// - /// Execute parameterized SQL - /// - /// Number of rows affected - public static int Execute(this IDbConnection cnn, string sql, object param, CommandType commandType) - { - return Execute(cnn, sql, param, null, null, commandType); - } - - /// - /// Execute parameterized SQL - /// - /// Number of rows affected - public static int Execute(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, CommandType commandType) - { - return Execute(cnn, sql, param, transaction, null, commandType); - } - - /// - /// Execute parameterized SQL and return an - /// - /// An that can be used to iterate over the results of the SQL query. - public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, object param) - { - return ExecuteReader(cnn, sql, param, null, null, null); - } - - /// - /// Execute parameterized SQL and return an - /// - /// An that can be used to iterate over the results of the SQL query. - public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, object param, IDbTransaction transaction) - { - return ExecuteReader(cnn, sql, param, transaction, null, null); - } - - /// - /// Execute parameterized SQL and return an - /// - /// An that can be used to iterate over the results of the SQL query. - public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, object param, CommandType commandType) - { - return ExecuteReader(cnn, sql, param, null, null, commandType); - } - - /// - /// Execute parameterized SQL and return an - /// - /// An that can be used to iterate over the results of the SQL query. - public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, CommandType commandType) - { - return ExecuteReader(cnn, sql, param, transaction, null, commandType); - } - - /// - /// Executes a query, returning the data typed as per T - /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, object param) - { - return Query(cnn, sql, param, null, true, null, null); - } - - /// - /// Executes a query, returning the data typed as per T - /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction) - { - return Query(cnn, sql, param, transaction, true, null, null); - } - - /// - /// Executes a query, returning the data typed as per T - /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, object param, CommandType commandType) - { - return Query(cnn, sql, param, null, true, null, commandType); - } - - /// - /// Executes a query, returning the data typed as per T - /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, CommandType commandType) - { - return Query(cnn, sql, param, transaction, true, null, commandType); - } - - /// - /// Execute a command that returns multiple result sets, and access each in turn - /// - public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param, IDbTransaction transaction) - { - return QueryMultiple(cnn, sql, param, transaction, null, null); - } - - /// - /// Execute a command that returns multiple result sets, and access each in turn - /// - public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param, CommandType commandType) - { - return QueryMultiple(cnn, sql, param, null, null, commandType); } /// - /// Execute a command that returns multiple result sets, and access each in turn + /// Obtains the data as a list; if it is *already* a list, the original object is returned without + /// any duplication; otherwise, ToList() is invoked. /// - public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, CommandType commandType) - { - return QueryMultiple(cnn, sql, param, transaction, null, commandType); - } -#endif - + /// The type of element in the list. + /// The enumerable to return as a list. + public static List AsList(this IEnumerable source) => + (source == null || source is List) ? (List)source : source.ToList(); /// - /// Execute parameterized SQL + /// Execute parameterized SQL. /// - /// Number of rows affected - public static int Execute( -#if CSHARP30 -this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -#endif -) + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The number of rows affected. + public static int Execute(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return ExecuteImpl(cnn, ref command); } + /// - /// Execute parameterized SQL + /// Execute parameterized SQL. /// - /// Number of rows affected - public static int Execute(this IDbConnection cnn, CommandDefinition command) - { - return ExecuteImpl(cnn, ref command); - } - + /// The connection to execute on. + /// The command to execute on this connection. + /// The number of rows affected. + public static int Execute(this IDbConnection cnn, CommandDefinition command) => ExecuteImpl(cnn, ref command); /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static object ExecuteScalar( -#if CSHARP30 -this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -#endif -) + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell selected as . + public static object ExecuteScalar(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return ExecuteScalarImpl(cnn, ref command); } /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static T ExecuteScalar( -#if CSHARP30 -this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -#endif -) + /// The type to return. + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell returned, as . + public static T ExecuteScalar(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return ExecuteScalarImpl(cnn, ref command); } /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static object ExecuteScalar(this IDbConnection cnn, CommandDefinition command) - { - return ExecuteScalarImpl(cnn, ref command); - } + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . + public static object ExecuteScalar(this IDbConnection cnn, CommandDefinition command) => + ExecuteScalarImpl(cnn, ref command); /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static T ExecuteScalar(this IDbConnection cnn, CommandDefinition command) - { - return ExecuteScalarImpl(cnn, ref command); - } + /// The type to return. + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . + public static T ExecuteScalar(this IDbConnection cnn, CommandDefinition command) => + ExecuteScalarImpl(cnn, ref command); private static IEnumerable GetMultiExec(object param) { return (param is IEnumerable - && !(param is string || param is IEnumerable> - )) ? (IEnumerable)param : null; + && !(param is string + || param is IEnumerable> + || param is IDynamicParameters) + ) ? (IEnumerable)param : null; } private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition command) @@ -1249,13 +518,11 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com CacheInfo info = null; if (multiExec != null) { -#if ASYNC - if((command.Flags & CommandFlags.Pipelined) != 0) + if ((command.Flags & CommandFlags.Pipelined) != 0) { // this includes all the code for concurrent/overlapped query return ExecuteMultiImplAsync(cnn, command, multiExec).Result; } -#endif bool isFirst = true; int total = 0; bool wasClosed = cnn.State == ConnectionState.Closed; @@ -1271,7 +538,7 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com { masterSql = cmd.CommandText; isFirst = false; - identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null); + identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType()); info = GetCacheInfo(identity, obj, command.AddToCache); } else @@ -1295,18 +562,25 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com // nice and simple if (param != null) { - identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null); + identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType()); info = GetCacheInfo(identity, param, command.AddToCache); } return ExecuteCommand(cnn, ref command, param == null ? null : info.ParamReader); } /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? /// An that can be used to iterate over the results of the SQL query. /// - /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a DataTable or DataSet. + /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a + /// or . /// /// /// @@ -1319,135 +593,334 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com /// ]]> /// /// - public static IDataReader ExecuteReader( -#if CSHARP30 -this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -#endif -) + public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered); - return ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); + var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd); + return WrappedReader.Create(dbcmd, reader); } /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The command to execute. /// An that can be used to iterate over the results of the SQL query. /// - /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a DataTable or DataSet. + /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a + /// or . /// public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinition command) { - return ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default); + var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd); + return WrappedReader.Create(dbcmd, reader); } + /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The command to execute. + /// The flags for this reader. /// An that can be used to iterate over the results of the SQL query. /// - /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a DataTable or DataSet. + /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a + /// or . /// public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) { - return ExecuteReaderImpl(cnn, ref command, commandBehavior); + var reader = ExecuteReaderImpl(cnn, ref command, commandBehavior, out IDbCommand dbcmd); + return WrappedReader.Create(dbcmd, reader); + } + + /// + /// Return a sequence of dynamic objects with properties matching the columns. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// Whether to buffer the results in memory. + /// The command timeout (in seconds). + /// The type of command to execute. + /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) => + Query(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType); + + /// + /// Return a dynamic object with properties matching the columns. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static dynamic QueryFirst(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryFirst(cnn, sql, param as object, transaction, commandTimeout, commandType); + + /// + /// Return a dynamic object with properties matching the columns. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static dynamic QueryFirstOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryFirstOrDefault(cnn, sql, param as object, transaction, commandTimeout, commandType); + + /// + /// Return a dynamic object with properties matching the columns. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static dynamic QuerySingle(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QuerySingle(cnn, sql, param as object, transaction, commandTimeout, commandType); + + /// + /// Return a dynamic object with properties matching the columns. + /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> + public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QuerySingleOrDefault(cnn, sql, param as object, transaction, commandTimeout, commandType); + + /// + /// Executes a query, returning the data typed as . + /// + /// The type of results to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// Whether to buffer results in memory. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) + { + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); + var data = QueryImpl(cnn, command, typeof(T)); + return command.Buffered ? data.ToList() : data; } -#if !CSHARP30 /// - /// Return a list of dynamic objects, reader is closed after the call + /// Executes a single-row query, returning the data typed as . /// - public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QueryFirst(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - return Query(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.First, ref command, typeof(T)); } -#else + /// - /// Return a list of dynamic objects, reader is closed after the call + /// Executes a single-row query, returning the data typed as . /// - public static IEnumerable> Query(this IDbConnection cnn, string sql, object param) + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QueryFirstOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - return Query(cnn, sql, param, null, true, null, null); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.FirstOrDefault, ref command, typeof(T)); } /// - /// Return a list of dynamic objects, reader is closed after the call + /// Executes a single-row query, returning the data typed as . /// - public static IEnumerable> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction) + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QuerySingle(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - return Query(cnn, sql, param, transaction, true, null, null); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.Single, ref command, typeof(T)); } /// - /// Return a list of dynamic objects, reader is closed after the call + /// Executes a single-row query, returning the data typed as . /// - public static IEnumerable> Query(this IDbConnection cnn, string sql, object param, CommandType? commandType) + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QuerySingleOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - return Query(cnn, sql, param, null, true, null, commandType); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.SingleOrDefault, ref command, typeof(T)); } /// - /// Return a list of dynamic objects, reader is closed after the call + /// Executes a single-row query, returning the data typed as . /// - public static IEnumerable> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, CommandType? commandType) + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// Whether to buffer results in memory. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static IEnumerable Query(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) { - return Query(cnn, sql, param, transaction, true, null, commandType); + if (type == null) throw new ArgumentNullException(nameof(type)); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); + var data = QueryImpl(cnn, command, type); + return command.Buffered ? data.ToList() : data; } /// - /// Return a list of dynamic objects, reader is closed after the call + /// Executes a single-row query, returning the data typed as . /// - public static IEnumerable> Query(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType) + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static object QueryFirst(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - return Query>(cnn, sql, param, transaction, buffered, commandTimeout, commandType); + if (type == null) throw new ArgumentNullException(nameof(type)); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.First, ref command, type); } -#endif /// - /// Executes a query, returning the data typed as per T + /// Executes a single-row query, returning the data typed as . /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static IEnumerable Query( -#if CSHARP30 -this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null -#endif -) + public static object QueryFirstOrDefault(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); - var data = QueryImpl(cnn, command, typeof(T)); - return command.Buffered ? data.ToList() : data; + if (type == null) throw new ArgumentNullException(nameof(type)); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.FirstOrDefault, ref command, type); } /// - /// Executes a query, returning the data typed as per the Type suggested + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static IEnumerable Query( -#if CSHARP30 -this IDbConnection cnn, Type type, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null -#endif -) + public static object QuerySingle(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { - if (type == null) throw new ArgumentNullException("type"); - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); - var data = QueryImpl(cnn, command, type); - return command.Buffered ? data.ToList() : data; + if (type == null) throw new ArgumentNullException(nameof(type)); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.Single, ref command, type); + } + + /// + /// Executes a single-row query, returning the data typed as . + /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static object QuerySingleOrDefault(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); + return QueryRowImpl(cnn, Row.SingleOrDefault, ref command, type); } + /// - /// Executes a query, returning the data typed as per T + /// Executes a query, returning the data typed as . /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A sequence of data of ; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// public static IEnumerable Query(this IDbConnection cnn, CommandDefinition command) @@ -1456,33 +929,85 @@ public static IEnumerable Query(this IDbConnection cnn, CommandDefinition return command.Buffered ? data.ToList() : data; } + /// + /// Executes a query, returning the data typed as . + /// + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single instance or null of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QueryFirst(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.First, ref command, typeof(T)); + /// + /// Executes a query, returning the data typed as . + /// + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single or null instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QueryFirstOrDefault(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.FirstOrDefault, ref command, typeof(T)); /// - /// Execute a command that returns multiple result sets, and access each in turn + /// Executes a query, returning the data typed as . /// - public static GridReader QueryMultiple( -#if CSHARP30 -this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered); - return QueryMultipleImpl(cnn, ref command); - } + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QuerySingle(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.Single, ref command, typeof(T)); + + /// + /// Executes a query, returning the data typed as . + /// + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static T QuerySingleOrDefault(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.SingleOrDefault, ref command, typeof(T)); + /// - /// Execute a command that returns multiple result sets, and access each in turn + /// Execute a command that returns multiple result sets, and access each in turn. /// - public static GridReader QueryMultiple(this IDbConnection cnn, CommandDefinition command) + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return QueryMultipleImpl(cnn, ref command); } + + /// + /// Execute a command that returns multiple result sets, and access each in turn. + /// + /// The connection to query on. + /// The command to execute for this query. + public static GridReader QueryMultiple(this IDbConnection cnn, CommandDefinition command) => + QueryMultipleImpl(cnn, ref command); + private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandDefinition command) { object param = command.Parameters; - Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param == null ? null : param.GetType(), null); + var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param?.GetType()); CacheInfo info = GetCacheInfo(identity, param, command.AddToCache); IDbCommand cmd = null; @@ -1492,9 +1017,10 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD { if (wasClosed) cnn.Open(); cmd = command.SetupCommand(cnn, info.ParamReader); - reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess); + reader = ExecuteReaderWithFlagsFallback(cmd, wasClosed, CommandBehavior.SequentialAccess); - var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters); + var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache); + cmd = null; // now owned by result wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader // with the CloseConnection flag, so the reader will deal with the connection; we // still need something in the "finally" to ensure that broken SQL still results @@ -1505,20 +1031,40 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD { if (reader != null) { - if (!reader.IsClosed) try { cmd.Cancel(); } + if (!reader.IsClosed) + { + try { cmd?.Cancel(); } catch { /* don't spoil the existing exception */ } + } reader.Dispose(); } - if (cmd != null) cmd.Dispose(); + cmd?.Dispose(); if (wasClosed) cnn.Close(); throw; } } + private static IDataReader ExecuteReaderWithFlagsFallback(IDbCommand cmd, bool wasClosed, CommandBehavior behavior) + { + try + { + return cmd.ExecuteReader(GetBehavior(wasClosed, behavior)); + } + catch (ArgumentException ex) + { // thanks, Sqlite! + if (Settings.DisableCommandBehaviorOptimizations(behavior, ex)) + { + // we can retry; this time it will have different flags + return cmd.ExecuteReader(GetBehavior(wasClosed, behavior)); + } + throw; + } + } + private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefinition command, Type effectiveType) { object param = command.Parameters; - var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null); + var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType()); var info = GetCacheInfo(identity, param, command.AddToCache); IDbCommand cmd = null; @@ -1530,7 +1076,7 @@ private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefini cmd = command.SetupCommand(cnn, info.ParamReader); if (wasClosed) cnn.Open(); - reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess); + reader = ExecuteReaderWithFlagsFallback(cmd, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult); wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader // with the CloseConnection flag, so the reader will deal with the connection; we // still need something in the "finally" to ensure that broken SQL still results @@ -1559,7 +1105,7 @@ private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefini yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); } } - while (reader.NextResult()) { } + while (reader.NextResult()) { /* ignore subsequent result sets */ } // happy path; close the reader cleanly - no // need for "Cancel" etc reader.Dispose(); @@ -1571,237 +1117,317 @@ private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefini { if (reader != null) { - if (!reader.IsClosed) try { cmd.Cancel(); } + if (!reader.IsClosed) + { + try { cmd.Cancel(); } catch { /* don't spoil the existing exception */ } + } reader.Dispose(); } if (wasClosed) cnn.Close(); - if (cmd != null) cmd.Dispose(); + cmd?.Dispose(); } } - /// - /// Maps a query to objects - /// - /// The first type in the recordset - /// The second type in the recordset - /// The return type - /// - /// - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout - /// Is it a stored proc or a batch? - /// - public static IEnumerable Query( -#if CSHARP30 -this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Maps a query to objects - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout - /// - /// - public static IEnumerable Query( -#if CSHARP30 -this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with 4 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query( -#if CSHARP30 -this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } - -#if !CSHARP30 - /// - /// Perform a multi mapping query with 5 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with 6 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -) + [Flags] + internal enum Row { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); + First = 0, + FirstOrDefault = 1, // & FirstOrDefault != 0: allow zero rows + Single = 2, // & Single != 0: demand at least one row + SingleOrDefault = 3 } - - /// - /// Perform a multi mapping query with 7 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) + private static readonly int[] ErrTwoRows = new int[2], ErrZeroRows = new int[0]; + private static void ThrowMultipleRows(Row row) { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); + switch (row) + { // get the standard exception from the runtime + case Row.Single: ErrTwoRows.Single(); break; + case Row.SingleOrDefault: ErrTwoRows.SingleOrDefault(); break; + default: throw new InvalidOperationException(); + } } - /// - /// Perform a multi mapping query with arbitrary input parameters - /// - /// The return type - /// - /// - /// array of types in the recordset - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout - /// Is it a stored proc or a batch? - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, Type[] types, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); - var results = MultiMapImpl(cnn, command, types, map, splitOn, null, null, true); - return buffered ? results.ToList() : results; - } -#endif - partial class DontMap { } - static IEnumerable MultiMap( - this IDbConnection cnn, string sql, Delegate map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType) + private static void ThrowZeroRows(Row row) { - var command = new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); - var results = MultiMapImpl(cnn, command, map, splitOn, null, null, true); - return buffered ? results.ToList() : results; + switch (row) + { // get the standard exception from the runtime + case Row.First: ErrZeroRows.First(); break; + case Row.Single: ErrZeroRows.Single(); break; + default: throw new InvalidOperationException(); + } } - static IEnumerable MultiMapImpl(this IDbConnection cnn, CommandDefinition command, Delegate map, string splitOn, IDataReader reader, Identity identity, bool finalize) + private static T QueryRowImpl(IDbConnection cnn, Row row, ref CommandDefinition command, Type effectiveType) { object param = command.Parameters; - identity = identity ?? new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param == null ? null : param.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) }); - CacheInfo cinfo = GetCacheInfo(identity, param, command.AddToCache); + var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType()); + var info = GetCacheInfo(identity, param, command.AddToCache); - IDbCommand ownedCommand = null; - IDataReader ownedReader = null; + IDbCommand cmd = null; + IDataReader reader = null; - bool wasClosed = cnn != null && cnn.State == ConnectionState.Closed; + bool wasClosed = cnn.State == ConnectionState.Closed; + try + { + cmd = command.SetupCommand(cnn, info.ParamReader); + + if (wasClosed) cnn.Open(); + reader = ExecuteReaderWithFlagsFallback(cmd, wasClosed, (row & Row.Single) != 0 + ? CommandBehavior.SequentialAccess | CommandBehavior.SingleResult // need to allow multiple rows, to check fail condition + : CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow); + wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader + + T result = default(T); + if (reader.Read() && reader.FieldCount != 0) + { + // with the CloseConnection flag, so the reader will deal with the connection; we + // still need something in the "finally" to ensure that broken SQL still results + // in the connection closing itself + var tuple = info.Deserializer; + int hash = GetColumnHash(reader); + if (tuple.Func == null || tuple.Hash != hash) + { + tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(effectiveType, reader, 0, -1, false)); + if (command.AddToCache) SetQueryCache(identity, info); + } + + var func = tuple.Func; + object val = func(reader); + if (val == null || val is T) + { + result = (T)val; + } + else + { + var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; + result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); + } + if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row); + while (reader.Read()) { /* ignore subsequent rows */ } + } + else if ((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one + { + ThrowZeroRows(row); + } + while (reader.NextResult()) { /* ignore subsequent result sets */ } + // happy path; close the reader cleanly - no + // need for "Cancel" etc + reader.Dispose(); + reader = null; + + command.OnCompleted(); + return result; + } + finally + { + if (reader != null) + { + if (!reader.IsClosed) + { + try { cmd.Cancel(); } + catch { /* don't spoil the existing exception */ } + } + reader.Dispose(); + } + if (wasClosed) cnn.Close(); + cmd?.Dispose(); + } + } + + /// + /// Perform a multi-mapping query with 2 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 3 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 4 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 5 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 6 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 7 input types. If you need more types -> use Query with Type[] parameter. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The seventh type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with an arbitrary number of input types. + /// This returns a single type, combined from the raw types via . + /// + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// Array of types in the recordset. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Type[] types, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) + { + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); + var results = MultiMapImpl(cnn, command, types, map, splitOn, null, null, true); + return buffered ? results.ToList() : results; + } + + private static IEnumerable MultiMap( + this IDbConnection cnn, string sql, Delegate map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType) + { + var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); + var results = MultiMapImpl(cnn, command, map, splitOn, null, null, true); + return buffered ? results.ToList() : results; + } + + private static IEnumerable MultiMapImpl(this IDbConnection cnn, CommandDefinition command, Delegate map, string splitOn, IDataReader reader, Identity identity, bool finalize) + { + object param = command.Parameters; + identity = identity ?? new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param?.GetType()); + CacheInfo cinfo = GetCacheInfo(identity, param, command.AddToCache); + + IDbCommand ownedCommand = null; + IDataReader ownedReader = null; + + bool wasClosed = cnn?.State == ConnectionState.Closed; try { if (reader == null) { ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader); if (wasClosed) cnn.Open(); - ownedReader = ownedCommand.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess); + ownedReader = ExecuteReaderWithFlagsFallback(ownedCommand, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult); reader = ownedReader; } - DeserializerState deserializer = default(DeserializerState); - Func[] otherDeserializers = null; + var deserializer = default(DeserializerState); + Func[] otherDeserializers; int hash = GetColumnHash(reader); if ((deserializer = cinfo.Deserializer).Func == null || (otherDeserializers = cinfo.OtherDeserializers) == null || hash != deserializer.Hash) { - var deserializers = GenerateDeserializers(new Type[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) }, splitOn, reader); + var deserializers = GenerateDeserializers(identity, splitOn, reader); deserializer = cinfo.Deserializer = new DeserializerState(hash, deserializers[0]); otherDeserializers = cinfo.OtherDeserializers = deserializers.Skip(1).ToArray(); if (command.AddToCache) SetQueryCache(identity, cinfo); @@ -1817,7 +1443,7 @@ static IEnumerable MultiMapImpl MultiMapImpl MultiMapImpl(this IDbConnection cnn, CommandDefinition command, Type[] types, Func map, string splitOn, IDataReader reader, Identity identity, bool finalize) + private static CommandBehavior GetBehavior(bool close, CommandBehavior @default) + { + return (close ? (@default | CommandBehavior.CloseConnection) : @default) & Settings.AllowedCommandBehaviors; + } + + private static IEnumerable MultiMapImpl(this IDbConnection cnn, CommandDefinition command, Type[] types, Func map, string splitOn, IDataReader reader, Identity identity, bool finalize) { if (types.Length < 1) { @@ -1850,29 +1475,29 @@ static IEnumerable MultiMapImpl(this IDbConnection cnn, Comman } object param = command.Parameters; - identity = identity ?? new Identity(command.CommandText, command.CommandType, cnn, types[0], param == null ? null : param.GetType(), types); + identity = identity ?? new IdentityWithTypes(command.CommandText, command.CommandType, cnn, types[0], param?.GetType(), types); CacheInfo cinfo = GetCacheInfo(identity, param, command.AddToCache); IDbCommand ownedCommand = null; IDataReader ownedReader = null; - bool wasClosed = cnn != null && cnn.State == ConnectionState.Closed; + bool wasClosed = cnn?.State == ConnectionState.Closed; try { if (reader == null) { ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader); if (wasClosed) cnn.Open(); - ownedReader = ownedCommand.ExecuteReader(); + ownedReader = ExecuteReaderWithFlagsFallback(ownedCommand, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult); reader = ownedReader; } - DeserializerState deserializer = default(DeserializerState); - Func[] otherDeserializers = null; + DeserializerState deserializer; + Func[] otherDeserializers; int hash = GetColumnHash(reader); if ((deserializer = cinfo.Deserializer).Func == null || (otherDeserializers = cinfo.OtherDeserializers) == null || hash != deserializer.Hash) { - var deserializers = GenerateDeserializers(types, splitOn, reader); + var deserializers = GenerateDeserializers(identity, splitOn, reader); deserializer = cinfo.Deserializer = new DeserializerState(hash, deserializers[0]); otherDeserializers = cinfo.OtherDeserializers = deserializers.Skip(1).ToArray(); SetQueryCache(identity, cinfo); @@ -1888,7 +1513,7 @@ static IEnumerable MultiMapImpl(this IDbConnection cnn, Comman } if (finalize) { - while (reader.NextResult()) { } + while (reader.NextResult()) { /* ignore subsequent result sets */ } command.OnCompleted(); } } @@ -1897,17 +1522,11 @@ static IEnumerable MultiMapImpl(this IDbConnection cnn, Comman { try { - if (ownedReader != null) - { - ownedReader.Dispose(); - } + ownedReader?.Dispose(); } finally { - if (ownedCommand != null) - { - ownedCommand.Dispose(); - } + ownedCommand?.Dispose(); if (wasClosed) cnn.Close(); } } @@ -1923,14 +1542,12 @@ private static Func GenerateMapper ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r)); case 3: return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r)); -#if !CSHARP30 case 4: return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r)); case 5: return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r)); case 6: return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r)); -#endif default: throw new NotSupportedException(); } @@ -1952,12 +1569,14 @@ private static Func GenerateMapper(int length, Fu }; } - private static Func[] GenerateDeserializers(Type[] types, string splitOn, IDataReader reader) + private static Func[] GenerateDeserializers(Identity identity, string splitOn, IDataReader reader) { var deserializers = new List>(); var splits = splitOn.Split(',').Select(s => s.Trim()).ToArray(); bool isMultiSplit = splits.Length > 1; - if (types.First() == typeof(Object)) + + int typeCount = identity.TypeCount; + if (identity.GetType(0) == typeof(object)) { // we go left to right for dynamic multi-mapping so that the madness of TestMultiMappingVariations // is supported @@ -1965,8 +1584,10 @@ private static Func[] GenerateDeserializers(Type[] types, s int currentPos = 0; int splitIdx = 0; string currentSplit = splits[splitIdx]; - foreach (var type in types) + + for (int i = 0; i < typeCount; i++) { + Type type = identity.GetType(i); if (type == typeof(DontMap)) { break; @@ -1977,7 +1598,7 @@ private static Func[] GenerateDeserializers(Type[] types, s { currentSplit = splits[++splitIdx]; } - deserializers.Add((GetDeserializer(type, reader, currentPos, splitPoint - currentPos, !first))); + deserializers.Add(GetDeserializer(type, reader, currentPos, splitPoint - currentPos, !first)); currentPos = splitPoint; first = false; } @@ -1989,9 +1610,9 @@ private static Func[] GenerateDeserializers(Type[] types, s int currentPos = reader.FieldCount; int splitIdx = splits.Length - 1; var currentSplit = splits[splitIdx]; - for (var typeIdx = types.Length - 1; typeIdx >= 0; --typeIdx) + for (var typeIdx = typeCount - 1; typeIdx >= 0; --typeIdx) { - var type = types[typeIdx]; + var type = identity.GetType(typeIdx); if (type == typeof(DontMap)) { continue; @@ -2007,13 +1628,13 @@ private static Func[] GenerateDeserializers(Type[] types, s } } - deserializers.Add((GetDeserializer(type, reader, splitPoint, currentPos - splitPoint, typeIdx > 0))); + deserializers.Add(GetDeserializer(type, reader, splitPoint, currentPos - splitPoint, typeIdx > 0)); currentPos = splitPoint; } deserializers.Reverse(); - } + return deserializers.ToArray(); } @@ -2060,16 +1681,19 @@ private static int GetNextSplit(int startIdx, string splitOn, IDataReader reader private static CacheInfo GetCacheInfo(Identity identity, object exampleParameters, bool addToCache) { - CacheInfo info; - if (!TryGetQueryCache(identity, out info)) + if (!TryGetQueryCache(identity, out CacheInfo info)) { + if (GetMultiExec(exampleParameters) != null) + { + throw new InvalidOperationException("An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context"); + } info = new CacheInfo(); if (identity.parametersType != null) { Action reader; if (exampleParameters is IDynamicParameters) { - reader = (cmd, obj) => { ((IDynamicParameters)obj).AddParameters(cmd, identity); }; + reader = (cmd, obj) => ((IDynamicParameters)obj).AddParameters(cmd, identity); } else if (exampleParameters is IEnumerable>) { @@ -2087,7 +1711,6 @@ private static CacheInfo GetCacheInfo(Identity identity, object exampleParameter if ((identity.commandType == null || identity.commandType == CommandType.Text) && ShouldPassByPosition(identity.sql)) { var tail = reader; - var sql = identity.sql; reader = (cmd, obj) => { tail(cmd, obj); @@ -2103,30 +1726,29 @@ private static CacheInfo GetCacheInfo(Identity identity, object exampleParameter private static bool ShouldPassByPosition(string sql) { - return sql != null && sql.IndexOf('?') >= 0 && pseudoPositional.IsMatch(sql); + return sql?.IndexOf('?') >= 0 && pseudoPositional.IsMatch(sql); } private static void PassByPosition(IDbCommand cmd) { if (cmd.Parameters.Count == 0) return; - Dictionary parameters = new Dictionary(StringComparer.InvariantCulture); + Dictionary parameters = new Dictionary(StringComparer.Ordinal); foreach (IDbDataParameter param in cmd.Parameters) { if (!string.IsNullOrEmpty(param.ParameterName)) parameters[param.ParameterName] = param; } - HashSet consumed = new HashSet(StringComparer.InvariantCulture); + HashSet consumed = new HashSet(StringComparer.Ordinal); bool firstMatch = true; cmd.CommandText = pseudoPositional.Replace(cmd.CommandText, match => { string key = match.Groups[1].Value; - IDbDataParameter param; if (!consumed.Add(key)) { throw new InvalidOperationException("When passing parameters by position, each parameter can only be referenced once"); } - else if (parameters.TryGetValue(key, out param)) + else if (parameters.TryGetValue(key, out IDbDataParameter param)) { if (firstMatch) { @@ -2149,25 +1771,16 @@ private static void PassByPosition(IDbCommand cmd) private static Func GetDeserializer(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing) { -#if !CSHARP30 // dynamic is passed in as Object ... by c# design - if (type == typeof(object) - || type == typeof(DapperRow)) + if (type == typeof(object) || type == typeof(DapperRow)) { return GetDapperRowDeserializer(reader, startBound, length, returnNullIfFirstMissing); } -#else - if (type.IsAssignableFrom(typeof(Dictionary))) - { - return GetDictionaryDeserializer(reader, startBound, length, returnNullIfFirstMissing); - } -#endif Type underlyingType = null; - if (!(typeMap.ContainsKey(type) || type.IsEnum || type.FullName == LinqBinary || - (type.IsValueType && (underlyingType = Nullable.GetUnderlyingType(type)) != null && underlyingType.IsEnum))) + if (!(typeMap.ContainsKey(type) || type.IsEnum || type.FullName == LinqBinary + || (type.IsValueType && (underlyingType = Nullable.GetUnderlyingType(type)) != null && underlyingType.IsEnum))) { - ITypeHandler handler; - if (typeHandlers.TryGetValue(type, out handler)) + if (typeHandlers.TryGetValue(type, out ITypeHandler handler)) { return GetHandlerDeserializer(handler, type, startBound); } @@ -2175,357 +1788,23 @@ private static Func GetDeserializer(Type type, IDataReader } return GetStructDeserializer(type, underlyingType ?? type, startBound); } - static Func GetHandlerDeserializer(ITypeHandler handler, Type type, int startBound) - { - return (IDataReader reader) => - handler.Parse(type, reader.GetValue(startBound)); - } - -#if !CSHARP30 - private sealed partial class DapperTable - { - string[] fieldNames; - readonly Dictionary fieldNameLookup; - - internal string[] FieldNames { get { return fieldNames; } } - - public DapperTable(string[] fieldNames) - { - if (fieldNames == null) throw new ArgumentNullException("fieldNames"); - this.fieldNames = fieldNames; - - fieldNameLookup = new Dictionary(fieldNames.Length, StringComparer.Ordinal); - // if there are dups, we want the **first** key to be the "winner" - so iterate backwards - for (int i = fieldNames.Length - 1; i >= 0; i--) - { - string key = fieldNames[i]; - if (key != null) fieldNameLookup[key] = i; - } - } - - internal int IndexOfName(string name) - { - int result; - return (name != null && fieldNameLookup.TryGetValue(name, out result)) ? result : -1; - } - internal int AddField(string name) - { - if (name == null) throw new ArgumentNullException("name"); - if (fieldNameLookup.ContainsKey(name)) throw new InvalidOperationException("Field already exists: " + name); - int oldLen = fieldNames.Length; - Array.Resize(ref fieldNames, oldLen + 1); // yes, this is sub-optimal, but this is not the expected common case - fieldNames[oldLen] = name; - fieldNameLookup[name] = oldLen; - return oldLen; - } - - - internal bool FieldExists(string key) - { - return key != null && fieldNameLookup.ContainsKey(key); - } - - public int FieldCount { get { return fieldNames.Length; } } - } - sealed partial class DapperRowMetaObject : System.Dynamic.DynamicMetaObject + private static Func GetHandlerDeserializer(ITypeHandler handler, Type type, int startBound) { - static readonly MethodInfo getValueMethod = typeof(IDictionary).GetProperty("Item").GetGetMethod(); - static readonly MethodInfo setValueMethod = typeof(DapperRow).GetMethod("SetValue", new Type[] { typeof(string), typeof(object) }); - - public DapperRowMetaObject( - System.Linq.Expressions.Expression expression, - System.Dynamic.BindingRestrictions restrictions - ) - : base(expression, restrictions) - { - } - - public DapperRowMetaObject( - System.Linq.Expressions.Expression expression, - System.Dynamic.BindingRestrictions restrictions, - object value - ) - : base(expression, restrictions, value) - { - } - - System.Dynamic.DynamicMetaObject CallMethod( - MethodInfo method, - System.Linq.Expressions.Expression[] parameters - ) - { - var callMethod = new System.Dynamic.DynamicMetaObject( - System.Linq.Expressions.Expression.Call( - System.Linq.Expressions.Expression.Convert(Expression, LimitType), - method, - parameters), - System.Dynamic.BindingRestrictions.GetTypeRestriction(Expression, LimitType) - ); - return callMethod; - } - - public override System.Dynamic.DynamicMetaObject BindGetMember(System.Dynamic.GetMemberBinder binder) - { - var parameters = new System.Linq.Expressions.Expression[] - { - System.Linq.Expressions.Expression.Constant(binder.Name) - }; - - var callMethod = CallMethod(getValueMethod, parameters); - - return callMethod; - } - - // Needed for Visual basic dynamic support - public override System.Dynamic.DynamicMetaObject BindInvokeMember(System.Dynamic.InvokeMemberBinder binder, System.Dynamic.DynamicMetaObject[] args) - { - var parameters = new System.Linq.Expressions.Expression[] - { - System.Linq.Expressions.Expression.Constant(binder.Name) - }; - - var callMethod = CallMethod(getValueMethod, parameters); - - return callMethod; - } - - public override System.Dynamic.DynamicMetaObject BindSetMember(System.Dynamic.SetMemberBinder binder, System.Dynamic.DynamicMetaObject value) - { - var parameters = new System.Linq.Expressions.Expression[] - { - System.Linq.Expressions.Expression.Constant(binder.Name), - value.Expression, - }; - - var callMethod = CallMethod(setValueMethod, parameters); - - return callMethod; - } + return reader => handler.Parse(type, reader.GetValue(startBound)); } - private sealed partial class DapperRow - : System.Dynamic.IDynamicMetaObjectProvider - , IDictionary - { - readonly DapperTable table; - object[] values; - - public DapperRow(DapperTable table, object[] values) - { - if (table == null) throw new ArgumentNullException("table"); - if (values == null) throw new ArgumentNullException("values"); - this.table = table; - this.values = values; - } - private sealed class DeadValue - { - public static readonly DeadValue Default = new DeadValue(); - private DeadValue() { } - } - int ICollection>.Count - { - get - { - int count = 0; - for (int i = 0; i < values.Length; i++) - { - if (!(values[i] is DeadValue)) count++; - } - return count; - } - } - - public bool TryGetValue(string name, out object value) - { - var index = table.IndexOfName(name); - if (index < 0) - { // doesn't exist - value = null; - return false; - } - // exists, **even if** we don't have a value; consider table rows heterogeneous - value = index < values.Length ? values[index] : null; - if (value is DeadValue) - { // pretend it isn't here - value = null; - return false; - } - return true; - } - - public override string ToString() - { - var sb = new StringBuilder("{DapperRow"); - foreach (var kv in this) - { - var value = kv.Value; - sb.Append(", ").Append(kv.Key); - if (value != null) - { - sb.Append(" = '").Append(kv.Value).Append('\''); - } - else - { - sb.Append(" = NULL"); - } - } - - return sb.Append('}').ToString(); - } - - System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject( - System.Linq.Expressions.Expression parameter) - { - return new DapperRowMetaObject(parameter, System.Dynamic.BindingRestrictions.Empty, this); - } - - public IEnumerator> GetEnumerator() - { - var names = table.FieldNames; - for (var i = 0; i < names.Length; i++) - { - object value = i < values.Length ? values[i] : null; - if (!(value is DeadValue)) - { - yield return new KeyValuePair(names[i], value); - } - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #region Implementation of ICollection> - - void ICollection>.Add(KeyValuePair item) - { - IDictionary dic = this; - dic.Add(item.Key, item.Value); - } - - void ICollection>.Clear() - { // removes values for **this row**, but doesn't change the fundamental table - for (int i = 0; i < values.Length; i++) - values[i] = DeadValue.Default; - } - - bool ICollection>.Contains(KeyValuePair item) - { - object value; - return TryGetValue(item.Key, out value) && Equals(value, item.Value); - } - - void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) - { - foreach (var kv in this) - { - array[arrayIndex++] = kv; // if they didn't leave enough space; not our fault - } - } - - bool ICollection>.Remove(KeyValuePair item) - { - IDictionary dic = this; - return dic.Remove(item.Key); - } - - bool ICollection>.IsReadOnly - { - get { return false; } - } - - #endregion - - #region Implementation of IDictionary - - bool IDictionary.ContainsKey(string key) - { - int index = table.IndexOfName(key); - if (index < 0 || index >= values.Length || values[index] is DeadValue) return false; - return true; - } - - void IDictionary.Add(string key, object value) - { - SetValue(key, value, true); - } - - bool IDictionary.Remove(string key) - { - int index = table.IndexOfName(key); - if (index < 0 || index >= values.Length || values[index] is DeadValue) return false; - values[index] = DeadValue.Default; - return true; - } - - object IDictionary.this[string key] - { - get { object val; TryGetValue(key, out val); return val; } - set { SetValue(key, value, false); } - } - - public object SetValue(string key, object value) - { - return SetValue(key, value, false); - } - private object SetValue(string key, object value, bool isAdd) - { - if (key == null) throw new ArgumentNullException("key"); - int index = table.IndexOfName(key); - if (index < 0) - { - index = table.AddField(key); - } - else if (isAdd && index < values.Length && !(values[index] is DeadValue)) - { - // then semantically, this value already exists - throw new ArgumentException("An item with the same key has already been added", "key"); - } - int oldLength = values.Length; - if (oldLength <= index) - { - // we'll assume they're doing lots of things, and - // grow it to the full width of the table - Array.Resize(ref values, table.FieldCount); - for (int i = oldLength; i < values.Length; i++) - { - values[i] = DeadValue.Default; - } - } - return values[index] = value; - } - - ICollection IDictionary.Keys - { - get { return this.Select(kv => kv.Key).ToArray(); } - } - - ICollection IDictionary.Values - { - get { return this.Select(kv => kv.Value).ToArray(); } - } - - #endregion - } -#endif private static Exception MultiMapException(IDataRecord reader) { bool hasFields = false; - try - { - hasFields = reader != null && reader.FieldCount != 0; - } - catch { } + try { hasFields = reader != null && reader.FieldCount != 0; } + catch { /* don't throw when trying to throw */ } if (hasFields) return new ArgumentException("When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id", "splitOn"); else return new InvalidOperationException("No columns were selected"); } -#if !CSHARP30 internal static Func GetDapperRowDeserializer(IDataRecord reader, int startBound, int length, bool returnNullIfFirstMissing) { var fieldCount = reader.FieldCount; @@ -2569,9 +1848,11 @@ internal static Func GetDapperRowDeserializer(IDataRecord r if (startBound == 0) { - r.GetValues(values); for (int i = 0; i < values.Length; i++) - if (values[i] is DBNull) values[i] = null; + { + object val = r.GetValue(i); + values[i] = val is DBNull ? null : val; + } } else { @@ -2585,72 +1866,45 @@ internal static Func GetDapperRowDeserializer(IDataRecord r return new DapperRow(table, values); }; } -#else - internal static Func GetDictionaryDeserializer(IDataRecord reader, int startBound, int length, bool returnNullIfFirstMissing) - { - var fieldCount = reader.FieldCount; - if (length == -1) - { - length = fieldCount - startBound; - } - - if (fieldCount <= startBound) - { - throw MultiMapException(reader); - } - - return - r => - { - IDictionary row = new Dictionary(length); - for (var i = startBound; i < startBound + length; i++) - { - var tmp = r.GetValue(i); - tmp = tmp == DBNull.Value ? null : tmp; - row[r.GetName(i)] = tmp; - if (returnNullIfFirstMissing && i == startBound && tmp == null) - { - return null; - } - } - return row; - }; - } -#endif /// - /// Internal use only + /// Internal use only. /// - /// - /// - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This method is for internal usage only", false)] + /// The object to convert to a character. + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete(ObsoleteInternalUsageOnly, false)] public static char ReadChar(object value) { - if (value == null || value is DBNull) throw new ArgumentNullException("value"); - string s = value as string; - if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", "value"); - return s[0]; + if (value == null || value is DBNull) throw new ArgumentNullException(nameof(value)); + if (value is string s && s.Length == 1) return s[0]; + if (value is char c) return c; + throw new ArgumentException("A single-character was expected", nameof(value)); } /// - /// Internal use only + /// Internal use only. /// - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This method is for internal usage only", false)] + /// The object to convert to a character. + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete(ObsoleteInternalUsageOnly, false)] public static char? ReadNullableChar(object value) { if (value == null || value is DBNull) return null; - string s = value as string; - if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", "value"); - return s[0]; + if (value is string s && s.Length == 1) return s[0]; + if (value is char c) return c; + throw new ArgumentException("A single-character was expected", nameof(value)); } - /// - /// Internal use only + /// Internal use only. /// - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This method is for internal usage only", true)] + /// The parameter collection to search in. + /// The command for this fetch. + /// The name of the parameter to get. + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete(ObsoleteInternalUsageOnly, true)] public static IDbDataParameter FindOrAddParameter(IDataParameterCollection parameters, IDbCommand command, string name) { IDbDataParameter result; @@ -2667,11 +1921,46 @@ public static IDbDataParameter FindOrAddParameter(IDataParameterCollection param return result; } - /// - /// Internal use only + internal static int GetListPaddingExtraCount(int count) + { + switch (count) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + return 0; // no padding + } + if (count < 0) return 0; + + int padFactor; + if (count <= 150) padFactor = 10; + else if (count <= 750) padFactor = 50; + else if (count <= 2000) padFactor = 100; // note: max param count for SQL Server + else if (count <= 2070) padFactor = 10; // try not to over-pad as we approach that limit + else if (count <= 2100) return 0; // just don't pad between 2070 and 2100, to minimize the crazy + else padFactor = 200; // above that, all bets are off! + + // if we have 17, factor = 10; 17 % 10 = 7, we need 3 more + int intoBlock = count % padFactor; + return intoBlock == 0 ? 0 : (padFactor - intoBlock); + } + + private static string GetInListRegex(string name, bool byPosition) => byPosition + ? (@"(\?)" + Regex.Escape(name) + @"\?(?!\w)(\s+(?i)unknown(?-i))?") + : ("([?@:]" + Regex.Escape(name) + @")(?!\w)(\s+(?i)unknown(?-i))?"); + + /// + /// Internal use only. /// - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This method is for internal usage only", false)] + /// The command to pack parameters for. + /// The name prefix for these parameters. + /// The parameter value can be an + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete(ObsoleteInternalUsageOnly, false)] public static void PackListParameters(IDbCommand command, string namePrefix, object value) { // initially we tried TVP, however it performs quite poorly. @@ -2680,131 +1969,275 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj if (FeatureSupport.Get(command.Connection).Arrays) { var arrayParm = command.CreateParameter(); - arrayParm.Value = value ?? DBNull.Value; + arrayParm.Value = SanitizeParameterValue(value); arrayParm.ParameterName = namePrefix; command.Parameters.Add(arrayParm); } else { + bool byPosition = ShouldPassByPosition(command.CommandText); var list = value as IEnumerable; var count = 0; bool isString = value is IEnumerable; bool isDbString = value is IEnumerable; - foreach (var item in list) + DbType dbType = 0; + + int splitAt = SqlMapper.Settings.InListStringSplitCount; + bool viaSplit = splitAt >= 0 + && TryStringSplit(ref list, splitAt, namePrefix, command, byPosition); + + if (list != null && !viaSplit) { - count++; - var listParam = command.CreateParameter(); - listParam.ParameterName = namePrefix + count; - if (isString) + object lastValue = null; + foreach (var item in list) { - listParam.Size = DbString.DefaultLength; - if (item != null && ((string)item).Length > DbString.DefaultLength) + if (++count == 1) // first item: fetch some type info { - listParam.Size = -1; + if (item == null) + { + throw new NotSupportedException("The first item in a list-expansion cannot be null"); + } + if (!isDbString) + { + dbType = LookupDbType(item.GetType(), "", true, out ITypeHandler handler); + } + } + var nextName = namePrefix + count.ToString(); + if (isDbString && item is DbString) + { + var str = item as DbString; + str.AddParameter(command, nextName); + } + else + { + var listParam = command.CreateParameter(); + listParam.ParameterName = nextName; + if (isString) + { + listParam.Size = DbString.DefaultLength; + if (item != null && ((string)item).Length > DbString.DefaultLength) + { + listParam.Size = -1; + } + } + + var tmp = listParam.Value = SanitizeParameterValue(item); + if (tmp != null && !(tmp is DBNull)) + lastValue = tmp; // only interested in non-trivial values for padding + + if (listParam.DbType != dbType) + { + listParam.DbType = dbType; + } + command.Parameters.Add(listParam); } } - if (isDbString && item as DbString != null) - { - var str = item as DbString; - str.AddParameter(command, listParam.ParameterName); - } - else + if (Settings.PadListExpansions && !isDbString && lastValue != null) { - listParam.Value = item ?? DBNull.Value; - command.Parameters.Add(listParam); + int padCount = GetListPaddingExtraCount(count); + for (int i = 0; i < padCount; i++) + { + count++; + var padParam = command.CreateParameter(); + padParam.ParameterName = namePrefix + count.ToString(); + if (isString) padParam.Size = DbString.DefaultLength; + padParam.DbType = dbType; + padParam.Value = lastValue; + command.Parameters.Add(padParam); + } } } - var regexIncludingUnknown = @"([?@:]" + Regex.Escape(namePrefix) + @")(\s+(?i)unknown(?-i))?"; - if (count == 0) + if (viaSplit) { - command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match => - { - var variableName = match.Groups[1].Value; - if (match.Groups[2].Success) - { - // looks like an optimize hint; leave it alone! - return match.Value; - } - else - { - return "(SELECT " + variableName + " WHERE 1 = 0)"; - } - }); - var dummyParam = command.CreateParameter(); - dummyParam.ParameterName = namePrefix; - dummyParam.Value = DBNull.Value; - command.Parameters.Add(dummyParam); + // already done } else { - command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match => + var regexIncludingUnknown = GetInListRegex(namePrefix, byPosition); + if (count == 0) { - var variableName = match.Groups[1].Value; - if (match.Groups[2].Success) + command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match => { - // looks like an optimize hint; expand it - var suffix = match.Groups[2].Value; - - var sb = new StringBuilder(variableName).Append(1).Append(suffix); - for (int i = 2; i <= count; i++) + var variableName = match.Groups[1].Value; + if (match.Groups[2].Success) { - sb.Append(',').Append(variableName).Append(i).Append(suffix); + // looks like an optimize hint; leave it alone! + return match.Value; } - return sb.ToString(); - } - else + else + { + return "(SELECT " + variableName + " WHERE 1 = 0)"; + } + }, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant); + var dummyParam = command.CreateParameter(); + dummyParam.ParameterName = namePrefix; + dummyParam.Value = DBNull.Value; + command.Parameters.Add(dummyParam); + } + else + { + command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match => { - var sb = new StringBuilder("(").Append(variableName).Append(1); - for (int i = 2; i <= count; i++) + var variableName = match.Groups[1].Value; + if (match.Groups[2].Success) + { + // looks like an optimize hint; expand it + var suffix = match.Groups[2].Value; + + var sb = GetStringBuilder().Append(variableName).Append(1).Append(suffix); + for (int i = 2; i <= count; i++) + { + sb.Append(',').Append(variableName).Append(i).Append(suffix); + } + return sb.__ToStringRecycle(); + } + else { - sb.Append(',').Append(variableName).Append(i); + var sb = GetStringBuilder().Append('(').Append(variableName); + if (!byPosition) sb.Append(1); else sb.Append(namePrefix).Append(1).Append(variableName); + for (int i = 2; i <= count; i++) + { + sb.Append(',').Append(variableName); + if (!byPosition) sb.Append(i); else sb.Append(namePrefix).Append(i).Append(variableName); + } + return sb.Append(')').__ToStringRecycle(); } - return sb.Append(')').ToString(); - } - }); + }, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant); + } } } - } - private static IEnumerable FilterParameters(IEnumerable parameters, string sql) + private static bool TryStringSplit(ref IEnumerable list, int splitAt, string namePrefix, IDbCommand command, bool byPosition) { - return parameters.Where(p => Regex.IsMatch(sql, @"[?@:]" + p.Name + "([^a-z0-9_]+|$)", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant)); + if (list == null || splitAt < 0) return false; + switch (list) + { + case IEnumerable l: + return TryStringSplit(ref l, splitAt, namePrefix, command, "int", byPosition, (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); + case IEnumerable l: + return TryStringSplit(ref l, splitAt, namePrefix, command, "bigint", byPosition, (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); + case IEnumerable l: + return TryStringSplit(ref l, splitAt, namePrefix, command, "smallint", byPosition, (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); + case IEnumerable l: + return TryStringSplit(ref l, splitAt, namePrefix, command, "tinyint", byPosition, (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); + } + return false; } - // look for ? / @ / : *by itself* - static readonly Regex smellsLikeOleDb = new Regex(@"(?(ref IEnumerable list, int splitAt, string namePrefix, IDbCommand command, string colType, bool byPosition, + Action append) + { + var typed = list as ICollection; + if (typed == null) + { + typed = list.ToList(); + list = typed; // because we still need to be able to iterate it, even if we fail here + } + if (typed.Count < splitAt) return false; + + string varName = null; + var regexIncludingUnknown = GetInListRegex(namePrefix, byPosition); + var sql = Regex.Replace(command.CommandText, regexIncludingUnknown, match => + { + var variableName = match.Groups[1].Value; + if (match.Groups[2].Success) + { + // looks like an optimize hint; leave it alone! + return match.Value; + } + else + { + varName = variableName; + return "(select cast([value] as " + colType + ") from string_split(" + variableName + ",','))"; + } + }, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant); + if (varName == null) return false; // couldn't resolve the var! + + command.CommandText = sql; + var concatenatedParam = command.CreateParameter(); + concatenatedParam.ParameterName = namePrefix; + concatenatedParam.DbType = DbType.AnsiString; + concatenatedParam.Size = -1; + string val; + using (var iter = typed.GetEnumerator()) + { + if (iter.MoveNext()) + { + var sb = GetStringBuilder(); + append(sb, iter.Current); + while (iter.MoveNext()) + { + append(sb.Append(','), iter.Current); + } + val = sb.ToString(); + } + else + { + val = ""; + } + } + concatenatedParam.Value = val; + command.Parameters.Add(concatenatedParam); + return true; + } /// - /// Represents a placeholder for a value that should be replaced as a literal value in the resulting sql + /// OBSOLETE: For internal usage only. Sanitizes the paramter value with proper type casting. /// - internal struct LiteralToken + /// The value to sanitize. + [Obsolete(ObsoleteInternalUsageOnly, false)] + public static object SanitizeParameterValue(object value) { - private readonly string token, member; - /// - /// The text in the original command that should be replaced - /// - public string Token { get { return token; } } - - /// - /// The name of the member referred to by the token - /// - public string Member { get { return member; } } - internal LiteralToken(string token, string member) + if (value == null) return DBNull.Value; + if (value is Enum) { - this.token = token; - this.member = member; + TypeCode typeCode; + if (value is IConvertible) + { + typeCode = ((IConvertible)value).GetTypeCode(); + } + else + { + typeCode = Type.GetTypeCode(Enum.GetUnderlyingType(value.GetType())); + } + switch (typeCode) + { + case TypeCode.Byte: return (byte)value; + case TypeCode.SByte: return (sbyte)value; + case TypeCode.Int16: return (short)value; + case TypeCode.Int32: return (int)value; + case TypeCode.Int64: return (long)value; + case TypeCode.UInt16: return (ushort)value; + case TypeCode.UInt32: return (uint)value; + case TypeCode.UInt64: return (ulong)value; + } } + return value; + } - internal static readonly IList None = new LiteralToken[0]; + private static IEnumerable FilterParameters(IEnumerable parameters, string sql) + { + var list = new List(16); + foreach (var p in parameters) + { + if (Regex.IsMatch(sql, @"[?@:]" + p.Name + @"([^\p{L}\p{N}_]+|$)", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant)) + list.Add(p); + } + return list; } + // look for ? / @ / : *by itself* + private static readonly Regex smellsLikeOleDb = new Regex(@"(? - /// Replace all literal tokens with their text form + /// Replace all literal tokens with their text form. /// + /// The parameter lookup to do replacements with. + /// The command to repalce parameters in. public static void ReplaceLiterals(this IParameterLookup parameters, IDbCommand command) { var tokens = GetLiteralTokens(command.CommandText); @@ -2812,10 +2245,12 @@ public static void ReplaceLiterals(this IParameterLookup parameters, IDbCommand } internal static readonly MethodInfo format = typeof(SqlMapper).GetMethod("Format", BindingFlags.Public | BindingFlags.Static); + /// - /// Convert numeric values to their string form for SQL literal purposes + /// Convert numeric values to their string form for SQL literal purposes. /// - [Obsolete("This is intended for internal usage only")] + /// The value to get a string for. + [Obsolete(ObsoleteInternalUsageOnly)] public static string Format(object value) { if (value == null) @@ -2856,12 +2291,20 @@ public static string Format(object value) var multiExec = GetMultiExec(value); if (multiExec != null) { - var sb = new StringBuilder(); + StringBuilder sb = null; bool first = true; foreach (object subval in multiExec) { - sb.Append(first ? '(' : ',').Append(Format(subval)); - first = false; + if (first) + { + sb = GetStringBuilder().Append('('); + first = false; + } + else + { + sb.Append(','); + } + sb.Append(Format(subval)); } if (first) { @@ -2869,15 +2312,14 @@ public static string Format(object value) } else { - return sb.Append(')').ToString(); + return sb.Append(')').__ToStringRecycle(); } } - throw new NotSupportedException(value.GetType().Name); + throw new NotSupportedException($"The type '{value.GetType().Name}' is not supported for SQL literals."); } } } - internal static void ReplaceLiterals(IParameterLookup parameters, IDbCommand command, IList tokens) { var sql = command.CommandText; @@ -2898,7 +2340,7 @@ internal static IList GetLiteralTokens(string sql) if (!literalTokens.IsMatch(sql)) return LiteralToken.None; var matches = literalTokens.Matches(sql); - var found = new HashSet(StringComparer.InvariantCulture); + var found = new HashSet(StringComparer.Ordinal); List list = new List(matches.Count); foreach (Match match in matches) { @@ -2912,48 +2354,76 @@ internal static IList GetLiteralTokens(string sql) } /// - /// Internal use only + /// Internal use only. /// - public static Action CreateParamInfoGenerator(Identity identity, bool checkForDuplicates, bool removeUnused) - { - return CreateParamInfoGenerator(identity, checkForDuplicates, removeUnused, GetLiteralTokens(identity.sql)); - } + /// The identity of the generator. + /// Whether to check for duplicates. + /// Whether to remove unused parameters. + public static Action CreateParamInfoGenerator(Identity identity, bool checkForDuplicates, bool removeUnused) => + CreateParamInfoGenerator(identity, checkForDuplicates, removeUnused, GetLiteralTokens(identity.sql)); + + private static bool IsValueTuple(Type type) => type?.IsValueType == true && type.FullName.StartsWith("System.ValueTuple`", StringComparison.Ordinal); internal static Action CreateParamInfoGenerator(Identity identity, bool checkForDuplicates, bool removeUnused, IList literals) { Type type = identity.parametersType; + if (IsValueTuple(type)) + { + throw new NotSupportedException("ValueTuple should not be used for parameters - the language-level names are not available to use as parameter names, and it adds unnecessary boxing"); + } + bool filterParams = false; if (removeUnused && identity.commandType.GetValueOrDefault(CommandType.Text) == CommandType.Text) { filterParams = !smellsLikeOleDb.IsMatch(identity.sql); } - var dm = new DynamicMethod(string.Format("ParamInfo{0}", Guid.NewGuid()), null, new[] { typeof(IDbCommand), typeof(object) }, type, true); + var dm = new DynamicMethod("ParamInfo" + Guid.NewGuid().ToString(), null, new[] { typeof(IDbCommand), typeof(object) }, type, true); var il = dm.GetILGenerator(); - il.DeclareLocal(type); // 0 - bool haveInt32Arg1 = false; + bool isStruct = type.IsValueType; + var _sizeLocal = (LocalBuilder)null; + LocalBuilder GetSizeLocal() => _sizeLocal ?? (_sizeLocal = il.DeclareLocal(typeof(int))); il.Emit(OpCodes.Ldarg_1); // stack is now [untyped-param] - il.Emit(OpCodes.Unbox_Any, type); // stack is now [typed-param] - il.Emit(OpCodes.Stloc_0);// stack is now empty + + LocalBuilder typedParameterLocal; + if (isStruct) + { + typedParameterLocal = il.DeclareLocal(type.MakeByRefType()); // note: ref-local + il.Emit(OpCodes.Unbox, type); // stack is now [typed-param] + } + else + { + typedParameterLocal = il.DeclareLocal(type); + il.Emit(OpCodes.Castclass, type); // stack is now [typed-param] + } + il.Emit(OpCodes.Stloc, typedParameterLocal); // stack is now empty il.Emit(OpCodes.Ldarg_0); // stack is now [command] - il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetProperty("Parameters").GetGetMethod(), null); // stack is now [parameters] + il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetProperty(nameof(IDbCommand.Parameters)).GetGetMethod(), null); // stack is now [parameters] + + var allTypeProps = type.GetProperties(); + var propsList = new List(allTypeProps.Length); + for (int i = 0; i < allTypeProps.Length; ++i) + { + var p = allTypeProps[i]; + if (p.GetIndexParameters().Length == 0) + propsList.Add(p); + } - var propsArr = type.GetProperties().Where(p => p.GetIndexParameters().Length == 0).ToArray(); var ctors = type.GetConstructors(); ParameterInfo[] ctorParams; IEnumerable props = null; // try to detect tuple patterns, e.g. anon-types, and use that to choose the order // otherwise: alphabetical - if (ctors.Length == 1 && propsArr.Length == (ctorParams = ctors[0].GetParameters()).Length) + if (ctors.Length == 1 && propsList.Count == (ctorParams = ctors[0].GetParameters()).Length) { // check if reflection was kind enough to put everything in the right order for us bool ok = true; - for (int i = 0; i < propsArr.Length; i++) + for (int i = 0; i < propsList.Count; i++) { - if (!string.Equals(propsArr[i].Name, ctorParams[i].Name, StringComparison.InvariantCultureIgnoreCase)) + if (!string.Equals(propsList[i].Name, ctorParams[i].Name, StringComparison.OrdinalIgnoreCase)) { ok = false; break; @@ -2962,23 +2432,22 @@ internal static Action CreateParamInfoGenerator(Identity ide if (ok) { // pre-sorted; the reflection gods have smiled upon us - props = propsArr; + props = propsList; } else { // might still all be accounted for; check the hard way - var positionByName = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + var positionByName = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var param in ctorParams) { positionByName[param.Name] = param.Position; } - if (positionByName.Count == propsArr.Length) + if (positionByName.Count == propsList.Count) { - int[] positions = new int[propsArr.Length]; + int[] positions = new int[propsList.Count]; ok = true; - for (int i = 0; i < propsArr.Length; i++) + for (int i = 0; i < propsList.Count; i++) { - int pos; - if (!positionByName.TryGetValue(propsArr[i].Name, out pos)) + if (!positionByName.TryGetValue(propsList[i].Name, out int pos)) { ok = false; break; @@ -2987,43 +2456,49 @@ internal static Action CreateParamInfoGenerator(Identity ide } if (ok) { - Array.Sort(positions, propsArr); - props = propsArr; + props = propsList.ToArray(); + Array.Sort(positions, (PropertyInfo[])props); } } } } - if (props == null) props = propsArr.OrderBy(x => x.Name); + if (props == null) + { + propsList.Sort(new PropertyInfoByNameComparer()); + props = propsList; + } if (filterParams) { props = FilterParameters(props, identity.sql); } + var callOpCode = isStruct ? OpCodes.Call : OpCodes.Callvirt; foreach (var prop in props) { if (typeof(ICustomQueryParameter).IsAssignableFrom(prop.PropertyType)) { - il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [typed-param] - il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [custom] + il.Emit(OpCodes.Ldloc, typedParameterLocal); // stack is now [parameters] [typed-param] + il.Emit(callOpCode, prop.GetGetMethod()); // stack is [parameters] [custom] il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [custom] [command] il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [custom] [command] [name] - il.EmitCall(OpCodes.Callvirt, prop.PropertyType.GetMethod("AddParameter"), null); // stack is now [parameters] + il.EmitCall(OpCodes.Callvirt, prop.PropertyType.GetMethod(nameof(ICustomQueryParameter.AddParameter)), null); // stack is now [parameters] continue; } - ITypeHandler handler; - DbType dbType = LookupDbType(prop.PropertyType, prop.Name, true, out handler); +#pragma warning disable 618 + DbType dbType = LookupDbType(prop.PropertyType, prop.Name, true, out ITypeHandler handler); +#pragma warning restore 618 if (dbType == DynamicParameters.EnumerableMultiParameter) { // this actually represents special handling for list types; il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [command] il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [command] [name] - il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [command] [name] [typed-param] - il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [command] [name] [typed-value] + il.Emit(OpCodes.Ldloc, typedParameterLocal); // stack is now [parameters] [command] [name] [typed-param] + il.Emit(callOpCode, prop.GetGetMethod()); // stack is [parameters] [command] [name] [typed-value] if (prop.PropertyType.IsValueType) { il.Emit(OpCodes.Box, prop.PropertyType); // stack is [parameters] [command] [name] [boxed-value] } - il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod("PackListParameters"), null); // stack is [parameters] + il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod(nameof(SqlMapper.PackListParameters)), null); // stack is [parameters] continue; } il.Emit(OpCodes.Dup); // stack is now [parameters] [parameters] @@ -3034,16 +2509,16 @@ internal static Action CreateParamInfoGenerator(Identity ide { // need to be a little careful about adding; use a utility method il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [parameters] [command] [name] - il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod("FindOrAddParameter"), null); // stack is [parameters] [parameter] + il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod(nameof(SqlMapper.FindOrAddParameter)), null); // stack is [parameters] [parameter] } else { // no risk of duplicates; just blindly add - il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetMethod("CreateParameter"), null);// stack is now [parameters] [parameters] [parameter] + il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetMethod(nameof(IDbCommand.CreateParameter)), null);// stack is now [parameters] [parameters] [parameter] il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("ParameterName").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] + il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.ParameterName)).GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] } if (dbType != DbType.Time && handler == null) // https://connect.microsoft.com/VisualStudio/feedback/details/381934/sqlparameter-dbtype-dbtype-time-sets-the-parameter-to-sqldbtype-datetime-instead-of-sqldbtype-time { @@ -3051,41 +2526,75 @@ internal static Action CreateParamInfoGenerator(Identity ide if (dbType == DbType.Object && prop.PropertyType == typeof(object)) // includes dynamic { // look it up from the param value - il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [[parameters]] [parameter] [parameter] [typed-param] - il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [[parameters]] [parameter] [parameter] [object-value] - il.Emit(OpCodes.Call, typeof(SqlMapper).GetMethod("GetDbType", BindingFlags.Static | BindingFlags.Public)); // stack is now [parameters] [[parameters]] [parameter] [parameter] [db-type] + il.Emit(OpCodes.Ldloc, typedParameterLocal); // stack is now [parameters] [[parameters]] [parameter] [parameter] [typed-param] + il.Emit(callOpCode, prop.GetGetMethod()); // stack is [parameters] [[parameters]] [parameter] [parameter] [object-value] + il.Emit(OpCodes.Call, typeof(SqlMapper).GetMethod(nameof(SqlMapper.GetDbType), BindingFlags.Static | BindingFlags.Public)); // stack is now [parameters] [[parameters]] [parameter] [parameter] [db-type] } else { // constant value; nice and simple EmitInt32(il, (int)dbType);// stack is now [parameters] [[parameters]] [parameter] [parameter] [db-type] } - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("DbType").GetSetMethod(), null);// stack is now [parameters] [[parameters]] [parameter] + il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.DbType)).GetSetMethod(), null);// stack is now [parameters] [[parameters]] [parameter] } il.Emit(OpCodes.Dup);// stack is now [parameters] [[parameters]] [parameter] [parameter] EmitInt32(il, (int)ParameterDirection.Input);// stack is now [parameters] [[parameters]] [parameter] [parameter] [dir] - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("Direction").GetSetMethod(), null);// stack is now [parameters] [[parameters]] [parameter] + il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Direction)).GetSetMethod(), null);// stack is now [parameters] [[parameters]] [parameter] il.Emit(OpCodes.Dup);// stack is now [parameters] [[parameters]] [parameter] [parameter] - il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [[parameters]] [parameter] [parameter] [typed-param] - il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [[parameters]] [parameter] [parameter] [typed-value] - bool checkForNull = true; + il.Emit(OpCodes.Ldloc, typedParameterLocal); // stack is now [parameters] [[parameters]] [parameter] [parameter] [typed-param] + il.Emit(callOpCode, prop.GetGetMethod()); // stack is [parameters] [[parameters]] [parameter] [parameter] [typed-value] + bool checkForNull; if (prop.PropertyType.IsValueType) { - il.Emit(OpCodes.Box, prop.PropertyType); // stack is [parameters] [[parameters]] [parameter] [parameter] [boxed-value] - if (Nullable.GetUnderlyingType(prop.PropertyType) == null) - { // struct but not Nullable; boxed value cannot be null - checkForNull = false; + var propType = prop.PropertyType; + var nullType = Nullable.GetUnderlyingType(propType); + bool callSanitize = false; + + if ((nullType ?? propType).IsEnum) + { + if (nullType != null) + { + // Nullable; we want to box as the underlying type; that's just *hard*; for + // simplicity, box as Nullable and call SanitizeParameterValue + callSanitize = checkForNull = true; + } + else + { + checkForNull = false; + // non-nullable enum; we can do that! just box to the wrong type! (no, really) + switch (Type.GetTypeCode(Enum.GetUnderlyingType(propType))) + { + case TypeCode.Byte: propType = typeof(byte); break; + case TypeCode.SByte: propType = typeof(sbyte); break; + case TypeCode.Int16: propType = typeof(short); break; + case TypeCode.Int32: propType = typeof(int); break; + case TypeCode.Int64: propType = typeof(long); break; + case TypeCode.UInt16: propType = typeof(ushort); break; + case TypeCode.UInt32: propType = typeof(uint); break; + case TypeCode.UInt64: propType = typeof(ulong); break; + } + } + } + else + { + checkForNull = nullType != null; + } + il.Emit(OpCodes.Box, propType); // stack is [parameters] [[parameters]] [parameter] [parameter] [boxed-value] + if (callSanitize) + { + checkForNull = false; // handled by sanitize + il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod(nameof(SanitizeParameterValue)), null); + // stack is [parameters] [[parameters]] [parameter] [parameter] [boxed-value] } } + else + { + checkForNull = true; // if not a value-type, need to check + } if (checkForNull) { - if ((dbType == DbType.String || dbType == DbType.AnsiString) && !haveInt32Arg1) - { - il.DeclareLocal(typeof(int)); - haveInt32Arg1 = true; - } // relative stack: [boxed value] il.Emit(OpCodes.Dup);// relative stack: [boxed value] [boxed value] Label notNull = il.DefineLabel(); @@ -3093,18 +2602,18 @@ internal static Action CreateParamInfoGenerator(Identity ide il.Emit(OpCodes.Brtrue_S, notNull); // relative stack [boxed value = null] il.Emit(OpCodes.Pop); // relative stack empty - il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value")); // relative stack [DBNull] + il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField(nameof(DBNull.Value))); // relative stack [DBNull] if (dbType == DbType.String || dbType == DbType.AnsiString) { EmitInt32(il, 0); - il.Emit(OpCodes.Stloc_1); + il.Emit(OpCodes.Stloc, GetSizeLocal()); } if (allDone != null) il.Emit(OpCodes.Br_S, allDone.Value); il.MarkLabel(notNull); if (prop.PropertyType == typeof(string)) { il.Emit(OpCodes.Dup); // [string] [string] - il.EmitCall(OpCodes.Callvirt, typeof(string).GetProperty("Length").GetGetMethod(), null); // [string] [length] + il.EmitCall(OpCodes.Callvirt, typeof(string).GetProperty(nameof(string.Length)).GetGetMethod(), null); // [string] [length] EmitInt32(il, DbString.DefaultLength); // [string] [length] [4000] il.Emit(OpCodes.Cgt); // [string] [0 or 1] Label isLong = il.DefineLabel(), lenDone = il.DefineLabel(); @@ -3114,7 +2623,7 @@ internal static Action CreateParamInfoGenerator(Identity ide il.MarkLabel(isLong); EmitInt32(il, -1); // [string] [-1] il.MarkLabel(lenDone); - il.Emit(OpCodes.Stloc_1); // [string] + il.Emit(OpCodes.Stloc, GetSizeLocal()); // [string] } if (prop.PropertyType.FullName == LinqBinary) { @@ -3127,24 +2636,25 @@ internal static Action CreateParamInfoGenerator(Identity ide if (handler != null) { #pragma warning disable 618 - il.Emit(OpCodes.Call, typeof(TypeHandlerCache<>).MakeGenericType(prop.PropertyType).GetMethod("SetValue")); // stack is now [parameters] [[parameters]] [parameter] + il.Emit(OpCodes.Call, typeof(TypeHandlerCache<>).MakeGenericType(prop.PropertyType).GetMethod(nameof(TypeHandlerCache.SetValue))); // stack is now [parameters] [[parameters]] [parameter] #pragma warning restore 618 } else { - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("Value").GetSetMethod(), null);// stack is now [parameters] [[parameters]] [parameter] + il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);// stack is now [parameters] [[parameters]] [parameter] } if (prop.PropertyType == typeof(string)) { var endOfSize = il.DefineLabel(); + var sizeLocal = GetSizeLocal(); // don't set if 0 - il.Emit(OpCodes.Ldloc_1); // [parameters] [[parameters]] [parameter] [size] + il.Emit(OpCodes.Ldloc, sizeLocal); // [parameters] [[parameters]] [parameter] [size] il.Emit(OpCodes.Brfalse_S, endOfSize); // [parameters] [[parameters]] [parameter] il.Emit(OpCodes.Dup);// stack is now [parameters] [[parameters]] [parameter] [parameter] - il.Emit(OpCodes.Ldloc_1); // stack is now [parameters] [[parameters]] [parameter] [parameter] [size] - il.EmitCall(OpCodes.Callvirt, typeof(IDbDataParameter).GetProperty("Size").GetSetMethod(), null); // stack is now [parameters] [[parameters]] [parameter] + il.Emit(OpCodes.Ldloc, sizeLocal); // stack is now [parameters] [[parameters]] [parameter] [parameter] [size] + il.EmitCall(OpCodes.Callvirt, typeof(IDbDataParameter).GetProperty(nameof(IDbDataParameter.Size)).GetSetMethod(), null); // stack is now [parameters] [[parameters]] [parameter] il.MarkLabel(endOfSize); } @@ -3157,7 +2667,7 @@ internal static Action CreateParamInfoGenerator(Identity ide { // stack is now [parameters] [parameters] [parameter] // blindly add - il.EmitCall(OpCodes.Callvirt, typeof(IList).GetMethod("Add"), null); // stack is now [parameters] + il.EmitCall(OpCodes.Callvirt, typeof(IList).GetMethod(nameof(IList.Add)), null); // stack is now [parameters] il.Emit(OpCodes.Pop); // IList.Add returns the new index (int); we don't care } } @@ -3165,11 +2675,11 @@ internal static Action CreateParamInfoGenerator(Identity ide // stack is currently [parameters] il.Emit(OpCodes.Pop); // stack is now empty - if (literals.Count != 0 && propsArr != null) + if (literals.Count != 0 && propsList != null) { il.Emit(OpCodes.Ldarg_0); // command il.Emit(OpCodes.Ldarg_0); // command, command - var cmdText = typeof(IDbCommand).GetProperty("CommandText"); + var cmdText = typeof(IDbCommand).GetProperty(nameof(IDbCommand.CommandText)); il.EmitCall(OpCodes.Callvirt, cmdText.GetGetMethod(), null); // command, sql Dictionary locals = null; LocalBuilder local = null; @@ -3178,13 +2688,13 @@ internal static Action CreateParamInfoGenerator(Identity ide // find the best member, preferring case-sensitive PropertyInfo exact = null, fallback = null; string huntName = literal.Member; - for (int i = 0; i < propsArr.Length; i++) + for (int i = 0; i < propsList.Count; i++) { - string thisName = propsArr[i].Name; - if (string.Equals(thisName, huntName, StringComparison.InvariantCultureIgnoreCase)) + string thisName = propsList[i].Name; + if (string.Equals(thisName, huntName, StringComparison.OrdinalIgnoreCase)) { - fallback = propsArr[i]; - if (string.Equals(thisName, huntName, StringComparison.InvariantCulture)) + fallback = propsList[i]; + if (string.Equals(thisName, huntName, StringComparison.Ordinal)) { exact = fallback; break; @@ -3196,13 +2706,21 @@ internal static Action CreateParamInfoGenerator(Identity ide if (prop != null) { il.Emit(OpCodes.Ldstr, literal.Token); - il.Emit(OpCodes.Ldloc_0); // command, sql, typed parameter - il.EmitCall(OpCodes.Callvirt, prop.GetGetMethod(), null); // command, sql, typed value + il.Emit(OpCodes.Ldloc, typedParameterLocal); // command, sql, typed parameter + il.EmitCall(callOpCode, prop.GetGetMethod(), null); // command, sql, typed value Type propType = prop.PropertyType; var typeCode = Type.GetTypeCode(propType); switch (typeCode) { case TypeCode.Boolean: + Label ifTrue = il.DefineLabel(), allDone = il.DefineLabel(); + il.Emit(OpCodes.Brtrue_S, ifTrue); + il.Emit(OpCodes.Ldstr, "0"); + il.Emit(OpCodes.Br_S, allDone); + il.MarkLabel(ifTrue); + il.Emit(OpCodes.Ldstr, "1"); + il.MarkLabel(allDone); + break; case TypeCode.Byte: case TypeCode.SByte: case TypeCode.UInt16: @@ -3214,7 +2732,7 @@ internal static Action CreateParamInfoGenerator(Identity ide case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: - // neeed to stloc, ldloca, call + // need to stloc, ldloca, call // re-use existing locals (both the last known, and via a dictionary) var convert = GetToString(typeCode); if (local == null || local.LocalType != propType) @@ -3243,7 +2761,6 @@ internal static Action CreateParamInfoGenerator(Identity ide if (propType.IsValueType) il.Emit(OpCodes.Box, propType); // command, sql, object value il.EmitCall(OpCodes.Call, format, null); // command, sql, string value break; - } il.EmitCall(OpCodes.Callvirt, StringReplace, null); } @@ -3254,18 +2771,20 @@ internal static Action CreateParamInfoGenerator(Identity ide il.Emit(OpCodes.Ret); return (Action)dm.CreateDelegate(typeof(Action)); } - static readonly Dictionary toStrings = new[] + + private static readonly Dictionary toStrings = new[] { typeof(bool), typeof(sbyte), typeof(byte), typeof(ushort), typeof(short), typeof(uint), typeof(int), typeof(ulong), typeof(long), typeof(float), typeof(double), typeof(decimal) - }.ToDictionary(x => Type.GetTypeCode(x), x => x.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(IFormatProvider) }, null)); - static MethodInfo GetToString(TypeCode typeCode) + }.ToDictionary(x => Type.GetTypeCode(x), x => x.GetPublicInstanceMethod(nameof(object.ToString), new[] { typeof(IFormatProvider) })); + + private static MethodInfo GetToString(TypeCode typeCode) { - MethodInfo method; - return toStrings.TryGetValue(typeCode, out method) ? method : null; + return toStrings.TryGetValue(typeCode, out MethodInfo method) ? method : null; } - static readonly MethodInfo StringReplace = typeof(string).GetMethod("Replace", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(string), typeof(string) }, null), - InvariantCulture = typeof(CultureInfo).GetProperty("InvariantCulture", BindingFlags.Public | BindingFlags.Static).GetGetMethod(); + + private static readonly MethodInfo StringReplace = typeof(string).GetPublicInstanceMethod(nameof(string.Replace), new Type[] { typeof(string), typeof(string) }), + InvariantCulture = typeof(CultureInfo).GetProperty(nameof(CultureInfo.InvariantCulture), BindingFlags.Public | BindingFlags.Static).GetGetMethod(); private static int ExecuteCommand(IDbConnection cnn, ref CommandDefinition command, Action paramReader) { @@ -3282,7 +2801,7 @@ private static int ExecuteCommand(IDbConnection cnn, ref CommandDefinition comma finally { if (wasClosed) cnn.Close(); - if (cmd != null) cmd.Dispose(); + cmd?.Dispose(); } } @@ -3292,7 +2811,7 @@ private static T ExecuteScalarImpl(IDbConnection cnn, ref CommandDefinition c object param = command.Parameters; if (param != null) { - var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null); + var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType()); paramReader = GetCacheInfo(identity, command.Parameters, command.AddToCache).ParamReader; } @@ -3309,32 +2828,30 @@ private static T ExecuteScalarImpl(IDbConnection cnn, ref CommandDefinition c finally { if (wasClosed) cnn.Close(); - if (cmd != null) cmd.Dispose(); + cmd?.Dispose(); } return Parse(result); } - private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefinition command, CommandBehavior commandBehavior) + private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefinition command, CommandBehavior commandBehavior, out IDbCommand cmd) { Action paramReader = GetParameterReader(cnn, ref command); - - IDbCommand cmd = null; - bool wasClosed = cnn.State == ConnectionState.Closed; + cmd = null; + bool wasClosed = cnn.State == ConnectionState.Closed, disposeCommand = true; try { cmd = command.SetupCommand(cnn, paramReader); if (wasClosed) cnn.Open(); - if (wasClosed) commandBehavior |= CommandBehavior.CloseConnection; - var reader = cmd.ExecuteReader(commandBehavior); + var reader = ExecuteReaderWithFlagsFallback(cmd, wasClosed, commandBehavior); wasClosed = false; // don't dispose before giving it to them! - + disposeCommand = false; // note: command.FireOutputCallbacks(); would be useless here; parameters come at the **end** of the TDS stream return reader; } finally { if (wasClosed) cnn.Close(); - if (cmd != null) cmd.Dispose(); + if (cmd != null && disposeCommand) cmd.Dispose(); } } @@ -3342,7 +2859,6 @@ private static Action GetParameterReader(IDbConnection cnn, { object param = command.Parameters; IEnumerable multiExec = GetMultiExec(param); - Identity identity; CacheInfo info = null; if (multiExec != null) { @@ -3352,10 +2868,10 @@ private static Action GetParameterReader(IDbConnection cnn, // nice and simple if (param != null) { - identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null); + var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType()); info = GetCacheInfo(identity, param, command.AddToCache); } - var paramReader = info == null ? null : info.ParamReader; + var paramReader = info?.ParamReader; return paramReader; } @@ -3365,11 +2881,11 @@ private static Func GetStructDeserializer(Type type, Type e #pragma warning disable 618 if (type == typeof(char)) { // this *does* need special handling, though - return r => SqlMapper.ReadChar(r.GetValue(index)); + return r => ReadChar(r.GetValue(index)); } if (type == typeof(char?)) { - return r => SqlMapper.ReadNullableChar(r.GetValue(index)); + return r => ReadNullableChar(r.GetValue(index)); } if (type.FullName == LinqBinary) { @@ -3389,8 +2905,7 @@ private static Func GetStructDeserializer(Type type, Type e return val is DBNull ? null : Enum.ToObject(effectiveType, val); }; } - ITypeHandler handler; - if (typeHandlers.TryGetValue(type, out handler)) + if (typeHandlers.TryGetValue(type, out ITypeHandler handler)) { return r => { @@ -3419,27 +2934,33 @@ private static T Parse(object value) } return (T)Enum.ToObject(type, value); } - ITypeHandler handler; - if (typeHandlers.TryGetValue(type, out handler)) + if (typeHandlers.TryGetValue(type, out ITypeHandler handler)) { return (T)handler.Parse(type, value); } return (T)Convert.ChangeType(value, type, CultureInfo.InvariantCulture); } - static readonly MethodInfo - enumParse = typeof(Enum).GetMethod("Parse", new Type[] { typeof(Type), typeof(string), typeof(bool) }), + private static readonly MethodInfo + enumParse = typeof(Enum).GetMethod(nameof(Enum.Parse), new Type[] { typeof(Type), typeof(string), typeof(bool) }), getItem = typeof(IDataRecord).GetProperties(BindingFlags.Instance | BindingFlags.Public) - .Where(p => p.GetIndexParameters().Any() && p.GetIndexParameters()[0].ParameterType == typeof(int)) + .Where(p => p.GetIndexParameters().Length > 0 && p.GetIndexParameters()[0].ParameterType == typeof(int)) .Select(p => p.GetGetMethod()).First(); /// /// Gets type-map for the given type /// + /// Type map instance, default is to create new instance of DefaultTypeMap + public static Func TypeMapProvider = (Type type) => new DefaultTypeMap(type); + + /// + /// Gets type-map for the given . + /// + /// The type to get a map for. /// Type map implementation, DefaultTypeMap instance if no override present public static ITypeMap GetTypeMap(Type type) { - if (type == null) throw new ArgumentNullException("type"); + if (type == null) throw new ArgumentNullException(nameof(type)); var map = (ITypeMap)_typeMaps[type]; if (map == null) { @@ -3447,9 +2968,10 @@ public static ITypeMap GetTypeMap(Type type) { // double-checked; store this to avoid reflection next time we see this type // since multiple queries commonly use the same domain-entity/DTO/view-model type map = (ITypeMap)_typeMaps[type]; + if (map == null) { - map = new DefaultTypeMap(type); + map = TypeMapProvider(type); _typeMaps[type] = map; } } @@ -3468,7 +2990,7 @@ public static ITypeMap GetTypeMap(Type type) public static void SetTypeMap(Type type, ITypeMap map) { if (type == null) - throw new ArgumentNullException("type"); + throw new ArgumentNullException(nameof(type)); if (map == null || map is DefaultTypeMap) { @@ -3498,21 +3020,35 @@ public static void SetTypeMap(Type type, ITypeMap map) /// /// public static Func GetTypeDeserializer( -#if CSHARP30 -Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing -#else -Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false -#endif -) + Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false + ) { + return TypeDeserializerCache.GetReader(type, reader, startBound, length, returnNullIfFirstMissing); + } - var dm = new DynamicMethod(string.Format("Deserialize{0}", Guid.NewGuid()), typeof(object), new[] { typeof(IDataReader) }, true); - var il = dm.GetILGenerator(); - il.DeclareLocal(typeof(int)); - il.DeclareLocal(type); - il.Emit(OpCodes.Ldc_I4_0); - il.Emit(OpCodes.Stloc_0); + private static LocalBuilder GetTempLocal(ILGenerator il, ref Dictionary locals, Type type, bool initAndLoad) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + locals = locals ?? new Dictionary(); + if (!locals.TryGetValue(type, out LocalBuilder found)) + { + found = il.DeclareLocal(type); + locals.Add(type, found); + } + if (initAndLoad) + { + il.Emit(OpCodes.Ldloca, found); + il.Emit(OpCodes.Initobj, type); + il.Emit(OpCodes.Ldloca, found); + il.Emit(OpCodes.Ldobj, type); + } + return found; + } + private static Func GetTypeDeserializerImpl( + Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false + ) + { if (length == -1) { length = reader.FieldCount - startBound; @@ -3523,18 +3059,133 @@ public static Func GetTypeDeserializer( throw MultiMapException(reader); } + var returnType = type.IsValueType ? typeof(object) : type; + var dm = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString(), returnType, new[] { typeof(IDataReader) }, type, true); + var il = dm.GetILGenerator(); + + if (IsValueTuple(type)) + { + GenerateValueTupleDeserializer(type, reader, startBound, length, il); + } + else + { + GenerateDeserializerFromMap(type, reader, startBound, length, returnNullIfFirstMissing, il); + } + + var funcType = System.Linq.Expressions.Expression.GetFuncType(typeof(IDataReader), returnType); + return (Func)dm.CreateDelegate(funcType); + } + + private static void GenerateValueTupleDeserializer(Type valueTupleType, IDataReader reader, int startBound, int length, ILGenerator il) + { + var currentValueTupleType = valueTupleType; + + var constructors = new List(); + var languageTupleElementTypes = new List(); + + while (true) + { + var arity = int.Parse(currentValueTupleType.Name.Substring("ValueTuple`".Length), CultureInfo.InvariantCulture); + var constructorParameterTypes = new Type[arity]; + var restField = (FieldInfo)null; + + foreach (var field in currentValueTupleType.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + { + if (field.Name == "Rest") + { + restField = field; + } + else if (field.Name.StartsWith("Item", StringComparison.Ordinal)) + { + var elementNumber = int.Parse(field.Name.Substring("Item".Length), CultureInfo.InvariantCulture); + constructorParameterTypes[elementNumber - 1] = field.FieldType; + } + } + + var itemFieldCount = constructorParameterTypes.Length; + if (restField != null) itemFieldCount--; + + for (var i = 0; i < itemFieldCount; i++) + { + languageTupleElementTypes.Add(constructorParameterTypes[i]); + } + + if (restField != null) + { + constructorParameterTypes[constructorParameterTypes.Length - 1] = restField.FieldType; + } + + constructors.Add(currentValueTupleType.GetConstructor(constructorParameterTypes)); + + if (restField is null) break; + + currentValueTupleType = restField.FieldType; + if (!IsValueTuple(currentValueTupleType)) + { + throw new InvalidOperationException("The Rest field of a ValueTuple must contain a nested ValueTuple of arity 1 or greater."); + } + } + + var stringEnumLocal = (LocalBuilder)null; + + for (var i = 0; i < languageTupleElementTypes.Count; i++) + { + var targetType = languageTupleElementTypes[i]; + + if (i < length) + { + LoadReaderValueOrBranchToDBNullLabel( + il, + startBound + i, + ref stringEnumLocal, + valueCopyLocal: null, + reader.GetFieldType(startBound + i), + targetType, + out var isDbNullLabel); + + var finishLabel = il.DefineLabel(); + il.Emit(OpCodes.Br_S, finishLabel); + il.MarkLabel(isDbNullLabel); + il.Emit(OpCodes.Pop); + + LoadDefaultValue(il, targetType); + + il.MarkLabel(finishLabel); + } + else + { + LoadDefaultValue(il, targetType); + } + } + + for (var i = constructors.Count - 1; i >= 0; i--) + { + il.Emit(OpCodes.Newobj, constructors[i]); + } + + il.Emit(OpCodes.Box, valueTupleType); + il.Emit(OpCodes.Ret); + } + + private static void GenerateDeserializerFromMap(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing, ILGenerator il) + { + var currentIndexDiagnosticLocal = il.DeclareLocal(typeof(int)); + var returnValueLocal = il.DeclareLocal(type); + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Stloc, currentIndexDiagnosticLocal); + var names = Enumerable.Range(startBound, length).Select(i => reader.GetName(i)).ToArray(); ITypeMap typeMap = GetTypeMap(type); int index = startBound; - ConstructorInfo specializedConstructor = null; bool supportInitialize = false; + Dictionary structLocals = null; if (type.IsValueType) { - il.Emit(OpCodes.Ldloca_S, (byte)1); + il.Emit(OpCodes.Ldloca, returnValueLocal); il.Emit(OpCodes.Initobj, type); } else @@ -3545,36 +3196,66 @@ public static Func GetTypeDeserializer( types[i - startBound] = reader.GetFieldType(i); } - var ctor = typeMap.FindConstructor(names, types); - if (ctor == null) + var explicitConstr = typeMap.FindExplicitConstructor(); + if (explicitConstr != null) { - string proposedTypes = "(" + string.Join(", ", types.Select((t, i) => t.FullName + " " + names[i]).ToArray()) + ")"; - throw new InvalidOperationException(string.Format("A parameterless default constructor or one matching signature {0} is required for {1} materialization", proposedTypes, type.FullName)); - } + var consPs = explicitConstr.GetParameters(); + foreach (var p in consPs) + { + if (!p.ParameterType.IsValueType) + { + il.Emit(OpCodes.Ldnull); + } + else + { + GetTempLocal(il, ref structLocals, p.ParameterType, true); + } + } - if (ctor.GetParameters().Length == 0) - { - il.Emit(OpCodes.Newobj, ctor); - il.Emit(OpCodes.Stloc_1); + il.Emit(OpCodes.Newobj, explicitConstr); + il.Emit(OpCodes.Stloc, returnValueLocal); supportInitialize = typeof(ISupportInitialize).IsAssignableFrom(type); if (supportInitialize) { - il.Emit(OpCodes.Ldloc_1); - il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod("BeginInit"), null); + il.Emit(OpCodes.Ldloc, returnValueLocal); + il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod(nameof(ISupportInitialize.BeginInit)), null); } } else - specializedConstructor = ctor; - } + { + var ctor = typeMap.FindConstructor(names, types); + if (ctor == null) + { + string proposedTypes = "(" + string.Join(", ", types.Select((t, i) => t.FullName + " " + names[i]).ToArray()) + ")"; + throw new InvalidOperationException($"A parameterless default constructor or one matching signature {proposedTypes} is required for {type.FullName} materialization"); + } - il.BeginExceptionBlock(); - if (type.IsValueType) - { - il.Emit(OpCodes.Ldloca_S, (byte)1);// [target] + if (ctor.GetParameters().Length == 0) + { + il.Emit(OpCodes.Newobj, ctor); + il.Emit(OpCodes.Stloc, returnValueLocal); + supportInitialize = typeof(ISupportInitialize).IsAssignableFrom(type); + if (supportInitialize) + { + il.Emit(OpCodes.Ldloc, returnValueLocal); + il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod(nameof(ISupportInitialize.BeginInit)), null); + } + } + else + { + specializedConstructor = ctor; + } + } + } + + il.BeginExceptionBlock(); + if (type.IsValueType) + { + il.Emit(OpCodes.Ldloca, returnValueLocal); // [target] } else if (specializedConstructor == null) { - il.Emit(OpCodes.Ldloc_1);// [target] + il.Emit(OpCodes.Ldloc, returnValueLocal); // [target] } var members = (specializedConstructor != null @@ -3582,121 +3263,32 @@ public static Func GetTypeDeserializer( : names.Select(n => typeMap.GetMember(n))).ToList(); // stack is now [target] - bool first = true; var allDone = il.DefineLabel(); - int enumDeclareLocal = -1, valueCopyLocal = il.DeclareLocal(typeof(object)).LocalIndex; + var stringEnumLocal = (LocalBuilder)null; + var valueCopyDiagnosticLocal = il.DeclareLocal(typeof(object)); + bool applyNullSetting = Settings.ApplyNullValues; foreach (var item in members) { if (item != null) { if (specializedConstructor == null) il.Emit(OpCodes.Dup); // stack is now [target][target] - Label isDbNullLabel = il.DefineLabel(); Label finishLabel = il.DefineLabel(); - - il.Emit(OpCodes.Ldarg_0); // stack is now [target][target][reader] - EmitInt32(il, index); // stack is now [target][target][reader][index] - il.Emit(OpCodes.Dup);// stack is now [target][target][reader][index][index] - il.Emit(OpCodes.Stloc_0);// stack is now [target][target][reader][index] - il.Emit(OpCodes.Callvirt, getItem); // stack is now [target][target][value-as-object] - il.Emit(OpCodes.Dup); // stack is now [target][target][value-as-object][value-as-object] - StoreLocal(il, valueCopyLocal); - Type colType = reader.GetFieldType(index); Type memberType = item.MemberType; - if (memberType == typeof(char) || memberType == typeof(char?)) - { - il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod( - memberType == typeof(char) ? "ReadChar" : "ReadNullableChar", BindingFlags.Static | BindingFlags.Public), null); // stack is now [target][target][typed-value] - } - else - { - il.Emit(OpCodes.Dup); // stack is now [target][target][value][value] - il.Emit(OpCodes.Isinst, typeof(DBNull)); // stack is now [target][target][value-as-object][DBNull or null] - il.Emit(OpCodes.Brtrue_S, isDbNullLabel); // stack is now [target][target][value-as-object] - - // unbox nullable enums as the primitive, i.e. byte etc - - var nullUnderlyingType = Nullable.GetUnderlyingType(memberType); - var unboxType = nullUnderlyingType != null && nullUnderlyingType.IsEnum ? nullUnderlyingType : memberType; - - if (unboxType.IsEnum) - { - Type numericType = Enum.GetUnderlyingType(unboxType); - if (colType == typeof(string)) - { - if (enumDeclareLocal == -1) - { - enumDeclareLocal = il.DeclareLocal(typeof(string)).LocalIndex; - } - il.Emit(OpCodes.Castclass, typeof(string)); // stack is now [target][target][string] - StoreLocal(il, enumDeclareLocal); // stack is now [target][target] - il.Emit(OpCodes.Ldtoken, unboxType); // stack is now [target][target][enum-type-token] - il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);// stack is now [target][target][enum-type] - LoadLocal(il, enumDeclareLocal); // stack is now [target][target][enum-type][string] - il.Emit(OpCodes.Ldc_I4_1); // stack is now [target][target][enum-type][string][true] - il.EmitCall(OpCodes.Call, enumParse, null); // stack is now [target][target][enum-as-object] - il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] - } - else - { - FlexibleConvertBoxedFromHeadOfStack(il, colType, unboxType, numericType); - } - - if (nullUnderlyingType != null) - { - il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType })); // stack is now [target][target][typed-value] - } - } - else if (memberType.FullName == LinqBinary) - { - il.Emit(OpCodes.Unbox_Any, typeof(byte[])); // stack is now [target][target][byte-array] - il.Emit(OpCodes.Newobj, memberType.GetConstructor(new Type[] { typeof(byte[]) }));// stack is now [target][target][binary] - } - else - { - TypeCode dataTypeCode = Type.GetTypeCode(colType), unboxTypeCode = Type.GetTypeCode(unboxType); - bool hasTypeHandler; - if ((hasTypeHandler = typeHandlers.ContainsKey(unboxType)) || colType == unboxType || dataTypeCode == unboxTypeCode || dataTypeCode == Type.GetTypeCode(nullUnderlyingType)) - { - if (hasTypeHandler) - { -#pragma warning disable 618 - il.EmitCall(OpCodes.Call, typeof(TypeHandlerCache<>).MakeGenericType(unboxType).GetMethod("Parse"), null); // stack is now [target][target][typed-value] -#pragma warning restore 618 - } - else - { - il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] - } - } - else - { - // not a direct match; need to tweak the unbox - FlexibleConvertBoxedFromHeadOfStack(il, colType, nullUnderlyingType ?? unboxType, null); - if (nullUnderlyingType != null) - { - il.Emit(OpCodes.Newobj, unboxType.GetConstructor(new[] { nullUnderlyingType })); // stack is now [target][target][typed-value] - } + // Save off the current index for access if an exception is thrown + EmitInt32(il, index); + il.Emit(OpCodes.Stloc, currentIndexDiagnosticLocal); - } + LoadReaderValueOrBranchToDBNullLabel(il, index, ref stringEnumLocal, valueCopyDiagnosticLocal, reader.GetFieldType(index), memberType, out var isDbNullLabel); - } - } if (specializedConstructor == null) { // Store the value in the property/field if (item.Property != null) { - if (type.IsValueType) - { - il.Emit(OpCodes.Call, DefaultTypeMap.GetPropertySetter(item.Property, type)); // stack is now [target] - } - else - { - il.Emit(OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, type)); // stack is now [target] - } + il.Emit(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, type)); } else { @@ -3710,16 +3302,30 @@ public static Func GetTypeDeserializer( if (specializedConstructor != null) { il.Emit(OpCodes.Pop); - if (item.MemberType.IsValueType) + LoadDefaultValue(il, item.MemberType); + } + else if (applyNullSetting && (!memberType.IsValueType || Nullable.GetUnderlyingType(memberType) != null)) + { + il.Emit(OpCodes.Pop); // stack is now [target][target] + // can load a null with this value + if (memberType.IsValueType) + { // must be Nullable for some T + GetTempLocal(il, ref structLocals, memberType, true); // stack is now [target][target][null] + } + else + { // regular reference-type + il.Emit(OpCodes.Ldnull); // stack is now [target][target][null] + } + + // Store the value in the property/field + if (item.Property != null) { - int localIndex = il.DeclareLocal(item.MemberType).LocalIndex; - LoadLocalAddress(il, localIndex); - il.Emit(OpCodes.Initobj, item.MemberType); - LoadLocal(il, localIndex); + il.Emit(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, type)); + // stack is now [target] } else { - il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Stfld, item.Field); // stack is now [target] } } else @@ -3732,14 +3338,14 @@ public static Func GetTypeDeserializer( { il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldnull); // stack is now [null] - il.Emit(OpCodes.Stloc_1); + il.Emit(OpCodes.Stloc, returnValueLocal); il.Emit(OpCodes.Br, allDone); } il.MarkLabel(finishLabel); } first = false; - index += 1; + index++; } if (type.IsValueType) { @@ -3751,29 +3357,134 @@ public static Func GetTypeDeserializer( { il.Emit(OpCodes.Newobj, specializedConstructor); } - il.Emit(OpCodes.Stloc_1); // stack is empty + il.Emit(OpCodes.Stloc, returnValueLocal); // stack is empty if (supportInitialize) { - il.Emit(OpCodes.Ldloc_1); - il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod("EndInit"), null); + il.Emit(OpCodes.Ldloc, returnValueLocal); + il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod(nameof(ISupportInitialize.EndInit)), null); } } il.MarkLabel(allDone); il.BeginCatchBlock(typeof(Exception)); // stack is Exception - il.Emit(OpCodes.Ldloc_0); // stack is Exception, index + il.Emit(OpCodes.Ldloc, currentIndexDiagnosticLocal); // stack is Exception, index il.Emit(OpCodes.Ldarg_0); // stack is Exception, index, reader - LoadLocal(il, valueCopyLocal); // stack is Exception, index, reader, value - il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod("ThrowDataException"), null); + il.Emit(OpCodes.Ldloc, valueCopyDiagnosticLocal); // stack is Exception, index, reader, value + il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod(nameof(SqlMapper.ThrowDataException)), null); il.EndExceptionBlock(); - il.Emit(OpCodes.Ldloc_1); // stack is [rval] + il.Emit(OpCodes.Ldloc, returnValueLocal); // stack is [rval] if (type.IsValueType) { il.Emit(OpCodes.Box, type); } il.Emit(OpCodes.Ret); + } + + private static void LoadDefaultValue(ILGenerator il, Type type) + { + if (type.IsValueType) + { + var local = il.DeclareLocal(type); + il.Emit(OpCodes.Ldloca, local); + il.Emit(OpCodes.Initobj, type); + il.Emit(OpCodes.Ldloc, local); + } + else + { + il.Emit(OpCodes.Ldnull); + } + } + + private static void LoadReaderValueOrBranchToDBNullLabel(ILGenerator il, int index, ref LocalBuilder stringEnumLocal, LocalBuilder valueCopyLocal, Type colType, Type memberType, out Label isDbNullLabel) + { + isDbNullLabel = il.DefineLabel(); + il.Emit(OpCodes.Ldarg_0); // stack is now [...][reader] + EmitInt32(il, index); // stack is now [...][reader][index] + il.Emit(OpCodes.Callvirt, getItem); // stack is now [...][value-as-object] + + if (valueCopyLocal != null) + { + il.Emit(OpCodes.Dup); // stack is now [...][value-as-object][value-as-object] + il.Emit(OpCodes.Stloc, valueCopyLocal); // stack is now [...][value-as-object] + } + + if (memberType == typeof(char) || memberType == typeof(char?)) + { + il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod( + memberType == typeof(char) ? nameof(SqlMapper.ReadChar) : nameof(SqlMapper.ReadNullableChar), BindingFlags.Static | BindingFlags.Public), null); // stack is now [...][typed-value] + } + else + { + il.Emit(OpCodes.Dup); // stack is now [...][value-as-object][value-as-object] + il.Emit(OpCodes.Isinst, typeof(DBNull)); // stack is now [...][value-as-object][DBNull or null] + il.Emit(OpCodes.Brtrue_S, isDbNullLabel); // stack is now [...][value-as-object] + + // unbox nullable enums as the primitive, i.e. byte etc + + var nullUnderlyingType = Nullable.GetUnderlyingType(memberType); + var unboxType = nullUnderlyingType?.IsEnum == true ? nullUnderlyingType : memberType; + + if (unboxType.IsEnum) + { + Type numericType = Enum.GetUnderlyingType(unboxType); + if (colType == typeof(string)) + { + if (stringEnumLocal == null) + { + stringEnumLocal = il.DeclareLocal(typeof(string)); + } + il.Emit(OpCodes.Castclass, typeof(string)); // stack is now [...][string] + il.Emit(OpCodes.Stloc, stringEnumLocal); // stack is now [...] + il.Emit(OpCodes.Ldtoken, unboxType); // stack is now [...][enum-type-token] + il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)), null);// stack is now [...][enum-type] + il.Emit(OpCodes.Ldloc, stringEnumLocal); // stack is now [...][enum-type][string] + il.Emit(OpCodes.Ldc_I4_1); // stack is now [...][enum-type][string][true] + il.EmitCall(OpCodes.Call, enumParse, null); // stack is now [...][enum-as-object] + il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [...][typed-value] + } + else + { + FlexibleConvertBoxedFromHeadOfStack(il, colType, unboxType, numericType); + } - return (Func)dm.CreateDelegate(typeof(Func)); + if (nullUnderlyingType != null) + { + il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType })); // stack is now [...][typed-value] + } + } + else if (memberType.FullName == LinqBinary) + { + il.Emit(OpCodes.Unbox_Any, typeof(byte[])); // stack is now [...][byte-array] + il.Emit(OpCodes.Newobj, memberType.GetConstructor(new Type[] { typeof(byte[]) }));// stack is now [...][binary] + } + else + { + TypeCode dataTypeCode = Type.GetTypeCode(colType), unboxTypeCode = Type.GetTypeCode(unboxType); + bool hasTypeHandler; + if ((hasTypeHandler = typeHandlers.ContainsKey(unboxType)) || colType == unboxType || dataTypeCode == unboxTypeCode || dataTypeCode == Type.GetTypeCode(nullUnderlyingType)) + { + if (hasTypeHandler) + { +#pragma warning disable 618 + il.EmitCall(OpCodes.Call, typeof(TypeHandlerCache<>).MakeGenericType(unboxType).GetMethod(nameof(TypeHandlerCache.Parse)), null); // stack is now [...][typed-value] +#pragma warning restore 618 + } + else + { + il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [...][typed-value] + } + } + else + { + // not a direct match; need to tweak the unbox + FlexibleConvertBoxedFromHeadOfStack(il, colType, nullUnderlyingType ?? unboxType, null); + if (nullUnderlyingType != null) + { + il.Emit(OpCodes.Newobj, unboxType.GetConstructor(new[] { nullUnderlyingType })); // stack is now [...][typed-value] + } + } + } + } } private static void FlexibleConvertBoxedFromHeadOfStack(ILGenerator il, Type from, Type to, Type via) @@ -3851,14 +3562,15 @@ private static void FlexibleConvertBoxedFromHeadOfStack(ILGenerator il, Type fro else { il.Emit(OpCodes.Ldtoken, via ?? to); // stack is now [target][target][value][member-type-token] - il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null); // stack is now [target][target][value][member-type] - il.EmitCall(OpCodes.Call, typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) }), null); // stack is now [target][target][boxed-member-type-value] + il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)), null); // stack is now [target][target][value][member-type] + il.EmitCall(OpCodes.Call, InvariantCulture, null); // stack is now [target][target][value][member-type][culture] + il.EmitCall(OpCodes.Call, typeof(Convert).GetMethod(nameof(Convert.ChangeType), new Type[] { typeof(object), typeof(Type), typeof(IFormatProvider) }), null); // stack is now [target][target][boxed-member-type-value] il.Emit(OpCodes.Unbox_Any, to); // stack is now [target][target][typed-value] } } } - static MethodInfo GetOperator(Type from, Type to) + private static MethodInfo GetOperator(Type from, Type to) { if (to == null) return null; MethodInfo[] fromMethods, toMethods; @@ -3866,9 +3578,9 @@ static MethodInfo GetOperator(Type from, Type to) ?? ResolveOperator(toMethods = to.GetMethods(BindingFlags.Static | BindingFlags.Public), from, to, "op_Implicit") ?? ResolveOperator(fromMethods, from, to, "op_Explicit") ?? ResolveOperator(toMethods, from, to, "op_Explicit"); - } - static MethodInfo ResolveOperator(MethodInfo[] methods, Type from, Type to, string name) + + private static MethodInfo ResolveOperator(MethodInfo[] methods, Type from, Type to, string name) { for (int i = 0; i < methods.Length; i++) { @@ -3880,65 +3592,14 @@ static MethodInfo ResolveOperator(MethodInfo[] methods, Type from, Type to, stri return null; } - private static void LoadLocal(ILGenerator il, int index) - { - if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException("index"); - switch (index) - { - case 0: il.Emit(OpCodes.Ldloc_0); break; - case 1: il.Emit(OpCodes.Ldloc_1); break; - case 2: il.Emit(OpCodes.Ldloc_2); break; - case 3: il.Emit(OpCodes.Ldloc_3); break; - default: - if (index <= 255) - { - il.Emit(OpCodes.Ldloc_S, (byte)index); - } - else - { - il.Emit(OpCodes.Ldloc, (short)index); - } - break; - } - } - private static void StoreLocal(ILGenerator il, int index) - { - if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException("index"); - switch (index) - { - case 0: il.Emit(OpCodes.Stloc_0); break; - case 1: il.Emit(OpCodes.Stloc_1); break; - case 2: il.Emit(OpCodes.Stloc_2); break; - case 3: il.Emit(OpCodes.Stloc_3); break; - default: - if (index <= 255) - { - il.Emit(OpCodes.Stloc_S, (byte)index); - } - else - { - il.Emit(OpCodes.Stloc, (short)index); - } - break; - } - } - private static void LoadLocalAddress(ILGenerator il, int index) - { - if (index < 0 || index >= short.MaxValue) throw new ArgumentNullException("index"); - - if (index <= 255) - { - il.Emit(OpCodes.Ldloca_S, (byte)index); - } - else - { - il.Emit(OpCodes.Ldloca, (short)index); - } - } /// /// Throws a data exception, only used internally /// - [Obsolete("Intended for internal use only")] + /// The exception to throw. + /// The index the exception occured at. + /// The reader the exception occured in. + /// The value that caused the exception. + [Obsolete(ObsoleteInternalUsageOnly, false)] public static void ThrowDataException(Exception ex, int index, IDataReader reader, object value) { Exception toThrow; @@ -3964,7 +3625,7 @@ public static void ThrowDataException(Exception ex, int index, IDataReader reade formattedValue = valEx.Message; } } - toThrow = new DataException(string.Format("Error parsing column {0} ({1}={2})", index, name, formattedValue), ex); + toThrow = new DataException($"Error parsing column {index} ({name}={formattedValue})", ex); } catch { // throw the **original** exception, wrapped as DataException @@ -3972,6 +3633,7 @@ public static void ThrowDataException(Exception ex, int index, IDataReader reade } throw toThrow; } + private static void EmitInt32(ILGenerator il, int value) { switch (value) @@ -3999,16 +3661,10 @@ private static void EmitInt32(ILGenerator il, int value) } } - - /// - /// Key used to indicate the type name associated with a DataTable - /// - private const string DataTableTypeNameKey = "dapper:TypeName"; - /// /// How should connection strings be compared for equivalence? Defaults to StringComparer.Ordinal. /// Providing a custom implementation can be useful for allowing multi-tenancy databases with identical - /// schema to share startegies. Note that usual equivalence rules apply: any equivalent connection strings + /// schema to share strategies. Note that usual equivalence rules apply: any equivalent connection strings /// MUST yield the same hash-code. /// public static IEqualityComparer ConnectionStringComparer @@ -4016,1217 +3672,74 @@ public static IEqualityComparer ConnectionStringComparer get { return connectionStringComparer; } set { connectionStringComparer = value ?? StringComparer.Ordinal; } } - private static IEqualityComparer connectionStringComparer = StringComparer.Ordinal; + private static IEqualityComparer connectionStringComparer = StringComparer.Ordinal; /// - /// The grid reader provides interfaces for reading multiple result sets from a Dapper query + /// Key used to indicate the type name associated with a DataTable. /// - public partial class GridReader : IDisposable - { - private IDataReader reader; - private IDbCommand command; - private Identity identity; - - internal GridReader(IDbCommand command, IDataReader reader, Identity identity, SqlMapper.IParameterCallbacks callbacks) - { - this.command = command; - this.reader = reader; - this.identity = identity; - this.callbacks = callbacks; - } - -#if !CSHARP30 - - /// - /// Read the next grid of results, returned as a dynamic object - /// - public IEnumerable Read(bool buffered = true) - { - return ReadImpl(typeof(DapperRow), buffered); - } -#endif - -#if CSHARP30 - /// - /// Read the next grid of results - /// - public IEnumerable Read() - { - return Read(true); - } -#endif - /// - /// Read the next grid of results - /// -#if CSHARP30 - public IEnumerable Read(bool buffered) -#else - public IEnumerable Read(bool buffered = true) -#endif - { - return ReadImpl(typeof(T), buffered); - } - - /// - /// Read the next grid of results - /// -#if CSHARP30 - public IEnumerable Read(Type type, bool buffered) -#else - public IEnumerable Read(Type type, bool buffered = true) -#endif - { - if (type == null) throw new ArgumentNullException("type"); - return ReadImpl(type, buffered); - } - - private IEnumerable ReadImpl(Type type, bool buffered) - { - if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); - if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); - var typedIdentity = identity.ForGrid(type, gridIndex); - CacheInfo cache = GetCacheInfo(typedIdentity, null, true); - var deserializer = cache.Deserializer; - - int hash = GetColumnHash(reader); - if (deserializer.Func == null || deserializer.Hash != hash) - { - deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); - cache.Deserializer = deserializer; - } - consumed = true; - var result = ReadDeferred(gridIndex, deserializer.Func, typedIdentity); - return buffered ? result.ToList() : result; - } - - - private IEnumerable MultiReadInternal(Delegate func, string splitOn) - { - var identity = this.identity.ForGrid(typeof(TReturn), new Type[] { - typeof(TFirst), - typeof(TSecond), - typeof(TThird), - typeof(TFourth), - typeof(TFifth), - typeof(TSixth), - typeof(TSeventh) - }, gridIndex); - try - { - foreach (var r in SqlMapper.MultiMapImpl(null, default(CommandDefinition), func, splitOn, reader, identity, false)) - { - yield return r; - } - } - finally - { - NextResult(); - } - } - -#if CSHARP30 - /// - /// Read multiple objects from a single recordset on the grid - /// - public IEnumerable Read(Func func, string splitOn) - { - return Read(func, splitOn, true); - } -#endif - /// - /// Read multiple objects from a single recordset on the grid - /// -#if CSHARP30 - public IEnumerable Read(Func func, string splitOn, bool buffered) -#else - public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) -#endif - { - var result = MultiReadInternal(func, splitOn); - return buffered ? result.ToList() : result; - } + private const string DataTableTypeNameKey = "dapper:TypeName"; -#if CSHARP30 - /// - /// Read multiple objects from a single recordset on the grid - /// - public IEnumerable Read(Func func, string splitOn) - { - return Read(func, splitOn, true); - } -#endif - /// - /// Read multiple objects from a single recordset on the grid - /// -#if CSHARP30 - public IEnumerable Read(Func func, string splitOn, bool buffered) -#else - public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) -#endif - { - var result = MultiReadInternal(func, splitOn); - return buffered ? result.ToList() : result; - } + /// + /// Used to pass a DataTable as a . + /// + /// The to create this parameter for. + /// The name of the type this parameter is for. + public static ICustomQueryParameter AsTableValuedParameter(this DataTable table, string typeName = null) => + new TableValuedParameter(table, typeName); -#if CSHARP30 - /// - /// Read multiple objects from a single record set on the grid - /// - public IEnumerable Read(Func func, string splitOn) - { - return Read(func, splitOn, true); - } -#endif - - /// - /// Read multiple objects from a single record set on the grid - /// -#if CSHARP30 - public IEnumerable Read(Func func, string splitOn, bool buffered) -#else - public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) -#endif + /// + /// Associate a DataTable with a type name. + /// + /// The that does with the . + /// The name of the type this table is for. + public static void SetTypeName(this DataTable table, string typeName) + { + if (table != null) { - var result = MultiReadInternal(func, splitOn); - return buffered ? result.ToList() : result; + if (string.IsNullOrEmpty(typeName)) + table.ExtendedProperties.Remove(DataTableTypeNameKey); + else + table.ExtendedProperties[DataTableTypeNameKey] = typeName; } + } + /// + /// Fetch the type name associated with a . + /// + /// The that has a type name associated with it. + public static string GetTypeName(this DataTable table) => + table?.ExtendedProperties[DataTableTypeNameKey] as string; + /// + /// Used to pass a IEnumerable<SqlDataRecord> as a TableValuedParameter. + /// + /// The list of records to convert to TVPs. + /// The sql parameter type name. + public static ICustomQueryParameter AsTableValuedParameter(this IEnumerable list, string typeName = null) where T : IDataRecord => + new SqlDataRecordListTVPParameter(list, typeName); -#if !CSHARP30 - /// - /// Read multiple objects from a single record set on the grid - /// - public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) - { - var result = MultiReadInternal(func, splitOn); - return buffered ? result.ToList() : result; - } - /// - /// Read multiple objects from a single record set on the grid - /// - public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) - { - var result = MultiReadInternal(func, splitOn); - return buffered ? result.ToList() : result; - } - /// - /// Read multiple objects from a single record set on the grid - /// - public IEnumerable Read(Func func, string splitOn = "id", bool buffered = true) + // one per thread + [ThreadStatic] + private static StringBuilder perThreadStringBuilderCache; + private static StringBuilder GetStringBuilder() + { + var tmp = perThreadStringBuilderCache; + if (tmp != null) { - var result = MultiReadInternal(func, splitOn); - return buffered ? result.ToList() : result; + perThreadStringBuilderCache = null; + tmp.Length = 0; + return tmp; } -#endif + return new StringBuilder(); + } - private IEnumerable ReadDeferred(int index, Func deserializer, Identity typedIdentity) - { - try - { - while (index == gridIndex && reader.Read()) - { - yield return (T)deserializer(reader); - } - } - finally // finally so that First etc progresses things even when multiple rows - { - if (index == gridIndex) - { - NextResult(); - } - } - } - private int gridIndex, readCount; - private bool consumed; - private SqlMapper.IParameterCallbacks callbacks; - - /// - /// Has the underlying reader been consumed? - /// - public bool IsConsumed - { - get - { - return consumed; - } - } - private void NextResult() - { - if (reader.NextResult()) - { - readCount++; - gridIndex++; - consumed = false; - } - else - { - // happy path; close the reader cleanly - no - // need for "Cancel" etc - reader.Dispose(); - reader = null; - if (callbacks != null) callbacks.OnCompleted(); - Dispose(); - } - } - /// - /// Dispose the grid, closing and disposing both the underlying reader and command. - /// - public void Dispose() - { - if (reader != null) - { - if (!reader.IsClosed && command != null) command.Cancel(); - reader.Dispose(); - reader = null; - } - if (command != null) - { - command.Dispose(); - command = null; - } - } - } - } - - /// - /// A bag of parameters that can be passed to the Dapper Query and Execute methods - /// - partial class DynamicParameters : SqlMapper.IDynamicParameters, SqlMapper.IParameterLookup, SqlMapper.IParameterCallbacks - { - internal const DbType EnumerableMultiParameter = (DbType)(-1); - static Dictionary> paramReaderCache = new Dictionary>(); - - Dictionary parameters = new Dictionary(); - List templates; - - object SqlMapper.IParameterLookup.this[string member] - { - get - { - ParamInfo param; - return parameters.TryGetValue(member, out param) ? param.Value : null; - } - } - - partial class ParamInfo - { - public string Name { get; set; } - public object Value { get; set; } - public ParameterDirection ParameterDirection { get; set; } - public DbType? DbType { get; set; } - public int? Size { get; set; } - public IDbDataParameter AttachedParam { get; set; } - internal Action OutputCallback { get; set; } - internal object OutputTarget { get; set; } - internal bool CameFromTemplate { get; set; } - } - - /// - /// construct a dynamic parameter bag - /// - public DynamicParameters() - { - RemoveUnused = true; - } - - /// - /// construct a dynamic parameter bag - /// - /// can be an anonymous type or a DynamicParameters bag - public DynamicParameters(object template) - { - RemoveUnused = true; - AddDynamicParams(template); - } - - /// - /// Append a whole object full of params to the dynamic - /// EG: AddDynamicParams(new {A = 1, B = 2}) // will add property A and B to the dynamic - /// - /// - public void AddDynamicParams(object param) - { - var obj = param as object; - if (obj != null) - { - var subDynamic = obj as DynamicParameters; - if (subDynamic == null) - { - var dictionary = obj as IEnumerable>; - if (dictionary == null) - { - templates = templates ?? new List(); - templates.Add(obj); - } - else - { - foreach (var kvp in dictionary) - { - Add(kvp.Key, kvp.Value, null, null, null); - } - } - } - else - { - if (subDynamic.parameters != null) - { - foreach (var kvp in subDynamic.parameters) - { - parameters.Add(kvp.Key, kvp.Value); - } - } - - if (subDynamic.templates != null) - { - templates = templates ?? new List(); - foreach (var t in subDynamic.templates) - { - templates.Add(t); - } - } - } - } - } - - /// - /// Add a parameter to this dynamic parameter list - /// - /// - /// - /// - /// - /// - public void Add( -#if CSHARP30 -string name, object value, DbType? dbType, ParameterDirection? direction, int? size -#else -string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null -#endif -) - { - parameters[Clean(name)] = new ParamInfo() { Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input, DbType = dbType, Size = size }; - } - - static string Clean(string name) - { - if (!string.IsNullOrEmpty(name)) - { - switch (name[0]) - { - case '@': - case ':': - case '?': - return name.Substring(1); - } - } - return name; - } - - void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Identity identity) - { - AddParameters(command, identity); - } - - /// - /// If true, the command-text is inspected and only values that are clearly used are included on the connection - /// - public bool RemoveUnused { get; set; } - - /// - /// Add all the parameters needed to the command just before it executes - /// - /// The raw command prior to execution - /// Information about the query - protected void AddParameters(IDbCommand command, SqlMapper.Identity identity) - { - var literals = SqlMapper.GetLiteralTokens(identity.sql); - - if (templates != null) - { - foreach (var template in templates) - { - var newIdent = identity.ForDynamicParameters(template.GetType()); - Action appender; - - lock (paramReaderCache) - { - if (!paramReaderCache.TryGetValue(newIdent, out appender)) - { - appender = SqlMapper.CreateParamInfoGenerator(newIdent, true, RemoveUnused, literals); - paramReaderCache[newIdent] = appender; - } - } - - appender(command, template); - } - - // The parameters were added to the command, but not the - // DynamicParameters until now. - foreach (IDbDataParameter param in command.Parameters) - { - // If someone makes a DynamicParameters with a template, - // then explicitly adds a parameter of a matching name, - // it will already exist in 'parameters'. - if (!parameters.ContainsKey(param.ParameterName)) - { - parameters.Add(param.ParameterName, new ParamInfo - { - AttachedParam = param, - CameFromTemplate = true, - DbType = param.DbType, - Name = param.ParameterName, - ParameterDirection = param.Direction, - Size = param.Size, - Value = param.Value - }); - } - } - - // Now that the parameters are added to the command, let's place our output callbacks - var tmp = outputCallbacks; - if (tmp != null) - { - foreach (var generator in tmp) - { - generator(); - } - } - } - - foreach (var param in parameters.Values) - { - if (param.CameFromTemplate) continue; - - var dbType = param.DbType; - var val = param.Value; - string name = Clean(param.Name); - var isCustomQueryParameter = val is SqlMapper.ICustomQueryParameter; - - SqlMapper.ITypeHandler handler = null; - if (dbType == null && val != null && !isCustomQueryParameter) dbType = SqlMapper.LookupDbType(val.GetType(), name, true, out handler); - if (dbType == DynamicParameters.EnumerableMultiParameter) - { -#pragma warning disable 612, 618 - SqlMapper.PackListParameters(command, name, val); -#pragma warning restore 612, 618 - } - else if (isCustomQueryParameter) - { - ((SqlMapper.ICustomQueryParameter)val).AddParameter(command, name); - } - else - { - - bool add = !command.Parameters.Contains(name); - IDbDataParameter p; - if (add) - { - p = command.CreateParameter(); - p.ParameterName = name; - } - else - { - p = (IDbDataParameter)command.Parameters[name]; - } - - p.Direction = param.ParameterDirection; - if (handler == null) - { - p.Value = val ?? DBNull.Value; - if (dbType != null && p.DbType != dbType) - { - p.DbType = dbType.Value; - } - var s = val as string; - if (s != null) - { - if (s.Length <= DbString.DefaultLength) - { - p.Size = DbString.DefaultLength; - } - } - if (param.Size != null) - { - p.Size = param.Size.Value; - } - } - else - { - if (dbType != null) p.DbType = dbType.Value; - if (param.Size != null) p.Size = param.Size.Value; - handler.SetValue(p, val ?? DBNull.Value); - } - - if (add) - { - command.Parameters.Add(p); - } - param.AttachedParam = p; - } - } - - // note: most non-priveleged implementations would use: this.ReplaceLiterals(command); - if (literals.Count != 0) SqlMapper.ReplaceLiterals(this, command, literals); - } - - /// - /// All the names of the param in the bag, use Get to yank them out - /// - public IEnumerable ParameterNames - { - get - { - return parameters.Select(p => p.Key); - } - } - - - /// - /// Get the value of a parameter - /// - /// - /// - /// The value, note DBNull.Value is not returned, instead the value is returned as null - public T Get(string name) - { - var val = parameters[Clean(name)].AttachedParam.Value; - if (val == DBNull.Value) - { - if (default(T) != null) - { - throw new ApplicationException("Attempting to cast a DBNull to a non nullable type!"); - } - return default(T); - } - return (T)val; - } - - /// - /// Allows you to automatically populate a target property/field from output parameters. It actually - /// creates an InputOutput parameter, so you can still pass data in. - /// - /// - /// The object whose property/field you wish to populate. - /// A MemberExpression targeting a property/field of the target (or descendant thereof.) - /// - /// The size to set on the parameter. Defaults to 0, or DbString.DefaultLength in case of strings. - /// The DynamicParameters instance -#if CSHARP30 - public DynamicParameters Output(T target, Expression> expression, DbType? dbType, int? size) -#else - public DynamicParameters Output(T target, Expression> expression, DbType? dbType = null, int? size = null) -#endif - { - var failMessage = "Expression must be a property/field chain off of a(n) {0} instance"; - failMessage = string.Format(failMessage, typeof(T).Name); - Action @throw = () => { throw new InvalidOperationException(failMessage); }; - - // Is it even a MemberExpression? - var lastMemberAccess = expression.Body as MemberExpression; - - if (lastMemberAccess == null || - (lastMemberAccess.Member.MemberType != MemberTypes.Property && - lastMemberAccess.Member.MemberType != MemberTypes.Field)) - { - if (expression.Body.NodeType == ExpressionType.Convert && - expression.Body.Type == typeof(object) && - ((UnaryExpression)expression.Body).Operand is MemberExpression) - { - // It's got to be unboxed - lastMemberAccess = (MemberExpression)((UnaryExpression)expression.Body).Operand; - } - else @throw(); - } - - // Does the chain consist of MemberExpressions leading to a ParameterExpression of type T? - MemberExpression diving = lastMemberAccess; - ParameterExpression constant = null; - // Retain a list of member names and the member expressions so we can rebuild the chain. - List names = new List(); - List chain = new List(); - - do - { - // Insert the names in the right order so expression - // "Post.Author.Name" becomes parameter "PostAuthorName" - names.Insert(0, diving.Member.Name); - chain.Insert(0, diving); - - constant = diving.Expression as ParameterExpression; - diving = diving.Expression as MemberExpression; - - if (constant != null && - constant.Type == typeof(T)) - { - break; - } - else if (diving == null || - (diving.Member.MemberType != MemberTypes.Property && - diving.Member.MemberType != MemberTypes.Field)) - { - @throw(); - } - } - while (diving != null); - - var dynamicParamName = string.Join(string.Empty, names.ToArray()); - - // Before we get all emitty... - var lookup = string.Join("|", names.ToArray()); - - var cache = CachedOutputSetters.Cache; - var setter = (Action)cache[lookup]; - - if (setter != null) goto MAKECALLBACK; - - // Come on let's build a method, let's build it, let's build it now! - var dm = new DynamicMethod(string.Format("ExpressionParam{0}", Guid.NewGuid()), null, new[] { typeof(object), this.GetType() }, true); - var il = dm.GetILGenerator(); - - il.Emit(OpCodes.Ldarg_0); // [object] - il.Emit(OpCodes.Castclass, typeof(T)); // [T] - - // Count - 1 to skip the last member access - var i = 0; - for (; i < (chain.Count - 1); i++) - { - var member = chain[0].Member; - - if (member.MemberType == MemberTypes.Property) - { - var get = ((PropertyInfo)member).GetGetMethod(true); - il.Emit(OpCodes.Callvirt, get); // [Member{i}] - } - else // Else it must be a field! - { - il.Emit(OpCodes.Ldfld, ((FieldInfo)member)); // [Member{i}] - } - } - - var paramGetter = this.GetType().GetMethod("Get", new Type[] { typeof(string) }).MakeGenericMethod(lastMemberAccess.Type); - - il.Emit(OpCodes.Ldarg_1); // [target] [DynamicParameters] - il.Emit(OpCodes.Ldstr, dynamicParamName); // [target] [DynamicParameters] [ParamName] - il.Emit(OpCodes.Callvirt, paramGetter); // [target] [value], it's already typed thanks to generic method - - // GET READY - var lastMember = lastMemberAccess.Member; - if (lastMember.MemberType == MemberTypes.Property) - { - var set = ((PropertyInfo)lastMember).GetSetMethod(true); - il.Emit(OpCodes.Callvirt, set); // SET - } - else - { - il.Emit(OpCodes.Stfld, ((FieldInfo)lastMember)); // SET - } - - il.Emit(OpCodes.Ret); // GO - - setter = (Action)dm.CreateDelegate(typeof(Action)); - lock (cache) - { - cache[lookup] = setter; - } - - // Queue the preparation to be fired off when adding parameters to the DbCommand - MAKECALLBACK: - (outputCallbacks ?? (outputCallbacks = new List())).Add(() => - { - // Finally, prep the parameter and attach the callback to it - ParamInfo parameter; - var targetMemberType = lastMemberAccess.Type; - int sizeToSet = (!size.HasValue && targetMemberType == typeof(string)) ? DbString.DefaultLength : size ?? 0; - - if (this.parameters.TryGetValue(dynamicParamName, out parameter)) - { - parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput; - - if (parameter.AttachedParam.Size == 0) - { - parameter.Size = parameter.AttachedParam.Size = sizeToSet; - } - } - else - { - SqlMapper.ITypeHandler handler; - dbType = (!dbType.HasValue) ? SqlMapper.LookupDbType(targetMemberType, targetMemberType.Name, true, out handler) : dbType; - - // CameFromTemplate property would not apply here because this new param - // Still needs to be added to the command - this.Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet); - } - - parameter = this.parameters[dynamicParamName]; - parameter.OutputCallback = setter; - parameter.OutputTarget = target; - }); - - return this; - } - - private List outputCallbacks; - - private readonly Dictionary> cachedOutputSetters = new Dictionary>(); - - internal static class CachedOutputSetters - { - public static readonly Hashtable Cache = new Hashtable(); - } - - void SqlMapper.IParameterCallbacks.OnCompleted() + private static string __ToStringRecycle(this StringBuilder obj) { - foreach (var param in (from p in parameters select p.Value)) - { - if (param.OutputCallback != null) param.OutputCallback(param.OutputTarget, this); - } - } - } - - /// - /// This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar - /// - sealed partial class DbString : Dapper.SqlMapper.ICustomQueryParameter - { - /// - /// A value to set the default value of strings - /// going through Dapper. Default is 4000, any value larger than this - /// field will not have the default value applied. - /// - public const int DefaultLength = 4000; - - /// - /// Create a new DbString - /// - public DbString() { Length = -1; } - /// - /// Ansi vs Unicode - /// - public bool IsAnsi { get; set; } - /// - /// Fixed length - /// - public bool IsFixedLength { get; set; } - /// - /// Length of the string -1 for max - /// - public int Length { get; set; } - /// - /// The value of the string - /// - public string Value { get; set; } - /// - /// Add the parameter to the command... internal use only - /// - /// - /// - public void AddParameter(IDbCommand command, string name) - { - if (IsFixedLength && Length == -1) - { - throw new InvalidOperationException("If specifying IsFixedLength, a Length must also be specified"); - } - var param = command.CreateParameter(); - param.ParameterName = name; - param.Value = (object)Value ?? DBNull.Value; - if (Length == -1 && Value != null && Value.Length <= DefaultLength) - { - param.Size = DefaultLength; - } - else - { - param.Size = Length; - } - param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String); - command.Parameters.Add(param); - } - } - - /// - /// Handles variances in features per DBMS - /// - partial class FeatureSupport - { - private static readonly FeatureSupport - @default = new FeatureSupport(false), - postgres = new FeatureSupport(true); - - /// - /// Gets the featureset based on the passed connection - /// - public static FeatureSupport Get(IDbConnection connection) - { - string name = connection == null ? null : connection.GetType().Name; - if (string.Equals(name, "npgsqlconnection", StringComparison.InvariantCultureIgnoreCase)) return postgres; - return @default; - } - private FeatureSupport(bool arrays) - { - Arrays = arrays; - } - /// - /// True if the db supports array columns e.g. Postgresql - /// - public bool Arrays { get; private set; } - } - - /// - /// Represents simple memeber map for one of target parameter or property or field to source DataReader column - /// - sealed partial class SimpleMemberMap : SqlMapper.IMemberMap - { - private readonly string _columnName; - private readonly PropertyInfo _property; - private readonly FieldInfo _field; - private readonly ParameterInfo _parameter; - - /// - /// Creates instance for simple property mapping - /// - /// DataReader column name - /// Target property - public SimpleMemberMap(string columnName, PropertyInfo property) - { - if (columnName == null) - throw new ArgumentNullException("columnName"); - - if (property == null) - throw new ArgumentNullException("property"); - - _columnName = columnName; - _property = property; - } - - /// - /// Creates instance for simple field mapping - /// - /// DataReader column name - /// Target property - public SimpleMemberMap(string columnName, FieldInfo field) - { - if (columnName == null) - throw new ArgumentNullException("columnName"); - - if (field == null) - throw new ArgumentNullException("field"); - - _columnName = columnName; - _field = field; - } - - /// - /// Creates instance for simple constructor parameter mapping - /// - /// DataReader column name - /// Target constructor parameter - public SimpleMemberMap(string columnName, ParameterInfo parameter) - { - if (columnName == null) - throw new ArgumentNullException("columnName"); - - if (parameter == null) - throw new ArgumentNullException("parameter"); - - _columnName = columnName; - _parameter = parameter; - } - - /// - /// DataReader column name - /// - public string ColumnName - { - get { return _columnName; } - } - - /// - /// Target member type - /// - public Type MemberType - { - get - { - if (_field != null) - return _field.FieldType; - - if (_property != null) - return _property.PropertyType; - - if (_parameter != null) - return _parameter.ParameterType; - - return null; - } - } - - /// - /// Target property - /// - public PropertyInfo Property - { - get { return _property; } - } - - /// - /// Target field - /// - public FieldInfo Field - { - get { return _field; } - } - - /// - /// Target constructor parameter - /// - public ParameterInfo Parameter - { - get { return _parameter; } - } - } - - /// - /// Represents default type mapping strategy used by Dapper - /// - sealed partial class DefaultTypeMap : SqlMapper.ITypeMap - { - private readonly List _fields; - private readonly List _properties; - private readonly Type _type; - - /// - /// Creates default type map - /// - /// Entity type - public DefaultTypeMap(Type type) - { - if (type == null) - throw new ArgumentNullException("type"); - - _fields = GetSettableFields(type); - _properties = GetSettableProps(type); - _type = type; + if (obj == null) return ""; + var s = obj.ToString(); + perThreadStringBuilderCache = perThreadStringBuilderCache ?? obj; + return s; } - - internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo, Type type) - { - return propertyInfo.DeclaringType == type ? - propertyInfo.GetSetMethod(true) : - propertyInfo.DeclaringType.GetProperty( - propertyInfo.Name, - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - Type.DefaultBinder, - propertyInfo.PropertyType, - propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(), - null).GetSetMethod(true); - } - - internal static List GetSettableProps(Type t) - { - return t - .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) - .Where(p => GetPropertySetter(p, t) != null) - .ToList(); - } - - internal static List GetSettableFields(Type t) - { - return t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToList(); - } - - /// - /// Finds best constructor - /// - /// DataReader column names - /// DataReader column types - /// Matching constructor or default one - public ConstructorInfo FindConstructor(string[] names, Type[] types) - { - var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - foreach (ConstructorInfo ctor in constructors.OrderBy(c => c.IsPublic ? 0 : (c.IsPrivate ? 2 : 1)).ThenBy(c => c.GetParameters().Length)) - { - ParameterInfo[] ctorParameters = ctor.GetParameters(); - if (ctorParameters.Length == 0) - return ctor; - - if (ctorParameters.Length != types.Length) - continue; - - int i = 0; - for (; i < ctorParameters.Length; i++) - { - if (!String.Equals(ctorParameters[i].Name, names[i], StringComparison.OrdinalIgnoreCase)) - break; - if (types[i] == typeof(byte[]) && ctorParameters[i].ParameterType.FullName == SqlMapper.LinqBinary) - continue; - var unboxedType = Nullable.GetUnderlyingType(ctorParameters[i].ParameterType) ?? ctorParameters[i].ParameterType; - if (unboxedType != types[i] - && !(unboxedType.IsEnum && Enum.GetUnderlyingType(unboxedType) == types[i]) - && !(unboxedType == typeof(char) && types[i] == typeof(string))) - break; - } - - if (i == ctorParameters.Length) - return ctor; - } - - return null; - } - - /// - /// Gets mapping for constructor parameter - /// - /// Constructor to resolve - /// DataReader column name - /// Mapping implementation - public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName) - { - var parameters = constructor.GetParameters(); - - return new SimpleMemberMap(columnName, parameters.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase))); - } - - /// - /// Gets member mapping for column - /// - /// DataReader column name - /// Mapping implementation - public SqlMapper.IMemberMap GetMember(string columnName) - { - var property = _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.Ordinal)) - ?? _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase)); - - if (property == null && MatchNamesWithUnderscores) - { - property = _properties.FirstOrDefault(p => string.Equals(p.Name, columnName.Replace("_", ""), StringComparison.Ordinal)) - ?? _properties.FirstOrDefault(p => string.Equals(p.Name, columnName.Replace("_", ""), StringComparison.OrdinalIgnoreCase)); - } - - if (property != null) - return new SimpleMemberMap(columnName, property); - - var field = _fields.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.Ordinal)) - ?? _fields.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase)); - - if (field == null && MatchNamesWithUnderscores) - { - field = _fields.FirstOrDefault(p => string.Equals(p.Name, columnName.Replace("_", ""), StringComparison.Ordinal)) - ?? _fields.FirstOrDefault(p => string.Equals(p.Name, columnName.Replace("_", ""), StringComparison.OrdinalIgnoreCase)); - } - - if (field != null) - return new SimpleMemberMap(columnName, field); - - return null; - } - /// - /// Should column names like User_Id be allowed to match properties/fields like UserId ? - /// - public static bool MatchNamesWithUnderscores { get; set; } } - - - - /// - /// Implements custom property mapping by user provided criteria (usually presence of some custom attribute with column to member mapping) - /// - sealed partial class CustomPropertyTypeMap : SqlMapper.ITypeMap - { - private readonly Type _type; - private readonly Func _propertySelector; - - /// - /// Creates custom property mapping - /// - /// Target entity type - /// Property selector based on target type and DataReader column name - public CustomPropertyTypeMap(Type type, Func propertySelector) - { - if (type == null) - throw new ArgumentNullException("type"); - - if (propertySelector == null) - throw new ArgumentNullException("propertySelector"); - - _type = type; - _propertySelector = propertySelector; - } - - /// - /// Always returns default constructor - /// - /// DataReader column names - /// DataReader column types - /// Default constructor - public ConstructorInfo FindConstructor(string[] names, Type[] types) - { - return _type.GetConstructor(new Type[0]); - } - - /// - /// Not impelmeneted as far as default constructor used for all cases - /// - /// - /// - /// - public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName) - { - throw new NotSupportedException(); - } - - /// - /// Returns property based on selector strategy - /// - /// DataReader column name - /// Poperty member map - public SqlMapper.IMemberMap GetMember(string columnName) - { - var prop = _propertySelector(_type, columnName); - return prop != null ? new SimpleMemberMap(columnName, prop) : null; - } - } - - // Define DAPPER_MAKE_PRIVATE if you reference Dapper by source - // and you like to make the Dapper types private (in order to avoid - // conflicts with other projects that also reference Dapper by source) -#if !DAPPER_MAKE_PRIVATE - - public partial class SqlMapper - { - } - - public partial class DynamicParameters - { - - } - - public partial class DbString - { - - } - - - public partial class SimpleMemberMap - { - - } - - public partial class DefaultTypeMap - { - - } - - public partial class CustomPropertyTypeMap - { - - } - - public partial class FeatureSupport - { - - } - -#endif - } diff --git a/src/ServiceStack.OrmLite/Dapper/TableValuedParameter.cs b/src/ServiceStack.OrmLite/Dapper/TableValuedParameter.cs new file mode 100644 index 000000000..d115b8769 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/TableValuedParameter.cs @@ -0,0 +1,50 @@ +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Used to pass a DataTable as a TableValuedParameter + /// + internal sealed class TableValuedParameter : SqlMapper.ICustomQueryParameter + { + private readonly DataTable table; + private readonly string typeName; + + /// + /// Create a new instance of . + /// + /// The to create this parameter for + public TableValuedParameter(DataTable table) : this(table, null) { /* run base */ } + + /// + /// Create a new instance of . + /// + /// The to create this parameter for. + /// The name of the type this parameter is for. + public TableValuedParameter(DataTable table, string typeName) + { + this.table = table; + this.typeName = typeName; + } + + void SqlMapper.ICustomQueryParameter.AddParameter(IDbCommand command, string name) + { + var param = command.CreateParameter(); + param.ParameterName = name; + Set(param, table, typeName); + command.Parameters.Add(param); + } + + internal static void Set(IDbDataParameter parameter, DataTable table, string typeName) + { +#pragma warning disable 0618 + parameter.Value = SqlMapper.SanitizeParameterValue(table); +#pragma warning restore 0618 + if (string.IsNullOrEmpty(typeName) && table != null) + { + typeName = table.GetTypeName(); + } + if (!string.IsNullOrEmpty(typeName)) StructuredHelper.ConfigureTVP(parameter, typeName); + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/TypeExtensions.cs b/src/ServiceStack.OrmLite/Dapper/TypeExtensions.cs new file mode 100644 index 000000000..2986af9da --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/TypeExtensions.cs @@ -0,0 +1,11 @@ +using System; +using System.Reflection; + +namespace ServiceStack.OrmLite.Dapper +{ + internal static class TypeExtensions + { + public static MethodInfo GetPublicInstanceMethod(this Type type, string name, Type[] types) + => type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public, null, types, null); + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/UdtTypeHandler.cs b/src/ServiceStack.OrmLite/Dapper/UdtTypeHandler.cs new file mode 100644 index 000000000..0de0ad77b --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/UdtTypeHandler.cs @@ -0,0 +1,39 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + public static partial class SqlMapper + { + /// + /// A type handler for data-types that are supported by the underlying provider, but which need + /// a well-known UdtTypeName to be specified + /// + public class UdtTypeHandler : ITypeHandler + { + private readonly string udtTypeName; + /// + /// Creates a new instance of UdtTypeHandler with the specified . + /// + /// The user defined type name. + public UdtTypeHandler(string udtTypeName) + { + if (string.IsNullOrEmpty(udtTypeName)) throw new ArgumentException("Cannot be null or empty", udtTypeName); + this.udtTypeName = udtTypeName; + } + + object ITypeHandler.Parse(Type destinationType, object value) + { + return value is DBNull ? null : value; + } + + void ITypeHandler.SetValue(IDbDataParameter parameter, object value) + { +#pragma warning disable 0618 + parameter.Value = SanitizeParameterValue(value); +#pragma warning restore 0618 + if(!(value is DBNull)) StructuredHelper.ConfigureUDT(parameter, udtTypeName); + } + } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/WrappedDataReader.cs b/src/ServiceStack.OrmLite/Dapper/WrappedDataReader.cs new file mode 100644 index 000000000..4efeb7406 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/WrappedDataReader.cs @@ -0,0 +1,20 @@ +using System.Data; + +namespace ServiceStack.OrmLite.Dapper +{ + /// + /// Describes a reader that controls the lifetime of both a command and a reader, + /// exposing the downstream command/reader as properties. + /// + public interface IWrappedDataReader : IDataReader + { + /// + /// Obtain the underlying reader + /// + IDataReader Reader { get; } + /// + /// Obtain the underlying command + /// + IDbCommand Command { get; } + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/WrappedReader.cs b/src/ServiceStack.OrmLite/Dapper/WrappedReader.cs new file mode 100644 index 000000000..f052c5b42 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/WrappedReader.cs @@ -0,0 +1,298 @@ +using System; +using System.Collections; +using System.Data; +using System.Data.Common; +using System.IO; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Dapper +{ + internal sealed class DisposedReader : DbDataReader + { + internal static readonly DisposedReader Instance = new DisposedReader(); + private DisposedReader() { } + public override int Depth => 0; + public override int FieldCount => 0; + public override bool IsClosed => true; + public override bool HasRows => false; + public override int RecordsAffected => -1; + public override int VisibleFieldCount => 0; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static T ThrowDisposed() => throw new ObjectDisposedException(nameof(DbDataReader)); + [MethodImpl(MethodImplOptions.NoInlining)] + private async static Task ThrowDisposedAsync() + { + var result = ThrowDisposed(); + await Task.Yield(); // will never hit this - already thrown and handled + return result; + } + public override void Close() { } + public override DataTable GetSchemaTable() => ThrowDisposed(); + public override object InitializeLifetimeService() => ThrowDisposed(); + protected override void Dispose(bool disposing) { } + public override bool GetBoolean(int ordinal) => ThrowDisposed(); + public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) => ThrowDisposed(); + public override float GetFloat(int ordinal) => ThrowDisposed(); + public override short GetInt16(int ordinal) => ThrowDisposed(); + public override byte GetByte(int ordinal) => ThrowDisposed(); + public override char GetChar(int ordinal) => ThrowDisposed(); + public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) => ThrowDisposed(); + public override string GetDataTypeName(int ordinal) => ThrowDisposed(); + public override DateTime GetDateTime(int ordinal) => ThrowDisposed(); + protected override DbDataReader GetDbDataReader(int ordinal) => ThrowDisposed(); + public override decimal GetDecimal(int ordinal) => ThrowDisposed(); + public override double GetDouble(int ordinal) => ThrowDisposed(); + public override IEnumerator GetEnumerator() => ThrowDisposed(); + public override Type GetFieldType(int ordinal) => ThrowDisposed(); + public override T GetFieldValue(int ordinal) => ThrowDisposed(); + public override Task GetFieldValueAsync(int ordinal, CancellationToken cancellationToken) => ThrowDisposedAsync(); + public override Guid GetGuid(int ordinal) => ThrowDisposed(); + public override int GetInt32(int ordinal) => ThrowDisposed(); + public override long GetInt64(int ordinal) => ThrowDisposed(); + public override string GetName(int ordinal) => ThrowDisposed(); + public override int GetOrdinal(string name) => ThrowDisposed(); + public override Type GetProviderSpecificFieldType(int ordinal) => ThrowDisposed(); + public override object GetProviderSpecificValue(int ordinal) => ThrowDisposed(); + public override int GetProviderSpecificValues(object[] values) => ThrowDisposed(); + public override Stream GetStream(int ordinal) => ThrowDisposed(); + public override string GetString(int ordinal) => ThrowDisposed(); + public override TextReader GetTextReader(int ordinal) => ThrowDisposed(); + public override object GetValue(int ordinal) => ThrowDisposed(); + public override int GetValues(object[] values) => ThrowDisposed(); + public override bool IsDBNull(int ordinal) => ThrowDisposed(); + public override Task IsDBNullAsync(int ordinal, CancellationToken cancellationToken) => ThrowDisposedAsync(); + public override bool NextResult() => ThrowDisposed(); + public override bool Read() => ThrowDisposed(); + public override Task NextResultAsync(CancellationToken cancellationToken) => ThrowDisposedAsync(); + public override Task ReadAsync(CancellationToken cancellationToken) => ThrowDisposedAsync(); + public override object this[int ordinal] => ThrowDisposed(); + public override object this[string name] => ThrowDisposed(); + } + + internal static class WrappedReader + { + // the purpose of wrapping here is to allow closing a reader to *also* close + // the command, without having to explicitly hand the command back to the + // caller; what that actually looks like depends on what we get: if we are + // given a DbDataReader, we will surface a DbDataReader; if we are given + // a raw IDataReader, we will surface that; and if null: null + public static IDataReader Create(IDbCommand cmd, IDataReader reader) + { + if (cmd == null) return reader; // no need to wrap if no command + + if (reader is DbDataReader dbr) return new DbWrappedReader(cmd, dbr); + if (reader != null) return new BasicWrappedReader(cmd, reader); + cmd.Dispose(); + return null; // GIGO + } + public static DbDataReader Create(IDbCommand cmd, DbDataReader reader) + { + if (cmd == null) return reader; // no need to wrap if no command + + if (reader != null) return new DbWrappedReader(cmd, reader); + cmd.Dispose(); + return null; // GIGO + } + } + internal sealed class DbWrappedReader : DbDataReader, IWrappedDataReader + { + private DbDataReader _reader; + private IDbCommand _cmd; + + IDataReader IWrappedDataReader.Reader => _reader; + + IDbCommand IWrappedDataReader.Command => _cmd; + + public DbWrappedReader(IDbCommand cmd, DbDataReader reader) + { + _cmd = cmd; + _reader = reader; + } + + public override bool HasRows => _reader.HasRows; + + public override void Close() => _reader.Close(); + public override DataTable GetSchemaTable() => _reader.GetSchemaTable(); + public override object InitializeLifetimeService() => _reader.InitializeLifetimeService(); + + public override int Depth => _reader.Depth; + + public override bool IsClosed => _reader.IsClosed; + + public override bool NextResult() => _reader.NextResult(); + + public override bool Read() => _reader.Read(); + + public override int RecordsAffected => _reader.RecordsAffected; + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _reader.Close(); + _reader.Dispose(); + _reader = DisposedReader.Instance; // all future ops are no-ops + _cmd?.Dispose(); + _cmd = null; + } + } + + public override int FieldCount => _reader.FieldCount; + + public override bool GetBoolean(int i) => _reader.GetBoolean(i); + + public override byte GetByte(int i) => _reader.GetByte(i); + + public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) => + _reader.GetBytes(i, fieldOffset, buffer, bufferoffset, length); + + public override char GetChar(int i) => _reader.GetChar(i); + + public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) => + _reader.GetChars(i, fieldoffset, buffer, bufferoffset, length); + + public override string GetDataTypeName(int i) => _reader.GetDataTypeName(i); + + public override DateTime GetDateTime(int i) => _reader.GetDateTime(i); + + public override decimal GetDecimal(int i) => _reader.GetDecimal(i); + + public override double GetDouble(int i) => _reader.GetDouble(i); + + public override Type GetFieldType(int i) => _reader.GetFieldType(i); + + public override float GetFloat(int i) => _reader.GetFloat(i); + + public override Guid GetGuid(int i) => _reader.GetGuid(i); + + public override short GetInt16(int i) => _reader.GetInt16(i); + + public override int GetInt32(int i) => _reader.GetInt32(i); + + public override long GetInt64(int i) => _reader.GetInt64(i); + + public override string GetName(int i) => _reader.GetName(i); + + public override int GetOrdinal(string name) => _reader.GetOrdinal(name); + + public override string GetString(int i) => _reader.GetString(i); + + public override object GetValue(int i) => _reader.GetValue(i); + + public override int GetValues(object[] values) => _reader.GetValues(values); + + public override bool IsDBNull(int i) => _reader.IsDBNull(i); + + public override object this[string name] => _reader[name]; + + public override object this[int i] => _reader[i]; + + public override T GetFieldValue(int ordinal) => _reader.GetFieldValue(ordinal); + public override Task GetFieldValueAsync(int ordinal, CancellationToken cancellationToken) => _reader.GetFieldValueAsync(ordinal, cancellationToken); + public override IEnumerator GetEnumerator() => _reader.GetEnumerator(); + public override Type GetProviderSpecificFieldType(int ordinal) => _reader.GetProviderSpecificFieldType(ordinal); + public override object GetProviderSpecificValue(int ordinal) => _reader.GetProviderSpecificValue(ordinal); + public override int GetProviderSpecificValues(object[] values) => _reader.GetProviderSpecificValues(values); + public override Stream GetStream(int ordinal) => _reader.GetStream(ordinal); + public override TextReader GetTextReader(int ordinal) => _reader.GetTextReader(ordinal); + public override Task IsDBNullAsync(int ordinal, CancellationToken cancellationToken) => _reader.IsDBNullAsync(ordinal, cancellationToken); + public override Task NextResultAsync(CancellationToken cancellationToken) => _reader.NextResultAsync(cancellationToken); + public override Task ReadAsync(CancellationToken cancellationToken) => _reader.ReadAsync(cancellationToken); + public override int VisibleFieldCount => _reader.VisibleFieldCount; + protected override DbDataReader GetDbDataReader(int ordinal) => (((IDataReader)_reader).GetData(ordinal) as DbDataReader) ?? throw new NotSupportedException(); + } + + internal class BasicWrappedReader : IWrappedDataReader + { + private IDataReader _reader; + private IDbCommand _cmd; + + IDataReader IWrappedDataReader.Reader => _reader; + + IDbCommand IWrappedDataReader.Command => _cmd; + + public BasicWrappedReader(IDbCommand cmd, IDataReader reader) + { + _cmd = cmd; + _reader = reader; + } + + void IDataReader.Close() => _reader.Close(); + + int IDataReader.Depth => _reader.Depth; + + DataTable IDataReader.GetSchemaTable() => _reader.GetSchemaTable(); + + bool IDataReader.IsClosed => _reader.IsClosed; + + bool IDataReader.NextResult() => _reader.NextResult(); + + bool IDataReader.Read() => _reader.Read(); + + int IDataReader.RecordsAffected => _reader.RecordsAffected; + + void IDisposable.Dispose() + { + _reader.Close(); + _reader.Dispose(); + _reader = DisposedReader.Instance; + _cmd?.Dispose(); + _cmd = null; + } + + int IDataRecord.FieldCount => _reader.FieldCount; + + bool IDataRecord.GetBoolean(int i) => _reader.GetBoolean(i); + + byte IDataRecord.GetByte(int i) => _reader.GetByte(i); + + long IDataRecord.GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) => + _reader.GetBytes(i, fieldOffset, buffer, bufferoffset, length); + + char IDataRecord.GetChar(int i) => _reader.GetChar(i); + + long IDataRecord.GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) => + _reader.GetChars(i, fieldoffset, buffer, bufferoffset, length); + + IDataReader IDataRecord.GetData(int i) => _reader.GetData(i); + + string IDataRecord.GetDataTypeName(int i) => _reader.GetDataTypeName(i); + + DateTime IDataRecord.GetDateTime(int i) => _reader.GetDateTime(i); + + decimal IDataRecord.GetDecimal(int i) => _reader.GetDecimal(i); + + double IDataRecord.GetDouble(int i) => _reader.GetDouble(i); + + Type IDataRecord.GetFieldType(int i) => _reader.GetFieldType(i); + + float IDataRecord.GetFloat(int i) => _reader.GetFloat(i); + + Guid IDataRecord.GetGuid(int i) => _reader.GetGuid(i); + + short IDataRecord.GetInt16(int i) => _reader.GetInt16(i); + + int IDataRecord.GetInt32(int i) => _reader.GetInt32(i); + + long IDataRecord.GetInt64(int i) => _reader.GetInt64(i); + + string IDataRecord.GetName(int i) => _reader.GetName(i); + + int IDataRecord.GetOrdinal(string name) => _reader.GetOrdinal(name); + + string IDataRecord.GetString(int i) => _reader.GetString(i); + + object IDataRecord.GetValue(int i) => _reader.GetValue(i); + + int IDataRecord.GetValues(object[] values) => _reader.GetValues(values); + + bool IDataRecord.IsDBNull(int i) => _reader.IsDBNull(i); + + object IDataRecord.this[string name] => _reader[name]; + + object IDataRecord.this[int i] => _reader[i]; + } +} diff --git a/src/ServiceStack.OrmLite/Dapper/XmlHandlers.cs b/src/ServiceStack.OrmLite/Dapper/XmlHandlers.cs new file mode 100644 index 000000000..de6771f40 --- /dev/null +++ b/src/ServiceStack.OrmLite/Dapper/XmlHandlers.cs @@ -0,0 +1,39 @@ +using System.Data; +using System.Xml; +using System.Xml.Linq; + +namespace ServiceStack.OrmLite.Dapper +{ + internal abstract class XmlTypeHandler : SqlMapper.StringTypeHandler + { + public override void SetValue(IDbDataParameter parameter, T value) + { + base.SetValue(parameter, value); + parameter.DbType = DbType.Xml; + } + } + + internal sealed class XmlDocumentHandler : XmlTypeHandler + { + protected override XmlDocument Parse(string xml) + { + var doc = new XmlDocument(); + doc.LoadXml(xml); + return doc; + } + + protected override string Format(XmlDocument xml) => xml.OuterXml; + } + + internal sealed class XDocumentHandler : XmlTypeHandler + { + protected override XDocument Parse(string xml) => XDocument.Parse(xml); + protected override string Format(XDocument xml) => xml.ToString(); + } + + internal sealed class XElementHandler : XmlTypeHandler + { + protected override XElement Parse(string xml) => XElement.Parse(xml); + protected override string Format(XElement xml) => xml.ToString(); + } +} diff --git a/src/ServiceStack.OrmLite/DbScripts.cs b/src/ServiceStack.OrmLite/DbScripts.cs new file mode 100644 index 000000000..e053c1479 --- /dev/null +++ b/src/ServiceStack.OrmLite/DbScripts.cs @@ -0,0 +1,312 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using ServiceStack.Data; +using ServiceStack.Script; + +namespace ServiceStack.OrmLite +{ + [Obsolete("Use DbScriptsAsync")] + public class DbScripts : ScriptMethods + { + private const string DbInfo = "__dbinfo"; // Keywords.DbInfo + private const string DbConnection = "__dbconnection"; // useDb global + + private IDbConnectionFactory dbFactory; + public IDbConnectionFactory DbFactory + { + get => dbFactory ??= Context.Container.Resolve(); + set => dbFactory = value; + } + + public IDbConnection OpenDbConnection(ScriptScopeContext scope, Dictionary options) + { + var dbConn = OpenDbConnectionFromOptions(options); + if (dbConn != null) + return dbConn; + + if (scope.PageResult != null) + { + if (scope.PageResult.Args.TryGetValue(DbInfo, out var oDbInfo) && oDbInfo is ConnectionInfo dbInfo) + return DbFactory.OpenDbConnection(dbInfo); + + if (scope.PageResult.Args.TryGetValue(DbConnection, out var oDbConn) && oDbConn is Dictionary globalDbConn) + return OpenDbConnectionFromOptions(globalDbConn); + } + + return DbFactory.OpenDbConnection(); + } + + T dialect(ScriptScopeContext scope, Func fn) + { + if (scope.PageResult != null) + { + if (scope.PageResult.Args.TryGetValue(DbInfo, out var oDbInfo) && oDbInfo is ConnectionInfo dbInfo) + return fn(DbFactory.GetDialectProvider(dbInfo)); + + if (scope.PageResult.Args.TryGetValue(DbConnection, out var oDbConn) && oDbConn is Dictionary useDb) + return fn(DbFactory.GetDialectProvider( + providerName:useDb.GetValueOrDefault("providerName")?.ToString(), + namedConnection:useDb.GetValueOrDefault("namedConnection")?.ToString())); + } + return fn(OrmLiteConfig.DialectProvider); + } + + public IgnoreResult useDb(ScriptScopeContext scope, Dictionary dbConnOptions) + { + if (dbConnOptions == null) + { + scope.PageResult.Args.Remove(DbConnection); + } + else + { + if (!dbConnOptions.ContainsKey("connectionString") && !dbConnOptions.ContainsKey("namedConnection")) + throw new NotSupportedException(nameof(useDb) + " requires either 'connectionString' or 'namedConnection' property"); + + scope.PageResult.Args[DbConnection] = dbConnOptions; + } + return IgnoreResult.Value; + } + + private IDbConnection OpenDbConnectionFromOptions(Dictionary options) + { + if (options != null) + { + if (options.TryGetValue("connectionString", out var connectionString)) + { + return options.TryGetValue("providerName", out var providerName) + ? DbFactory.OpenDbConnectionString((string) connectionString, (string) providerName) + : DbFactory.OpenDbConnectionString((string) connectionString); + } + + if (options.TryGetValue("namedConnection", out var namedConnection)) + { + return DbFactory.OpenDbConnection((string) namedConnection); + } + } + + return null; + } + + T exec(Func fn, ScriptScopeContext scope, object options) + { + try + { + using var db = OpenDbConnection(scope, options as Dictionary); + return fn(db); + } + catch (Exception ex) + { + throw new StopFilterExecutionException(scope, options, ex); + } + } + + public object dbSelect(ScriptScopeContext scope, string sql) => + exec(db => db.SqlList>(sql), scope, null); + + public object dbSelect(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.SqlList>(sql, args), scope, null); + + public object dbSelect(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.SqlList>(sql, args), scope, options); + + + public object dbSingle(ScriptScopeContext scope, string sql) => + exec(db => db.Single>(sql), scope, null); + + public object dbSingle(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.Single>(sql, args), scope, null); + + public object dbSingle(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.Single>(sql, args), scope, options); + + + public object dbScalar(ScriptScopeContext scope, string sql) => + exec(db => db.Scalar(sql), scope, null); + + public object dbScalar(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.Scalar(sql, args), scope, null); + + public object dbScalar(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.Scalar(sql, args), scope, options); + + + public long dbCount(ScriptScopeContext scope, string sql) => + exec(db => db.RowCount(sql), scope, null); + + public long dbCount(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.RowCount(sql, args), scope, null); + + public long dbCount(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.RowCount(sql, args), scope, options); + + + public bool dbExists(ScriptScopeContext scope, string sql) => + dbScalar(scope, sql) != null; + + public bool dbExists(ScriptScopeContext scope, string sql, Dictionary args) => + dbScalar(scope, sql, args) != null; + + public bool dbExists(ScriptScopeContext scope, string sql, Dictionary args, object options) => + dbScalar(scope, sql, args, options) != null; + + + public int dbExec(ScriptScopeContext scope, string sql) => + exec(db => db.ExecuteSql(sql), scope, null); + + public int dbExec(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.ExecuteSql(sql, args), scope, null); + + public int dbExec(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.ExecuteSql(sql, args), scope, options); + + public List dbNamedConnections() => OrmLiteConnectionFactory.NamedConnections.Keys.ToList(); + public List dbTableNames(ScriptScopeContext scope) => dbTableNames(scope, null, null); + public List dbTableNames(ScriptScopeContext scope, Dictionary args) => dbTableNames(scope, args, null); + public List dbTableNames(ScriptScopeContext scope, Dictionary args, object options) => + exec(db => db.GetTableNames(args != null && args.TryGetValue("schema", out var oSchema) ? oSchema as string : null), scope, options); + + public List> dbTableNamesWithRowCounts(ScriptScopeContext scope) => + dbTableNamesWithRowCounts(scope, null, null); + public List> dbTableNamesWithRowCounts(ScriptScopeContext scope, Dictionary args) => + dbTableNamesWithRowCounts(scope, args, null); + public List> dbTableNamesWithRowCounts(ScriptScopeContext scope, Dictionary args, object options) => + exec(db => args == null + ? db.GetTableNamesWithRowCounts() + : db.GetTableNamesWithRowCounts( + live: args.TryGetValue("live", out var oLive) && oLive is bool b && b, + schema: args.TryGetValue("schema", out var oSchema) ? oSchema as string : null), + scope, options); + + public string[] dbColumnNames(ScriptScopeContext scope, string tableName) => dbColumnNames(scope, tableName, null); + public string[] dbColumnNames(ScriptScopeContext scope, string tableName, object options) => + dbColumns(scope, tableName, options).Select(x => x.ColumnName).ToArray(); + + public ColumnSchema[] dbColumns(ScriptScopeContext scope, string tableName) => dbColumns(scope, tableName, null); + public ColumnSchema[] dbColumns(ScriptScopeContext scope, string tableName, object options) => + exec(db => db.GetTableColumns($"SELECT * FROM {sqlQuote(scope,tableName)}"), scope, options); + + public ColumnSchema[] dbDesc(ScriptScopeContext scope, string sql) => dbDesc(scope, sql, null); + public ColumnSchema[] dbDesc(ScriptScopeContext scope, string sql, object options) => exec(db => db.GetTableColumns(sql), scope, options); + + + public string sqlQuote(ScriptScopeContext scope, string name) => dialect(scope, d => d.GetQuotedName(name)); + public string sqlConcat(ScriptScopeContext scope, IEnumerable values) => dialect(scope, d => d.SqlConcat(values)); + public string sqlCurrency(ScriptScopeContext scope, string fieldOrValue) => dialect(scope, d => d.SqlCurrency(fieldOrValue)); + public string sqlCurrency(ScriptScopeContext scope, string fieldOrValue, string symbol) => + dialect(scope, d => d.SqlCurrency(fieldOrValue, symbol)); + + public string sqlCast(ScriptScopeContext scope, object fieldOrValue, string castAs) => + dialect(scope, d => d.SqlCast(fieldOrValue, castAs)); + public string sqlBool(ScriptScopeContext scope, bool value) => dialect(scope, d => d.SqlBool(value)); + public string sqlTrue(ScriptScopeContext scope) => dialect(scope, d => d.SqlBool(true)); + public string sqlFalse(ScriptScopeContext scope) => dialect(scope, d => d.SqlBool(false)); + public string sqlLimit(ScriptScopeContext scope, int? offset, int? limit) => + dialect(scope, d => padCondition(d.SqlLimit(offset, limit))); + public string sqlLimit(ScriptScopeContext scope, int? limit) => + dialect(scope, d => padCondition(d.SqlLimit(null, limit))); + public string sqlSkip(ScriptScopeContext scope, int? offset) => + dialect(scope, d => padCondition(d.SqlLimit(offset, null))); + public string sqlTake(ScriptScopeContext scope, int? limit) => + dialect(scope, d => padCondition(d.SqlLimit(null, limit))); + public string sqlOrderByFields(ScriptScopeContext scope, string orderBy) => + dialect(scope, d => OrmLiteUtils.OrderByFields(d, orderBy)); + public string ormliteVar(ScriptScopeContext scope, string name) => + dialect(scope, d => d.Variables.TryGetValue(name, out var value) ? value : null); + + public string sqlVerifyFragment(string sql) => sql.SqlVerifyFragment(); + public bool isUnsafeSql(string sql) => OrmLiteUtils.isUnsafeSql(sql, OrmLiteUtils.VerifySqlRegEx); + public bool isUnsafeSqlFragment(string sql) => OrmLiteUtils.isUnsafeSql(sql, OrmLiteUtils.VerifyFragmentRegEx); + + private string padCondition(string text) => string.IsNullOrEmpty(text) ? "" : " " + text; + } + + public partial class DbScriptsAsync + { + private DbScripts sync; + private DbScripts Sync => sync ??= new DbScripts { Context = Context, Pages = Pages }; + + public object dbSelectSync(ScriptScopeContext scope, string sql) => Sync.dbSelect(scope, sql); + + public object dbSelectSync(ScriptScopeContext scope, string sql, Dictionary args) => + Sync.dbSelect(scope, sql, args); + + public object dbSelectSync(ScriptScopeContext scope, string sql, Dictionary args, object options) => + Sync.dbSelect(scope, sql, args, options); + + + public object dbSingleSync(ScriptScopeContext scope, string sql) => + Sync.dbSingle(scope, sql); + + public object dbSingleSync(ScriptScopeContext scope, string sql, Dictionary args) => + Sync.dbSingle(scope, sql, args); + + public object dbSingleSync(ScriptScopeContext scope, string sql, Dictionary args, object options) => + Sync.dbSingle(scope, sql, args, options); + + + public object dbScalarSync(ScriptScopeContext scope, string sql) => + Sync.dbScalar(scope, sql); + + public object dbScalarSync(ScriptScopeContext scope, string sql, Dictionary args) => + Sync.dbScalar(scope, sql, args); + + public object dbScalarSync(ScriptScopeContext scope, string sql, Dictionary args, object options) => + Sync.dbScalar(scope, sql, args, options); + + + public long dbCountSync(ScriptScopeContext scope, string sql) => + Sync.dbCount(scope, sql); + + public long dbCountSync(ScriptScopeContext scope, string sql, Dictionary args) => + Sync.dbCount(scope, sql, args); + + public long dbCountSync(ScriptScopeContext scope, string sql, Dictionary args, object options) => + Sync.dbCount(scope, sql, args, options); + + + public bool dbExistsSync(ScriptScopeContext scope, string sql) => + Sync.dbExists(scope, sql); + + public bool dbExistsSync(ScriptScopeContext scope, string sql, Dictionary args) => + Sync.dbExists(scope, sql, args); + + public bool dbExistsSync(ScriptScopeContext scope, string sql, Dictionary args, object options) => + Sync.dbExists(scope, sql, args, options); + + + public int dbExecSync(ScriptScopeContext scope, string sql) => + Sync.dbExec(scope, sql); + + public int dbExecSync(ScriptScopeContext scope, string sql, Dictionary args) => + Sync.dbExec(scope, sql, args); + + public int dbExecSync(ScriptScopeContext scope, string sql, Dictionary args, object options) => + Sync.dbExec(scope, sql, args, options); + + public List dbTableNamesSync(ScriptScopeContext scope) => dbTableNamesSync(scope, null, null); + public List dbTableNamesSync(ScriptScopeContext scope, Dictionary args) => dbTableNamesSync(scope, args, null); + public List dbTableNamesSync(ScriptScopeContext scope, Dictionary args, object options) => + Sync.dbTableNames(scope, args, options); + + public List> dbTableNamesWithRowCountsSync(ScriptScopeContext scope) => + dbTableNamesWithRowCountsSync(scope, null, null); + public List> dbTableNamesWithRowCountsSync(ScriptScopeContext scope, Dictionary args) => + dbTableNamesWithRowCountsSync(scope, args, null); + public List> dbTableNamesWithRowCountsSync(ScriptScopeContext scope, Dictionary args, object options) => + Sync.dbTableNamesWithRowCounts(scope, args, options); + + public string[] dbColumnNamesSync(ScriptScopeContext scope, string tableName) => dbColumnNamesSync(scope, tableName, null); + public string[] dbColumnNamesSync(ScriptScopeContext scope, string tableName, object options) => + dbColumnsSync(scope, tableName, options).Select(x => x.ColumnName).ToArray(); + + public ColumnSchema[] dbColumnsSync(ScriptScopeContext scope, string tableName) => dbColumnsSync(scope, tableName, null); + public ColumnSchema[] dbColumnsSync(ScriptScopeContext scope, string tableName, object options) => + Sync.dbColumns(scope, tableName, options); + + public ColumnSchema[] dbDescSync(ScriptScopeContext scope, string sql) => dbDescSync(scope, sql, null); + public ColumnSchema[] dbDescSync(ScriptScopeContext scope, string sql, object options) => + Sync.dbDesc(scope, sql, options); + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/DbScriptsAsync.cs b/src/ServiceStack.OrmLite/DbScriptsAsync.cs new file mode 100644 index 000000000..f65bbd3e9 --- /dev/null +++ b/src/ServiceStack.OrmLite/DbScriptsAsync.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using ServiceStack.Data; +using ServiceStack.Script; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite +{ + public partial class DbScriptsAsync : ScriptMethods + { + private const string DbInfo = "__dbinfo"; // Keywords.DbInfo + private const string DbConnection = "__dbconnection"; // useDb global + + private IDbConnectionFactory dbFactory; + public IDbConnectionFactory DbFactory + { + get => dbFactory ??= Context.Container.Resolve(); + set => dbFactory = value; + } + + public async Task OpenDbConnectionAsync(ScriptScopeContext scope, Dictionary options) + { + var dbConn = await OpenDbConnectionFromOptionsAsync(options).ConfigAwait(); + if (dbConn != null) + return dbConn; + + if (scope.PageResult != null) + { + if (scope.PageResult.Args.TryGetValue(DbInfo, out var oDbInfo) && oDbInfo is ConnectionInfo dbInfo) + return await DbFactory.OpenDbConnectionAsync(dbInfo); + + if (scope.PageResult.Args.TryGetValue(DbConnection, out var oDbConn) && oDbConn is Dictionary globalDbConn) + return await OpenDbConnectionFromOptionsAsync(globalDbConn); + } + + return await DbFactory.OpenAsync(); + } + + T dialect(ScriptScopeContext scope, Func fn) + { + if (scope.PageResult != null) + { + if (scope.PageResult.Args.TryGetValue(DbInfo, out var oDbInfo) && oDbInfo is ConnectionInfo dbInfo) + return fn(DbFactory.GetDialectProvider(dbInfo)); + + if (scope.PageResult.Args.TryGetValue(DbConnection, out var oDbConn) && oDbConn is Dictionary useDb) + return fn(DbFactory.GetDialectProvider( + providerName:useDb.GetValueOrDefault("providerName")?.ToString(), + namedConnection:useDb.GetValueOrDefault("namedConnection")?.ToString())); + } + return fn(OrmLiteConfig.DialectProvider); + } + + public IgnoreResult useDb(ScriptScopeContext scope, Dictionary dbConnOptions) + { + if (dbConnOptions == null) + { + scope.PageResult.Args.Remove(DbConnection); + } + else + { + if (!dbConnOptions.ContainsKey("connectionString") && !dbConnOptions.ContainsKey("namedConnection")) + throw new NotSupportedException(nameof(useDb) + " requires either 'connectionString' or 'namedConnection' property"); + + scope.PageResult.Args[DbConnection] = dbConnOptions; + } + return IgnoreResult.Value; + } + + private async Task OpenDbConnectionFromOptionsAsync(Dictionary options) + { + if (options != null) + { + if (options.TryGetValue("connectionString", out var connectionString)) + { + return options.TryGetValue("providerName", out var providerName) + ? await DbFactory.OpenDbConnectionStringAsync((string) connectionString, (string) providerName).ConfigAwait() + : await DbFactory.OpenDbConnectionStringAsync((string) connectionString).ConfigAwait(); + } + + if (options.TryGetValue("namedConnection", out var namedConnection)) + { + return await DbFactory.OpenDbConnectionAsync((string) namedConnection).ConfigAwait(); + } + } + + return null; + } + + async Task exec(Func> fn, ScriptScopeContext scope, object options) + { + try + { + using var db = await OpenDbConnectionAsync(scope, options as Dictionary).ConfigAwait(); + var result = await fn(db).ConfigAwait(); + return result; + } + catch (Exception ex) + { + throw new StopFilterExecutionException(scope, options, ex); + } + } + + public Task dbSelect(ScriptScopeContext scope, string sql) => + exec(db => db.SqlListAsync>(sql), scope, null); + + public Task dbSelect(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.SqlListAsync>(sql, args), scope, null); + + public Task dbSelect(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.SqlListAsync>(sql, args), scope, options); + + + public Task dbSingle(ScriptScopeContext scope, string sql) => + exec(db => db.SingleAsync>(sql), scope, null); + + public Task dbSingle(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.SingleAsync>(sql, args), scope, null); + + public Task dbSingle(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.SingleAsync>(sql, args), scope, options); + + + public Task dbScalar(ScriptScopeContext scope, string sql) => + exec(db => db.ScalarAsync(sql), scope, null); + + public Task dbScalar(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.ScalarAsync(sql, args), scope, null); + + public Task dbScalar(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.ScalarAsync(sql, args), scope, options); + + + public Task dbCount(ScriptScopeContext scope, string sql) => + exec(db => db.RowCountAsync(sql), scope, null); + + public Task dbCount(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.RowCountAsync(sql, args), scope, null); + + public Task dbCount(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.RowCountAsync(sql, args), scope, options); + + + public async Task dbExists(ScriptScopeContext scope, string sql) => + await dbScalar(scope, sql).ConfigAwait() != null; + + public async Task dbExists(ScriptScopeContext scope, string sql, Dictionary args) => + await dbScalar(scope, sql, args).ConfigAwait() != null; + + public async Task dbExists(ScriptScopeContext scope, string sql, Dictionary args, object options) => + await dbScalar(scope, sql, args, options).ConfigAwait() != null; + + + public Task dbExec(ScriptScopeContext scope, string sql) => + exec(db => db.ExecuteSqlAsync(sql), scope, null); + + public Task dbExec(ScriptScopeContext scope, string sql, Dictionary args) => + exec(db => db.ExecuteSqlAsync(sql, args), scope, null); + + public Task dbExec(ScriptScopeContext scope, string sql, Dictionary args, object options) => + exec(db => db.ExecuteSqlAsync(sql, args), scope, options); + + public List dbNamedConnections() => OrmLiteConnectionFactory.NamedConnections.Keys.ToList(); + public Task dbTableNames(ScriptScopeContext scope) => dbTableNames(scope, null, null); + public Task dbTableNames(ScriptScopeContext scope, Dictionary args) => dbTableNames(scope, args, null); + public Task dbTableNames(ScriptScopeContext scope, Dictionary args, object options) => + exec(db => db.GetTableNamesAsync(args != null && args.TryGetValue("schema", out var oSchema) ? oSchema as string : null), scope, options); + + public Task dbTableNamesWithRowCounts(ScriptScopeContext scope) => + dbTableNamesWithRowCounts(scope, null, null); + public Task dbTableNamesWithRowCounts(ScriptScopeContext scope, Dictionary args) => + dbTableNamesWithRowCounts(scope, args, null); + public Task dbTableNamesWithRowCounts(ScriptScopeContext scope, Dictionary args, object options) => + exec(db => args == null + ? db.GetTableNamesWithRowCountsAsync() + : db.GetTableNamesWithRowCountsAsync( + live: args.TryGetValue("live", out var oLive) && oLive is bool b && b, + schema: args.TryGetValue("schema", out var oSchema) ? oSchema as string : null), + scope, options); + + public Task dbColumnNames(ScriptScopeContext scope, string tableName) => dbColumnNames(scope, tableName, null); + public Task dbColumnNames(ScriptScopeContext scope, string tableName, object options) => + exec(async db => (await db.GetTableColumnsAsync($"SELECT * FROM {sqlQuote(scope,tableName)}").ConfigAwait()) + .Select(x => x.ColumnName).ToArray(), scope, options); + + public Task dbColumns(ScriptScopeContext scope, string tableName) => dbColumns(scope, tableName, null); + public Task dbColumns(ScriptScopeContext scope, string tableName, object options) => + exec(db => db.GetTableColumnsAsync($"SELECT * FROM {sqlQuote(scope,tableName)}"), scope, options); + + public Task dbDesc(ScriptScopeContext scope, string sql) => dbDesc(scope, sql, null); + public Task dbDesc(ScriptScopeContext scope, string sql, object options) => exec(db => db.GetTableColumnsAsync(sql), scope, options); + + public string sqlQuote(ScriptScopeContext scope, string name) => dialect(scope, d => d.GetQuotedName(name)); + public string sqlConcat(ScriptScopeContext scope, IEnumerable values) => dialect(scope, d => d.SqlConcat(values)); + public string sqlCurrency(ScriptScopeContext scope, string fieldOrValue) => dialect(scope, d => d.SqlCurrency(fieldOrValue)); + public string sqlCurrency(ScriptScopeContext scope, string fieldOrValue, string symbol) => + dialect(scope, d => d.SqlCurrency(fieldOrValue, symbol)); + + public string sqlCast(ScriptScopeContext scope, object fieldOrValue, string castAs) => + dialect(scope, d => d.SqlCast(fieldOrValue, castAs)); + public string sqlBool(ScriptScopeContext scope, bool value) => dialect(scope, d => d.SqlBool(value)); + public string sqlTrue(ScriptScopeContext scope) => dialect(scope, d => d.SqlBool(true)); + public string sqlFalse(ScriptScopeContext scope) => dialect(scope, d => d.SqlBool(false)); + public string sqlLimit(ScriptScopeContext scope, int? offset, int? limit) => + dialect(scope, d => padCondition(d.SqlLimit(offset, limit))); + public string sqlLimit(ScriptScopeContext scope, int? limit) => + dialect(scope, d => padCondition(d.SqlLimit(null, limit))); + public string sqlSkip(ScriptScopeContext scope, int? offset) => + dialect(scope, d => padCondition(d.SqlLimit(offset, null))); + public string sqlTake(ScriptScopeContext scope, int? limit) => + dialect(scope, d => padCondition(d.SqlLimit(null, limit))); + public string sqlOrderByFields(ScriptScopeContext scope, string orderBy) => + dialect(scope, d => OrmLiteUtils.OrderByFields(d, orderBy)); + public string ormliteVar(ScriptScopeContext scope, string name) => + dialect(scope, d => d.Variables.TryGetValue(name, out var value) ? value : null); + + public string sqlVerifyFragment(string sql) => sql.SqlVerifyFragment(); + public bool isUnsafeSql(string sql) => OrmLiteUtils.isUnsafeSql(sql, OrmLiteUtils.VerifySqlRegEx); + public bool isUnsafeSqlFragment(string sql) => OrmLiteUtils.isUnsafeSql(sql, OrmLiteUtils.VerifyFragmentRegEx); + + private string padCondition(string text) => string.IsNullOrEmpty(text) ? "" : " " + text; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/DbValues.cs b/src/ServiceStack.OrmLite/DbValues.cs new file mode 100644 index 000000000..987b63c6d --- /dev/null +++ b/src/ServiceStack.OrmLite/DbValues.cs @@ -0,0 +1,18 @@ +namespace ServiceStack.OrmLite +{ + public struct XmlValue + { + public string Xml { get; } + public XmlValue(string xml) => Xml = xml; + public override string ToString() => Xml; + + public bool Equals(XmlValue other) => Xml == other.Xml; + + public override bool Equals(object obj) => obj is XmlValue other && Equals(other); + + public override int GetHashCode() => Xml != null ? Xml.GetHashCode() : 0; + + public static implicit operator XmlValue(string expandedName) => + expandedName != null ? new XmlValue(expandedName) : null; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/DictionaryRow.cs b/src/ServiceStack.OrmLite/DictionaryRow.cs new file mode 100644 index 000000000..ac951dead --- /dev/null +++ b/src/ServiceStack.OrmLite/DictionaryRow.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace ServiceStack.OrmLite +{ + public interface IDynamicRow + { + Type Type { get; } + } + + public interface IDynamicRow : IDynamicRow + { + T Fields { get; } + } + + public struct DictionaryRow : IDynamicRow> + { + public Type Type { get; } + public Dictionary Fields { get; } + + public DictionaryRow(Type type, Dictionary fields) + { + Type = type; + Fields = fields; + } + } + + public struct ObjectRow : IDynamicRow + { + public Type Type { get; } + public object Fields { get; } + + public ObjectRow(Type type, object fields) + { + Type = type; + Fields = fields; + } + } + + public static class DynamicRowUtils + { + internal static object ToFilterType(this object row) => ToFilterType(row, typeof(T)); + + internal static object ToFilterType(this object row, Type type) => row == null + ? null + : type.IsInstanceOfType(row) + ? row + : row switch { + Dictionary obj => new DictionaryRow(type, obj), + _ => new ObjectRow(type, row), + }; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Expressions/IUntypedSqlExpression.cs b/src/ServiceStack.OrmLite/Expressions/IUntypedSqlExpression.cs new file mode 100644 index 000000000..8bb76cd55 --- /dev/null +++ b/src/ServiceStack.OrmLite/Expressions/IUntypedSqlExpression.cs @@ -0,0 +1,706 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; + +namespace ServiceStack.OrmLite +{ + public interface IHasUntypedSqlExpression + { + IUntypedSqlExpression GetUntyped(); + } + + public interface IUntypedSqlExpression : ISqlExpression + { + string TableAlias { get; set; } + bool PrefixFieldWithTableName { get; set; } + bool WhereStatementWithoutWhereString { get; set; } + IOrmLiteDialectProvider DialectProvider { get; set; } + string SelectExpression { get; set; } + string FromExpression { get; set; } + string BodyExpression { get; } + string WhereExpression { get; set; } + string GroupByExpression { get; set; } + string HavingExpression { get; set; } + string OrderByExpression { get; set; } + int? Rows { get; set; } + int? Offset { get; set; } + List UpdateFields { get; set; } + List InsertFields { get; set; } + ModelDefinition ModelDef { get; } + IUntypedSqlExpression Clone(); + + IUntypedSqlExpression Select(); + IUntypedSqlExpression Select(string selectExpression); + IUntypedSqlExpression UnsafeSelect(string rawSelect); + + IUntypedSqlExpression Select(Expression> fields); + IUntypedSqlExpression Select(Expression> fields); + IUntypedSqlExpression SelectDistinct(Expression> fields); + IUntypedSqlExpression SelectDistinct(Expression> fields); + IUntypedSqlExpression SelectDistinct(); + IUntypedSqlExpression From(string tables); + IUntypedSqlExpression UnsafeFrom(string rawFrom); + IUntypedSqlExpression Where(); + IUntypedSqlExpression UnsafeWhere(string rawSql, params object[] filterParams); + IUntypedSqlExpression Ensure(string sqlFilter, params object[] filterParams); + IUntypedSqlExpression Where(string sqlFilter, params object[] filterParams); + IUntypedSqlExpression UnsafeAnd(string rawSql, params object[] filterParams); + IUntypedSqlExpression And(string sqlFilter, params object[] filterParams); + IUntypedSqlExpression UnsafeOr(string rawSql, params object[] filterParams); + IUntypedSqlExpression Or(string sqlFilter, params object[] filterParams); + IUntypedSqlExpression AddCondition(string condition, string sqlFilter, params object[] filterParams); + IUntypedSqlExpression GroupBy(); + IUntypedSqlExpression GroupBy(string groupBy); + IUntypedSqlExpression Having(); + IUntypedSqlExpression Having(string sqlFilter, params object[] filterParams); + IUntypedSqlExpression OrderBy(); + IUntypedSqlExpression OrderBy(string orderBy); + ModelDefinition GetModelDefinition(FieldDefinition fieldDef); + IUntypedSqlExpression OrderByFields(params FieldDefinition[] fields); + IUntypedSqlExpression OrderByFieldsDescending(params FieldDefinition[] fields); + IUntypedSqlExpression OrderByFields(params string[] fieldNames); + IUntypedSqlExpression OrderByFieldsDescending(params string[] fieldNames); + IUntypedSqlExpression OrderBy
(Expression> keySelector); + IUntypedSqlExpression ThenBy(string orderBy); + IUntypedSqlExpression ThenBy
(Expression> keySelector); + IUntypedSqlExpression OrderByDescending
(Expression> keySelector); + IUntypedSqlExpression OrderByDescending(string orderBy); + IUntypedSqlExpression ThenByDescending(string orderBy); + IUntypedSqlExpression ThenByDescending
(Expression> keySelector); + + IUntypedSqlExpression Skip(int? skip = null); + IUntypedSqlExpression Take(int? take = null); + IUntypedSqlExpression Limit(int skip, int rows); + IUntypedSqlExpression Limit(int? skip, int? rows); + IUntypedSqlExpression Limit(int rows); + IUntypedSqlExpression Limit(); + IUntypedSqlExpression ClearLimits(); + IUntypedSqlExpression Update(List updateFields); + IUntypedSqlExpression Update(); + IUntypedSqlExpression Insert(List insertFields); + IUntypedSqlExpression Insert(); + + IDbDataParameter CreateParam(string name, object value = null, ParameterDirection direction = ParameterDirection.Input, DbType? dbType = null); + IUntypedSqlExpression Join(Expression> joinExpr = null); + IUntypedSqlExpression Join(Type sourceType, Type targetType, Expression joinExpr = null); + IUntypedSqlExpression LeftJoin(Expression> joinExpr = null); + IUntypedSqlExpression LeftJoin(Type sourceType, Type targetType, Expression joinExpr = null); + IUntypedSqlExpression RightJoin(Expression> joinExpr = null); + IUntypedSqlExpression FullJoin(Expression> joinExpr = null); + IUntypedSqlExpression CrossJoin(Expression> joinExpr = null); + IUntypedSqlExpression CustomJoin(string joinString); + IUntypedSqlExpression Ensure(Expression> predicate); + IUntypedSqlExpression Ensure(Expression> predicate); + IUntypedSqlExpression Where(Expression> predicate); + IUntypedSqlExpression Where(Expression> predicate); + IUntypedSqlExpression And(Expression> predicate); + IUntypedSqlExpression And(Expression> predicate); + IUntypedSqlExpression Or(Expression> predicate); + IUntypedSqlExpression Or(Expression> predicate); + + string SqlTable(ModelDefinition modelDef); + string SqlColumn(string columnName); + string ToDeleteRowStatement(); + string ToCountStatement(); + IList GetAllFields(); + Tuple FirstMatchingField(string fieldName); + } + + public class UntypedSqlExpressionProxy : IUntypedSqlExpression + { + private SqlExpression q; + public UntypedSqlExpressionProxy(SqlExpression q) + { + this.q = q; + } + + public string TableAlias + { + get => q.TableAlias; + set => q.TableAlias = value; + } + + public bool PrefixFieldWithTableName + { + get => q.PrefixFieldWithTableName; + set => q.PrefixFieldWithTableName = value; + } + + public bool WhereStatementWithoutWhereString + { + get => q.WhereStatementWithoutWhereString; + set => q.WhereStatementWithoutWhereString = value; + } + + public IOrmLiteDialectProvider DialectProvider + { + get => q.DialectProvider; + set => q.DialectProvider = value; + } + + public List Params + { + get => q.Params; + set => q.Params = value; + } + + public string SelectExpression + { + get => q.SelectExpression; + set => q.SelectExpression = value; + } + + public string FromExpression + { + get => q.FromExpression; + set => q.FromExpression = value; + } + + public string BodyExpression => q.BodyExpression; + + public string WhereExpression + { + get => q.WhereExpression; + set => q.WhereExpression = value; + } + + public string GroupByExpression + { + get => q.GroupByExpression; + set => q.GroupByExpression = value; + } + + public string HavingExpression + { + get => q.HavingExpression; + set => q.HavingExpression = value; + } + + public string OrderByExpression + { + get => q.OrderByExpression; + set => q.OrderByExpression = value; + } + + public int? Rows + { + get => q.Rows; + set => q.Rows = value; + } + + public int? Offset + { + get => q.Offset; + set => q.Offset = value; + } + + public List UpdateFields + { + get => q.UpdateFields; + set => q.UpdateFields = value; + } + + public List InsertFields + { + get => q.InsertFields; + set => q.InsertFields = value; + } + + public ModelDefinition ModelDef => q.ModelDef; + + + public IUntypedSqlExpression Clone() + { + q.Clone(); + return this; + } + + public IUntypedSqlExpression Select() + { + q.Select(); + return this; + } + + public IUntypedSqlExpression Select(string selectExpression) + { + q.Select(selectExpression); + return this; + } + + public IUntypedSqlExpression UnsafeSelect(string rawSelect) + { + q.UnsafeSelect(rawSelect); + return this; + } + + public IUntypedSqlExpression Select(Expression> fields) + { + q.Select(fields); + return this; + } + + public IUntypedSqlExpression Select(Expression> fields) + { + q.Select(fields); + return this; + } + + public IUntypedSqlExpression SelectDistinct(Expression> fields) + { + q.SelectDistinct(fields); + return this; + } + + public IUntypedSqlExpression SelectDistinct(Expression> fields) + { + q.SelectDistinct(fields); + return this; + } + + public IUntypedSqlExpression SelectDistinct() + { + q.SelectDistinct(); + return this; + } + + public IUntypedSqlExpression From(string tables) + { + q.From(tables); + return this; + } + + public IUntypedSqlExpression UnsafeFrom(string rawFrom) + { + q.UnsafeFrom(rawFrom); + return this; + } + + public IUntypedSqlExpression Where() + { + q.Where(); + return this; + } + + public IUntypedSqlExpression UnsafeWhere(string rawSql, params object[] filterParams) + { + q.UnsafeWhere(rawSql, filterParams); + return this; + } + + public IUntypedSqlExpression Ensure(string sqlFilter, params object[] filterParams) + { + q.Ensure(sqlFilter, filterParams); + return this; + } + + public IUntypedSqlExpression Where(string sqlFilter, params object[] filterParams) + { + q.Where(sqlFilter, filterParams); + return this; + } + + public IUntypedSqlExpression UnsafeAnd(string rawSql, params object[] filterParams) + { + q.UnsafeAnd(rawSql, filterParams); + return this; + } + + public IUntypedSqlExpression And(string sqlFilter, params object[] filterParams) + { + q.And(sqlFilter, filterParams); + return this; + } + + public IUntypedSqlExpression UnsafeOr(string rawSql, params object[] filterParams) + { + q.UnsafeOr(rawSql, filterParams); + return this; + } + + public IUntypedSqlExpression Or(string sqlFilter, params object[] filterParams) + { + q.Or(sqlFilter, filterParams); + return this; + } + + public IUntypedSqlExpression AddCondition(string condition, string sqlFilter, params object[] filterParams) + { + q.AddCondition(condition, sqlFilter, filterParams); + return this; + } + + public IUntypedSqlExpression GroupBy() + { + q.GroupBy(); + return this; + } + + public IUntypedSqlExpression GroupBy(string groupBy) + { + q.GroupBy(groupBy); + return this; + } + + public IUntypedSqlExpression Having() + { + q.Having(); + return this; + } + + public IUntypedSqlExpression Having(string sqlFilter, params object[] filterParams) + { + q.Having(sqlFilter, filterParams); + return this; + } + + public IUntypedSqlExpression OrderBy() + { + q.OrderBy(); + return this; + } + + public IUntypedSqlExpression OrderBy(string orderBy) + { + q.OrderBy(orderBy); + return this; + } + + public ModelDefinition GetModelDefinition(FieldDefinition fieldDef) + { + return q.GetModelDefinition(fieldDef); + } + + public IUntypedSqlExpression OrderByFields(params FieldDefinition[] fields) + { + q.OrderByFields(fields); + return this; + } + + public IUntypedSqlExpression OrderByFieldsDescending(params FieldDefinition[] fields) + { + q.OrderByFieldsDescending(fields); + return this; + } + + public IUntypedSqlExpression OrderByFields(params string[] fieldNames) + { + q.OrderByFields(fieldNames); + return this; + } + + public IUntypedSqlExpression OrderByFieldsDescending(params string[] fieldNames) + { + q.OrderByFieldsDescending(fieldNames); + return this; + } + + public IUntypedSqlExpression OrderBy
(Expression> keySelector) + { + q.OrderBy(keySelector); + return this; + } + + public IUntypedSqlExpression ThenBy(string orderBy) + { + q.ThenBy(orderBy); + return this; + } + + public IUntypedSqlExpression ThenBy
(Expression> keySelector) + { + q.ThenBy(keySelector); + return this; + } + + public IUntypedSqlExpression OrderByDescending
(Expression> keySelector) + { + q.OrderByDescending(keySelector); + return this; + } + + public IUntypedSqlExpression OrderByDescending(string orderBy) + { + q.OrderByDescending(orderBy); + return this; + } + + public IUntypedSqlExpression ThenByDescending(string orderBy) + { + q.ThenByDescending(orderBy); + return this; + } + + public IUntypedSqlExpression ThenByDescending
(Expression> keySelector) + { + q.ThenByDescending(keySelector); + return this; + } + + public IUntypedSqlExpression Skip(int? skip = null) + { + q.Skip(skip); + return this; + } + + public IUntypedSqlExpression Take(int? take = null) + { + q.Take(take); + return this; + } + + public IUntypedSqlExpression Limit(int skip, int rows) + { + q.Limit(skip, rows); + return this; + } + + public IUntypedSqlExpression Limit(int? skip, int? rows) + { + q.Limit(skip, rows); + return this; + } + + public IUntypedSqlExpression Limit(int rows) + { + q.Limit(rows); + return this; + } + + public IUntypedSqlExpression Limit() + { + q.Limit(); + return this; + } + + public IUntypedSqlExpression ClearLimits() + { + q.ClearLimits(); + return this; + } + + public IUntypedSqlExpression Update(List updateFields) + { + q.Update(updateFields); + return this; + } + + public IUntypedSqlExpression Update() + { + q.Update(); + return this; + } + + public IUntypedSqlExpression Insert(List insertFields) + { + q.Insert(insertFields); + return this; + } + + public IUntypedSqlExpression Insert() + { + q.Insert(); + return this; + } + + public IDbDataParameter CreateParam(string name, object value = null, ParameterDirection direction = ParameterDirection.Input, DbType? dbType = null) + { + return q.CreateParam(name, value, direction, dbType); + } + + public IUntypedSqlExpression Join(Expression> joinExpr = null) + { + q.Join(joinExpr); + return this; + } + + public IUntypedSqlExpression Join(Type sourceType, Type targetType, Expression joinExpr = null) + { + q.Join(sourceType, targetType, joinExpr); + return this; + } + + public IUntypedSqlExpression LeftJoin(Expression> joinExpr = null) + { + q.LeftJoin(joinExpr); + return this; + } + + public IUntypedSqlExpression LeftJoin(Type sourceType, Type targetType, Expression joinExpr = null) + { + q.LeftJoin(sourceType, targetType, joinExpr); + return this; + } + + public IUntypedSqlExpression RightJoin(Expression> joinExpr = null) + { + q.RightJoin(joinExpr); + return this; + } + + public IUntypedSqlExpression FullJoin(Expression> joinExpr = null) + { + q.FullJoin(joinExpr); + return this; + } + + public IUntypedSqlExpression CrossJoin(Expression> joinExpr = null) + { + q.CrossJoin(joinExpr); + return this; + } + + public IUntypedSqlExpression CustomJoin(string joinString) + { + q.CustomJoin(joinString); + return this; + } + + public IUntypedSqlExpression Where(Expression> predicate) + { + q.Where(predicate); + return this; + } + + public IUntypedSqlExpression Ensure(Expression> predicate) + { + q.Ensure(predicate); + return this; + } + + public IUntypedSqlExpression Where(Expression> predicate) + { + q.Where(predicate); + return this; + } + + public IUntypedSqlExpression Ensure(Expression> predicate) + { + q.Ensure(predicate); + return this; + } + + public IUntypedSqlExpression And(Expression> predicate) + { + q.And(predicate); + return this; + } + + public IUntypedSqlExpression And(Expression> predicate) + { + q.And(predicate); + return this; + } + + public IUntypedSqlExpression Or(Expression> predicate) + { + q.Or(predicate); + return this; + } + + public IUntypedSqlExpression Or(Expression> predicate) + { + q.Or(predicate); + return this; + } + + public string SqlTable(ModelDefinition modelDef) + { + return q.SqlTable(modelDef); + } + + public string SqlColumn(string columnName) + { + return q.SqlColumn(columnName); + } + + public string ToDeleteRowStatement() + { + return q.ToDeleteRowStatement(); + } + + public string ToSelectStatement() => ToSelectStatement(QueryType.Select); + public string ToSelectStatement(QueryType forType) + { + return q.ToSelectStatement(forType); + } + + public string ToCountStatement() + { + return q.ToCountStatement(); + } + + public IList GetAllFields() + { + return q.GetAllFields(); + } + + public Tuple FirstMatchingField(string fieldName) + { + return q.FirstMatchingField(fieldName); + } + + public string SelectInto() => q.SelectInto(); + public string SelectInto(QueryType queryType) => q.SelectInto(queryType); + } + + public static class SqlExpressionExtensions + { + public static IUntypedSqlExpression GetUntypedSqlExpression(this ISqlExpression sqlExpression) + { + var hasUntyped = sqlExpression as IHasUntypedSqlExpression; + return hasUntyped?.GetUntyped(); + } + + public static IOrmLiteDialectProvider ToDialectProvider(this ISqlExpression sqlExpression) => + (sqlExpression as IHasDialectProvider)?.DialectProvider ?? OrmLiteConfig.DialectProvider; + + public static string Table(this ISqlExpression sqlExpression) => sqlExpression.ToDialectProvider().GetQuotedTableName(typeof(T).GetModelDefinition()); + + public static string Table(this IOrmLiteDialectProvider dialect) => dialect.GetQuotedTableName(typeof(T).GetModelDefinition()); + + public static string Column
(this ISqlExpression sqlExpression, Expression> propertyExpression, bool prefixTable = false) => + sqlExpression.ToDialectProvider().Column(propertyExpression, prefixTable); + + public static string Column
(this IOrmLiteDialectProvider dialect, Expression> propertyExpression, bool prefixTable = false) + { + string propertyName = null; + Expression expr = propertyExpression; + + if (expr is LambdaExpression lambda) + expr = lambda.Body; + + if (expr.NodeType == ExpressionType.Convert && expr is UnaryExpression unary) + expr = unary.Operand; + + if (expr is MemberExpression member) + propertyName = member.Member.Name; + + if (propertyName == null) + propertyName = expr.ToPropertyInfo()?.Name; + + if (propertyName != null) + return dialect.Column
(propertyName, prefixTable); + + throw new ArgumentException("Expected Lambda MemberExpression but received: " + propertyExpression.Name); + } + + public static string Column
(this ISqlExpression sqlExpression, string propertyName, bool prefixTable = false) => + sqlExpression.ToDialectProvider().Column
(propertyName, prefixTable); + + public static string Column
(this IOrmLiteDialectProvider dialect, string propertyName, bool prefixTable = false) + { + var tableDef = typeof(Table).GetModelDefinition(); + + var fieldDef = tableDef.FieldDefinitions.FirstOrDefault(x => x.Name == propertyName); + var fieldName = fieldDef != null + ? fieldDef.FieldName + : propertyName; + + return prefixTable + ? dialect.GetQuotedColumnName(tableDef, fieldName) + : dialect.GetQuotedColumnName(fieldName); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Expressions/ReadExpressionCommandExtensions.cs b/src/ServiceStack.OrmLite/Expressions/ReadExpressionCommandExtensions.cs index 4c9fe3659..898f8e5c3 100644 --- a/src/ServiceStack.OrmLite/Expressions/ReadExpressionCommandExtensions.cs +++ b/src/ServiceStack.OrmLite/Expressions/ReadExpressionCommandExtensions.cs @@ -4,111 +4,197 @@ using System.Data; using System.Linq.Expressions; using System.Text; +using ServiceStack.Text; namespace ServiceStack.OrmLite { internal static class ReadExpressionCommandExtensions { - internal static List Select(this IDbCommand dbCmd, Func, SqlExpression> expression) + internal static List Select(this IDbCommand dbCmd, SqlExpression q) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - string sql = expression(expr).SelectInto(); + string sql = q.SelectInto(QueryType.Select); + return dbCmd.ExprConvertToList(sql, q.Params, onlyFields: q.OnlyFields); + } + + internal static List Select(this IDbCommand dbCmd, Expression> predicate) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + string sql = q.Where(predicate).SelectInto(QueryType.Select); - return dbCmd.ExprConvertToList(sql); + return dbCmd.ExprConvertToList(sql, q.Params); } - internal static List Select(this IDbCommand dbCmd, Func, SqlExpression> expression) + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - string sql = expression(expr).SelectInto(); + q.SelectIfDistinct(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToList>(q.ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } - return dbCmd.ExprConvertToList(sql); + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q) + { + q.SelectIfDistinct(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToList>(q.ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); } - internal static List Select(this IDbCommand dbCmd, SqlExpression expression) + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q) { - string sql = expression.SelectInto(); - return dbCmd.ExprConvertToList(sql); + q.SelectIfDistinct(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToList>(q.ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); } - internal static List Select(this IDbCommand dbCmd, SqlExpression expression) + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q) { - string sql = expression.SelectInto(); + q.SelectIfDistinct(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToList>(q.ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } - return dbCmd.ExprConvertToList(sql); + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q) + { + q.SelectIfDistinct(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToList>(q.ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); } - internal static List Select(this IDbCommand dbCmd, Expression> predicate) + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q) + { + q.SelectIfDistinct(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToList>(q.ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q) + { + q.SelectIfDistinct(q.CreateMultiSelect(dbCmd.GetDialectProvider())); + return dbCmd.ExprConvertToList>(q.ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static string CreateMultiSelect(this SqlExpression q, IOrmLiteDialectProvider dialectProvider) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - string sql = expr.Where(predicate).SelectInto(); + var sb = StringBuilderCache.Allocate() + .Append($"{dialectProvider.GetQuotedTableName(typeof(T).GetModelDefinition())}.*, {Sql.EOT}"); - return dbCmd.ExprConvertToList(sql); + if (typeof(T2) != typeof(EOT)) + sb.Append($", {dialectProvider.GetQuotedTableName(typeof(T2).GetModelDefinition())}.*, {Sql.EOT}"); + if (typeof(T3) != typeof(EOT)) + sb.Append($", {dialectProvider.GetQuotedTableName(typeof(T3).GetModelDefinition())}.*, {Sql.EOT}"); + if (typeof(T4) != typeof(EOT)) + sb.Append($", {dialectProvider.GetQuotedTableName(typeof(T4).GetModelDefinition())}.*, {Sql.EOT}"); + if (typeof(T5) != typeof(EOT)) + sb.Append($", {dialectProvider.GetQuotedTableName(typeof(T5).GetModelDefinition())}.*, {Sql.EOT}"); + if (typeof(T6) != typeof(EOT)) + sb.Append($", {dialectProvider.GetQuotedTableName(typeof(T6).GetModelDefinition())}.*, {Sql.EOT}"); + if (typeof(T7) != typeof(EOT)) + sb.Append($", {dialectProvider.GetQuotedTableName(typeof(T7).GetModelDefinition())}.*, {Sql.EOT}"); + if (typeof(T8) != typeof(EOT)) + sb.Append($", {dialectProvider.GetQuotedTableName(typeof(T8).GetModelDefinition())}.*, {Sql.EOT}"); + + return StringBuilderCache.ReturnAndFree(sb); + } + + internal static string CreateMultiSelect(this ISqlExpression q, string[] tableSelects) + { + var sb = StringBuilderCache.Allocate(); + + foreach (var tableSelect in tableSelects) + { + if (sb.Length > 0) + sb.Append(", "); + + sb.Append($"{tableSelect}, {Sql.EOT}"); + } + + return StringBuilderCache.ReturnAndFree(sb); } - internal static T Single(this IDbCommand dbCmd, Func, SqlExpression> expression) + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - return dbCmd.Single(expression(expr)); + return dbCmd.ExprConvertToList>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects) + { + return dbCmd.ExprConvertToList>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects) + { + return dbCmd.ExprConvertToList>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects) + { + return dbCmd.ExprConvertToList>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects) + { + return dbCmd.ExprConvertToList>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects) + { + return dbCmd.ExprConvertToList>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); + } + + internal static List> SelectMulti(this IDbCommand dbCmd, SqlExpression q, string[] tableSelects) + { + return dbCmd.ExprConvertToList>(q.Select(q.CreateMultiSelect(tableSelects)).ToSelectStatement(QueryType.Select), q.Params, onlyFields: q.OnlyFields); } internal static T Single(this IDbCommand dbCmd, Expression> predicate) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); + var q = dbCmd.GetDialectProvider().SqlExpression(); - return Single(dbCmd, ev.Where(predicate)); + return Single(dbCmd, q.Where(predicate)); } - internal static T Single(this IDbCommand dbCmd, SqlExpression expression) + internal static T Single(this IDbCommand dbCmd, SqlExpression q) { - string sql = expression.Limit(1).SelectInto(); + string sql = q.Limit(1).SelectInto(QueryType.Single); - return dbCmd.ExprConvertTo(sql); + return dbCmd.ExprConvertTo(sql, q.Params, onlyFields:q.OnlyFields); } - public static TKey Scalar(this IDbCommand dbCmd, Expression> field) + public static TKey Scalar(this IDbCommand dbCmd, SqlExpression expression) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Select(field); - var sql = ev.SelectInto(); - return dbCmd.Scalar(sql); + var sql = expression.SelectInto(QueryType.Scalar); + return dbCmd.Scalar(sql, expression.Params); } - internal static TKey Scalar(this IDbCommand dbCmd, - Expression> field, Expression> predicate) + public static TKey Scalar(this IDbCommand dbCmd, Expression> field) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Select(field).Where(predicate); - string sql = ev.SelectInto(); - return dbCmd.Scalar(sql); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Select(field); + var sql = q.SelectInto(QueryType.Scalar); + return dbCmd.Scalar(sql, q.Params); } - internal static long Count(this IDbCommand dbCmd) + internal static TKey Scalar(this IDbCommand dbCmd, + Expression> field, Expression> predicate) { - var expression = dbCmd.GetDialectProvider().SqlExpression(); - var sql = expression.ToCountStatement(); - return GetCount(dbCmd, sql); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Select(field).Where(predicate); + string sql = q.SelectInto(QueryType.Scalar); + return dbCmd.Scalar(sql, q.Params); } - internal static long Count(this IDbCommand dbCmd, Func, SqlExpression> expression) + internal static long Count(this IDbCommand dbCmd) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - var sql = expression(expr).ToCountStatement(); - return GetCount(dbCmd, sql); + var q = dbCmd.GetDialectProvider().SqlExpression(); + var sql = q.ToCountStatement(); + return GetCount(dbCmd, sql, q.Params); } internal static long Count(this IDbCommand dbCmd, SqlExpression expression) { var sql = expression.ToCountStatement(); - return GetCount(dbCmd, sql); + return GetCount(dbCmd, sql, expression.Params); } internal static long Count(this IDbCommand dbCmd, Expression> predicate) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Where(predicate); - var sql = ev.ToCountStatement(); - return GetCount(dbCmd, sql); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(predicate); + var sql = q.ToCountStatement(); + return GetCount(dbCmd, sql, q.Params); } internal static long GetCount(this IDbCommand dbCmd, string sql) @@ -116,37 +202,83 @@ internal static long GetCount(this IDbCommand dbCmd, string sql) return dbCmd.Column(sql).Sum(); } + internal static long GetCount(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + return dbCmd.Column(sql, sqlParams).Sum(); + } + internal static long RowCount(this IDbCommand dbCmd, SqlExpression expression) { - return dbCmd.Scalar(dbCmd.GetDialectProvider().ToRowCountStatement(expression.ToSelectStatement())); + //ORDER BY throws when used in sub selects in SQL Server. Removing OrderBy() clause since it doesn't impact results + var countExpr = expression.Clone().OrderBy(); + return dbCmd.Scalar(dbCmd.GetDialectProvider().ToRowCountStatement(countExpr.ToSelectStatement(QueryType.Scalar)), countExpr.Params); } - internal static long RowCount(this IDbCommand dbCmd, string sql) + internal static long RowCount(this IDbCommand dbCmd, string sql, object anonType) { + if (anonType != null) + dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); + return dbCmd.Scalar(dbCmd.GetDialectProvider().ToRowCountStatement(sql)); } - internal static List LoadSelect(this IDbCommand dbCmd, Func, SqlExpression> expression) + internal static long RowCount(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) { - var expr = dbCmd.GetDialectProvider().SqlExpression(); - expr = expression(expr); - return dbCmd.LoadListWithReferences(expr); + return dbCmd.SetParameters(sqlParams).Scalar(dbCmd.GetDialectProvider().ToRowCountStatement(sql)); } - internal static List LoadSelect(this IDbCommand dbCmd, SqlExpression expression = null) + internal static List LoadSelect(this IDbCommand dbCmd, SqlExpression expression = null, IEnumerable include = null) { - return dbCmd.LoadListWithReferences(expression); + return dbCmd.LoadListWithReferences(expression, include); } - internal static List LoadSelect(this IDbCommand dbCmd, SqlExpression expression) + internal static List LoadSelect(this IDbCommand dbCmd, SqlExpression expression, IEnumerable include = null) { - return dbCmd.LoadListWithReferences(expression); + return dbCmd.LoadListWithReferences(expression, include); } - internal static List LoadSelect(this IDbCommand dbCmd, Expression> predicate) + internal static List LoadSelect(this IDbCommand dbCmd, Expression> predicate, IEnumerable include = null) { var expr = dbCmd.GetDialectProvider().SqlExpression().Where(predicate); - return dbCmd.LoadListWithReferences(expr); + return dbCmd.LoadListWithReferences(expr, include); + } + + internal static DataTable GetSchemaTable(this IDbCommand dbCmd, string sql) + { + using (var reader = dbCmd.ExecReader(sql, CommandBehavior.KeyInfo)) //KeyInfo required for npgsql + { + return reader.GetSchemaTable(); + } + } + + public static ColumnSchema[] GetTableColumns(this IDbCommand dbCmd, Type table) => + dbCmd.GetTableColumns($"SELECT * FROM {dbCmd.GetDialectProvider().GetQuotedTableName(table.GetModelDefinition())}"); + + public static ColumnSchema[] GetTableColumns(this IDbCommand dbCmd, string sql) => + dbCmd.GetSchemaTable(sql).ToColumnSchemas(dbCmd); + + internal static ColumnSchema[] ToColumnSchemas(this DataTable dt, IDbCommand dbCmd) + { + var ret = new List(); + foreach (DataRow row in dt.Rows) + { + var obj = new Dictionary(); + foreach (DataColumn column in dt.Columns) + { + obj[column.ColumnName] = row[column.Ordinal]; + } + + var to = obj.FromObjectDictionary(); + //MySQL doesn't populate DataTypeName, so reverse populate it from Type Converter ColumnDefinition + if (to.DataTypeName == null && to.DataType != null) + to.DataTypeName = dbCmd.GetDialectProvider().GetConverter(to.DataType)?.ColumnDefinition.LeftPart('('); + if (to.DataTypeName == null) + continue; + + ret.Add(to); + } + + return ret.ToArray(); } } } diff --git a/src/ServiceStack.OrmLite/Expressions/Sql.cs b/src/ServiceStack.OrmLite/Expressions/Sql.cs index 97047b700..3138700c6 100644 --- a/src/ServiceStack.OrmLite/Expressions/Sql.cs +++ b/src/ServiceStack.OrmLite/Expressions/Sql.cs @@ -1,16 +1,14 @@ +using System; using System.Collections; using System.Linq; using System.Collections.Generic; namespace ServiceStack.OrmLite { - public static class Sql + public static partial class Sql { - public static bool In(T value, params TItem[] list) - { - return value != null && Flatten(list).Any(obj => obj.ToString() == value.ToString()); - } - + public static string VARCHAR = nameof(VARCHAR); + public static List Flatten(IEnumerable list) { var ret = new List(); @@ -20,8 +18,7 @@ public static List Flatten(IEnumerable list) { if (item == null) continue; - var arr = item as IEnumerable; - if (arr != null && !(item is string)) + if (item is IEnumerable arr && !(item is string)) { ret.AddRange(arr.Cast()); } @@ -33,66 +30,151 @@ public static List Flatten(IEnumerable list) return ret; } - public static string Desc(T value) - { - return value == null ? "" : value.ToString() + " DESC"; - } + public static bool In(T value, params TItem[] list) => value != null && Flatten(list).Any(obj => obj.ToString() == value.ToString()); - public static string As(T value, object asValue) - { - return value == null ? "" : string.Format("{0} AS {1}", value.ToString(), asValue); - } + public static bool In(T value, SqlExpression query) => value != null && query != null; - public static T Sum(T value) - { - return value; - } + public static string Asc(T value) => value == null ? "" : value + " ASC"; + public static string Desc(T value) => value == null ? "" : value + " DESC"; - public static string Sum(string value) - { - return "SUM({0})".Fmt(value); - } + public static string As(T value, object asValue) => value == null ? "" : $"{value} AS {asValue}"; - public static T Count(T value) - { - return value; - } + public static T Sum(T value) => value; - public static string Count(string value) - { - return "COUNT({0})".Fmt(value); - } + public static string Sum(string value) => $"SUM({value})"; - public static T Min(T value) - { - return value; - } + public static T Count(T value) => value; - public static string Min(string value) - { - return "MIN({0})".Fmt(value); - } + public static T CountDistinct(T value) => value; - public static T Max(T value) - { - return value; - } + public static string Count(string value) => $"COUNT({value})"; - public static string Max(string value) - { - return "MAX({0})".Fmt(value); - } + public static T Min(T value) => value; - public static T Avg(T value) - { - return value; - } + public static string Min(string value) => $"MIN({value})"; - public static string Avg(string value) - { - return "AVG({0})".Fmt(value); - } + public static T Max(T value) => value; + + public static string Max(string value) => $"MAX({value})"; + + public static T Avg(T value) => value; + + public static string Avg(string value) => $"AVG({value})"; + + public static T AllFields(T item) => item; + + [Obsolete("Use TableAlias")] + public static string JoinAlias(string property, string tableAlias) => tableAlias; + + public static string TableAlias(string property, string tableAlias) => tableAlias; + + [Obsolete("Use TableAlias")] + public static T JoinAlias(T property, string tableAlias) => default(T); + + public static T TableAlias(T property, string tableAlias) => default(T); + + public static string Custom(string customSql) => customSql; + + public static T Custom(string customSql) => default(T); + + public static string Cast(object value, string castAs) => $"CAST({value} AS {castAs})"; + + public const string EOT= "0 EOT"; } + /// + /// SQL Server 2016 specific features + /// + public static partial class Sql + { + /// Tests whether a string contains valid JSON. + /// The string to test. + /// Returns True if the string contains valid JSON; otherwise, returns False. Returns null if expression is null. + /// ISJSON does not check the uniqueness of keys at the same level. + /// + public static bool? IsJson(string expression) => null; + + /// Extracts a scalar value from a JSON string. + /// + /// An expression. Typically the name of a variable or a column that contains JSON text.

+ /// If JSON_VALUE finds JSON that is not valid in expression before it finds the value identified by path, the function returns an error. If JSON_VALUE doesn't find the value identified by path, it scans the entire text and returns an error if it finds JSON that is not valid anywhere in expression. + /// + /// + /// A JSON path that specifies the property to extract. For more info, see JSON Path Expressions (SQL Server).

+ /// In SQL Server 2017 and in Azure SQL Database, you can provide a variable as the value of path.

+ /// If the format of path isn't valid, JSON_VALUE returns an error.

+ /// + /// + /// Returns a single text value of type nvarchar(4000). The collation of the returned value is the same as the collation of the input expression. + /// If the value is greater than 4000 characters:

+ ///
    + ///
  • In lax mode, JSON_VALUE returns null.
  • + ///
  • In strict mode, JSON_VALUE returns an error.
  • + ///
+ ///
+ /// If you have to return scalar values greater than 4000 characters, use OPENJSON instead of JSON_VALUE. For more info, see OPENJSON (Transact-SQL). + ///
+ /// + public static T JsonValue(string expression, string path) => default(T); + + /// Extracts a scalar value from a JSON string. + /// + /// An expression. Typically the name of a variable or a column that contains JSON text.

+ /// If JSON_VALUE finds JSON that is not valid in expression before it finds the value identified by path, the function returns an error. If JSON_VALUE doesn't find the value identified by path, it scans the entire text and returns an error if it finds JSON that is not valid anywhere in expression. + /// + /// + /// A JSON path that specifies the property to extract. For more info, see JSON Path Expressions (SQL Server).

+ /// In SQL Server 2017 and in Azure SQL Database, you can provide a variable as the value of path.

+ /// If the format of path isn't valid, JSON_VALUE returns an error.

+ /// + /// + /// Returns a single text value of type nvarchar(4000). The collation of the returned value is the same as the collation of the input expression. + /// If the value is greater than 4000 characters:

+ ///
    + ///
  • In lax mode, JSON_VALUE returns null.
  • + ///
  • In strict mode, JSON_VALUE returns an error.
  • + ///
+ ///
+ /// If you have to return scalar values greater than 4000 characters, use OPENJSON instead of JSON_VALUE. For more info, see OPENJSON (Transact-SQL). + ///
+ /// + public static string JsonValue(string expression, string path) => string.Empty; + + + /// + /// Extracts an object or an array from a JSON string.

+ /// To extract a scalar value from a JSON string instead of an object or an array, see JSON_VALUE(Transact-SQL). + /// For info about the differences between JSON_VALUE and JSON_QUERY, see Compare JSON_VALUE and JSON_QUERY. + ///
+ /// Type of objects returned + /// + /// An expression. Typically the name of a variable or a column that contains JSON text.

+ /// If JSON_QUERY finds JSON that is not valid in expression before it finds the value identified by path, the function returns an error. If JSON_QUERY doesn't find the value identified by path, it scans the entire text and returns an error if it finds JSON that is not valid anywhere in expression. + /// + /// + /// A JSON path that specifies the object or the array to extract.

+ /// In SQL Server 2017 and in Azure SQL Database, you can provide a variable as the value of path.

+ /// The JSON path can specify lax or strict mode for parsing.If you don't specify the parsing mode, lax mode is the default. For more info, see JSON Path Expressions (SQL Server).

+ /// The default value for path is '$'. As a result, if you don't provide a value for path, JSON_QUERY returns the input expression.

+ /// If the format of path isn't valid, JSON_QUERY returns an error. + /// + /// + /// Returns a JSON fragment of type T. The collation of the returned value is the same as the collation of the input expression.

+ /// If the value is not an object or an array: + ///
    + ///
  • In lax mode, JSON_QUERY returns null.
  • + ///
  • In strict mode, JSON_QUERY returns an error.
  • + ///
+ ///
+ public static string JsonQuery(string expression) => string.Empty; + + public static T JsonQuery(string expression) => default(T); + + // SQL Server 2017+ + public static string JsonQuery(string expression, string path) => string.Empty; + + // SQL Server 2017+ + public static T JsonQuery(string expression, string path) => default(T); + } } diff --git a/src/ServiceStack.OrmLite/Expressions/SqlExpression.Join.cs b/src/ServiceStack.OrmLite/Expressions/SqlExpression.Join.cs index 327c8d317..1ebb0e331 100644 --- a/src/ServiceStack.OrmLite/Expressions/SqlExpression.Join.cs +++ b/src/ServiceStack.OrmLite/Expressions/SqlExpression.Join.cs @@ -1,16 +1,51 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Linq.Expressions; using System.Text; +using ServiceStack.Text; namespace ServiceStack.OrmLite { + public delegate string JoinFormatDelegate(IOrmLiteDialectProvider dialect, ModelDefinition tableDef, string joinExpr); + + public class TableOptions + { + public string Expression { get; set; } + public string Alias { get; set; } + + internal JoinFormatDelegate JoinFormat; + internal ModelDefinition ModelDef; + internal string ParamName; + } + public abstract partial class SqlExpression : ISqlExpression { - List tableDefs = new List(); + protected List tableDefs = new(); - bool IsJoinedTable(Type type) + public List GetAllTables() + { + var allTableDefs = new List { modelDef }; + allTableDefs.AddRange(tableDefs); + return allTableDefs; + } + + public SqlExpression AddReferenceTableIfNotExists() + { + var tableDef = typeof(Target).GetModelDefinition(); + if (!tableDefs.Contains(tableDef)) + tableDefs.Add(tableDef); + return this; + } + + public SqlExpression CustomJoin(string joinString) + { + AddReferenceTableIfNotExists(); + return CustomJoin(joinString); + } + + public bool IsJoinedTable(Type type) { return tableDefs.FirstOrDefault(x => x.ModelType == type) != null; } @@ -20,11 +55,31 @@ public SqlExpression Join(Expression> joinExpr return InternalJoin("INNER JOIN", joinExpr); } + public SqlExpression Join(Expression> joinExpr, TableOptions options) + { + if (options == null) + throw new ArgumentNullException(nameof(options)); + + if (options.Expression != null) + throw new ArgumentException("Can't set both Join Expression and TableOptions Expression"); + + return InternalJoin("INNER JOIN", joinExpr, options); + } + + public SqlExpression Join(Expression> joinExpr, JoinFormatDelegate joinFormat) => + InternalJoin("INNER JOIN", joinExpr, joinFormat ?? throw new ArgumentNullException(nameof(joinFormat))); + public SqlExpression Join(Expression> joinExpr = null) { return InternalJoin("INNER JOIN", joinExpr); } + public SqlExpression Join(Expression> joinExpr, JoinFormatDelegate joinFormat) => + InternalJoin("INNER JOIN", joinExpr, joinFormat); + + public SqlExpression Join(Expression> joinExpr, TableOptions options) => + InternalJoin("INNER JOIN", joinExpr, options); + public SqlExpression Join(Type sourceType, Type targetType, Expression joinExpr = null) { return InternalJoin("INNER JOIN", joinExpr, sourceType.GetModelDefinition(), targetType.GetModelDefinition()); @@ -35,11 +90,23 @@ public SqlExpression LeftJoin(Expression> joinE return InternalJoin("LEFT JOIN", joinExpr); } + public SqlExpression LeftJoin(Expression> joinExpr, JoinFormatDelegate joinFormat) => + InternalJoin("LEFT JOIN", joinExpr, joinFormat ?? throw new ArgumentNullException(nameof(joinFormat))); + + public SqlExpression LeftJoin(Expression> joinExpr, TableOptions options) => + InternalJoin("LEFT JOIN", joinExpr, options ?? throw new ArgumentNullException(nameof(options))); + public SqlExpression LeftJoin(Expression> joinExpr = null) { return InternalJoin("LEFT JOIN", joinExpr); } + public SqlExpression LeftJoin(Expression> joinExpr, JoinFormatDelegate joinFormat) => + InternalJoin("LEFT JOIN", joinExpr, joinFormat); + + public SqlExpression LeftJoin(Expression> joinExpr, TableOptions options) => + InternalJoin("LEFT JOIN", joinExpr, options); + public SqlExpression LeftJoin(Type sourceType, Type targetType, Expression joinExpr = null) { return InternalJoin("LEFT JOIN", joinExpr, sourceType.GetModelDefinition(), targetType.GetModelDefinition()); @@ -50,11 +117,23 @@ public SqlExpression RightJoin(Expression> join return InternalJoin("RIGHT JOIN", joinExpr); } + public SqlExpression RightJoin(Expression> joinExpr, JoinFormatDelegate joinFormat) => + InternalJoin("RIGHT JOIN", joinExpr, joinFormat ?? throw new ArgumentNullException(nameof(joinFormat))); + + public SqlExpression RightJoin(Expression> joinExpr, TableOptions options) => + InternalJoin("RIGHT JOIN", joinExpr, options ?? throw new ArgumentNullException(nameof(options))); + public SqlExpression RightJoin(Expression> joinExpr = null) { return InternalJoin("RIGHT JOIN", joinExpr); } + public SqlExpression RightJoin(Expression> joinExpr, JoinFormatDelegate joinFormat) => + InternalJoin("RIGHT JOIN", joinExpr, joinFormat); + + public SqlExpression RightJoin(Expression> joinExpr, TableOptions options) => + InternalJoin("RIGHT JOIN", joinExpr, options); + public SqlExpression FullJoin(Expression> joinExpr = null) { return InternalJoin("FULL JOIN", joinExpr); @@ -75,8 +154,18 @@ public SqlExpression CrossJoin(Expression InternalJoin(string joinType, - Expression> joinExpr) + protected SqlExpression InternalJoin(string joinType, Expression> joinExpr, JoinFormatDelegate joinFormat) => + InternalJoin(joinType, joinExpr, joinFormat != null ? new TableOptions { JoinFormat = joinFormat } : null); + + protected SqlExpression InternalJoin(string joinType, Expression> joinExpr, TableOptions options = null) + { + var sourceDef = typeof(Source).GetModelDefinition(); + var targetDef = typeof(Target).GetModelDefinition(); + + return InternalJoin(joinType, joinExpr, sourceDef, targetDef, options); + } + + protected SqlExpression InternalJoin(string joinType, Expression joinExpr) { var sourceDef = typeof(Source).GetModelDefinition(); var targetDef = typeof(Target).GetModelDefinition(); @@ -84,9 +173,19 @@ private SqlExpression InternalJoin(string joinType, return InternalJoin(joinType, joinExpr, sourceDef, targetDef); } + public SqlExpression Join(Expression> joinExpr) => InternalJoin("INNER JOIN", joinExpr); + public SqlExpression LeftJoin(Expression> joinExpr) => InternalJoin("LEFT JOIN", joinExpr); + public SqlExpression RightJoin(Expression> joinExpr) => InternalJoin("RIGHT JOIN", joinExpr); + public SqlExpression FullJoin(Expression> joinExpr) => InternalJoin("FULL JOIN", joinExpr); + + public SqlExpression Join(Expression> joinExpr) => InternalJoin("INNER JOIN", joinExpr); + public SqlExpression LeftJoin(Expression> joinExpr) => InternalJoin("LEFT JOIN", joinExpr); + public SqlExpression RightJoin(Expression> joinExpr) => InternalJoin("RIGHT JOIN", joinExpr); + public SqlExpression FullJoin(Expression> joinExpr) => InternalJoin("FULL JOIN", joinExpr); + private string InternalCreateSqlFromExpression(Expression joinExpr, bool isCrossJoin) { - return "{0} {1}".Fmt((isCrossJoin ? "WHERE" : "ON"), Visit(joinExpr).ToString()); + return $"{(isCrossJoin ? "WHERE" : "ON")} {VisitJoin(joinExpr)}"; } private string InternalCreateSqlFromDefinitions(ModelDefinition sourceDef, ModelDefinition targetDef, bool isCrossJoin) @@ -105,12 +204,12 @@ private string InternalCreateSqlFromDefinitions(ModelDefinition sourceDef, Model if (refField == null) { if(!isCrossJoin) - throw new ArgumentException("Could not infer relationship between {0} and {1}".Fmt(sourceDef.ModelName, targetDef.ModelName)); + throw new ArgumentException($"Could not infer relationship between {sourceDef.ModelName} and {targetDef.ModelName}"); return string.Empty; } - return "{0}\n({1}.{2} = {3}.{4})".Fmt( + return string.Format("{0}\n({1}.{2} = {3}.{4})", isCrossJoin ? "WHERE" : "ON", DialectProvider.GetQuotedTableName(parentDef), SqlColumn(parentDef.PrimaryKey.FieldName), @@ -125,73 +224,170 @@ public SqlExpression CustomJoin(string joinString) return this; } - private SqlExpression InternalJoin(string joinType, - Expression joinExpr, ModelDefinition sourceDef, ModelDefinition targetDef) + private TableOptions joinAlias; + + protected virtual SqlExpression InternalJoin(string joinType, Expression joinExpr, ModelDefinition sourceDef, ModelDefinition targetDef, TableOptions options = null) { PrefixFieldWithTableName = true; - //Changes how Sql Expressions are generated. - useFieldName = true; - sep = " "; + Reset(); + + var joinFormat = options?.JoinFormat; + if (options?.Alias != null) //Set joinAlias + { + options.ParamName = joinExpr is LambdaExpression l && l.Parameters.Count == 2 + ? l.Parameters[1].Name + : null; + if (options.ParamName != null) + { + joinFormat = null; + options.ModelDef = targetDef; + joinAlias = options; + } + } + + + if (!tableDefs.Contains(sourceDef)) + tableDefs.Add(sourceDef); + if (!tableDefs.Contains(targetDef)) + tableDefs.Add(targetDef); + + var isCrossJoin = "CROSS JOIN" == joinType; - var isCrossJoin = "CROSS JOIN".Equals(joinType); var sqlExpr = joinExpr != null ? InternalCreateSqlFromExpression(joinExpr, isCrossJoin) : InternalCreateSqlFromDefinitions(sourceDef, targetDef, isCrossJoin); var joinDef = tableDefs.Contains(targetDef) && !tableDefs.Contains(sourceDef) - ? sourceDef - : targetDef; + ? sourceDef + : targetDef; - FromExpression += " {0} {1} {2}".Fmt(joinType, SqlTable(joinDef), sqlExpr); + FromExpression += joinFormat != null + ? $" {joinType} {joinFormat(DialectProvider, joinDef, sqlExpr)}" + : joinAlias != null + ? $" {joinType} {SqlTable(joinDef)} {DialectProvider.GetQuotedName(joinAlias.Alias)} {sqlExpr}" + : $" {joinType} {SqlTable(joinDef)} {sqlExpr}"; - if (!tableDefs.Contains(sourceDef)) - tableDefs.Add(sourceDef); - if (!tableDefs.Contains(targetDef)) - tableDefs.Add(targetDef); + + if (joinAlias != null) //Unset joinAlias + { + joinAlias = null; + if (options != null) + { + options.ParamName = null; + options.ModelDef = null; + } + } return this; } - public string SelectInto() + public string SelectInto() => SelectInto(QueryType.Select); + public string SelectInto(QueryType queryType) { - if (CustomSelect || (typeof(TModel) == typeof(T) && !PrefixFieldWithTableName)) + if ((CustomSelect && OnlyFields == null) || (typeof(TModel) == typeof(T) && !PrefixFieldWithTableName)) { - return ToSelectStatement(); + return ToSelectStatement(queryType); } - var sbSelect = new StringBuilder(); - var selectDef = typeof(TModel).GetModelDefinition(); + useFieldName = true; + var sbSelect = StringBuilderCache.Allocate(); + var selectDef = modelDef; var orderedDefs = tableDefs; - if (selectDef != modelDef && tableDefs.Contains(selectDef)) + + if (typeof(TModel) != typeof(List) && + typeof(TModel) != typeof(Dictionary) && + typeof(TModel) != typeof(object) && //dynamic + !typeof(TModel).IsValueTuple()) { - orderedDefs = tableDefs.ToList(); //clone - orderedDefs.Remove(selectDef); - orderedDefs.Insert(0, selectDef); + selectDef = typeof(TModel).GetModelDefinition(); + if (selectDef != modelDef && tableDefs.Contains(selectDef)) + { + orderedDefs = tableDefs.ToList(); //clone + orderedDefs.Remove(selectDef); + orderedDefs.Insert(0, selectDef); + } } foreach (var fieldDef in selectDef.FieldDefinitions) { var found = false; + if (fieldDef.BelongToModelName != null) + { + var tableDef = orderedDefs.FirstOrDefault(x => x.Name == fieldDef.BelongToModelName); + if (tableDef != null) + { + var matchingField = FindWeakMatch(tableDef, fieldDef); + if (matchingField != null) + { + if (OnlyFields == null || OnlyFields.Contains(fieldDef.Name)) + { + if (sbSelect.Length > 0) + sbSelect.Append(", "); + + if (fieldDef.CustomSelect == null) + { + if (fieldDef.IsRowVersion) + { + sbSelect.Append(DialectProvider.GetRowVersionSelectColumn(fieldDef, DialectProvider.GetTableName(tableDef.ModelName))); + } + else + { + sbSelect.Append($"{GetQuotedColumnName(tableDef, matchingField.Name)} AS {SqlColumn(fieldDef.Name)}"); + } + } + else + { + sbSelect.Append(fieldDef.CustomSelect + " AS " + fieldDef.FieldName); + } + + continue; + } + } + } + } + foreach (var tableDef in orderedDefs) { foreach (var tableFieldDef in tableDef.FieldDefinitions) { if (tableFieldDef.Name == fieldDef.Name) { - found = true; + if (OnlyFields != null && !OnlyFields.Contains(fieldDef.Name)) + continue; + if (sbSelect.Length > 0) sbSelect.Append(", "); - sbSelect.AppendFormat("{0}.{1}", - SqlTable(tableDef), - tableFieldDef.GetQuotedName(DialectProvider)); - - if (tableFieldDef.Alias != null) - sbSelect.Append(" AS ").Append(SqlColumn(fieldDef.Name)); + var tableAlias = tableDef == modelDef // Use TableAlias if source modelDef + ? TableAlias + : null; + + if (fieldDef.CustomSelect == null) + { + if (fieldDef.IsRowVersion) + { + sbSelect.Append(DialectProvider.GetRowVersionSelectColumn(fieldDef, + DialectProvider.GetTableName(tableAlias ?? tableDef.ModelName, tableDef.Schema))); + } + else + { + sbSelect.Append(tableAlias == null + ? GetQuotedColumnName(tableDef, tableFieldDef.Name) + : GetQuotedColumnName(tableDef, tableAlias, tableFieldDef.Name)); + + if (tableFieldDef.RequiresAlias) + sbSelect.Append(" AS ").Append(SqlColumn(fieldDef.Name)); + } + } + else + { + sbSelect.Append(tableFieldDef.CustomSelect).Append(" AS ").Append(tableFieldDef.FieldName); + } + found = true; break; } } @@ -205,19 +401,20 @@ public string SelectInto() // Add support for auto mapping `{Table}{Field}` convention foreach (var tableDef in orderedDefs) { - var matchingField = tableDef.FieldDefinitions - .FirstOrDefault(x => - string.Compare(tableDef.Name + x.Name, fieldDef.Name, StringComparison.OrdinalIgnoreCase) == 0 - || string.Compare(tableDef.ModelName + x.FieldName, fieldDef.Name, StringComparison.OrdinalIgnoreCase) == 0); - + var matchingField = FindWeakMatch(tableDef, fieldDef); if (matchingField != null) { + if (OnlyFields != null && !OnlyFields.Contains(fieldDef.Name)) + continue; + if (sbSelect.Length > 0) sbSelect.Append(", "); - sbSelect.AppendFormat("{0} as {1}", - DialectProvider.GetQuotedColumnName(tableDef, matchingField), - SqlColumn(fieldDef.Name)); + var tableAlias = tableDef == modelDef // Use TableAlias if source modelDef + ? TableAlias + : null; + + sbSelect.Append($"{DialectProvider.GetQuotedColumnName(tableDef, tableAlias, matchingField)} as {SqlColumn(fieldDef.Name)}"); break; } @@ -225,47 +422,111 @@ public string SelectInto() } } - var columns = sbSelect.Length > 0 ? sbSelect.ToString() : "*"; + var select = StringBuilderCache.ReturnAndFree(sbSelect); + + var columns = select.Length > 0 ? select : "*"; SelectExpression = "SELECT " + (selectDistinct ? "DISTINCT " : "") + columns; - return ToSelectStatement(); + return ToSelectStatement(queryType); } - public virtual SqlExpression Where(Expression> predicate) + private static FieldDefinition FindWeakMatch(ModelDefinition tableDef, FieldDefinition fieldDef) { - AppendToWhere("AND", predicate); - return this; + return tableDef.FieldDefinitions + .FirstOrDefault(x => + string.Compare(tableDef.Name + x.Name, fieldDef.Name, StringComparison.OrdinalIgnoreCase) == 0 + || string.Compare(tableDef.ModelName + x.FieldName, fieldDef.Name, StringComparison.OrdinalIgnoreCase) == 0); } - public virtual SqlExpression Where(Expression> predicate) - { - AppendToWhere("AND", predicate); - return this; - } + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); - public virtual SqlExpression And(Expression> predicate) - { - AppendToWhere("AND", predicate); - return this; - } + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); - public virtual SqlExpression And(Expression> predicate) - { - AppendToWhere("AND", predicate); - return this; - } + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); - public virtual SqlExpression Or(Expression> predicate) - { - AppendToWhere("OR", predicate); - return this; - } + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); - public virtual SqlExpression Or(Expression> predicate) - { - AppendToWhere("OR", predicate); - return this; - } + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); + + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); public Tuple FirstMatchingField(string fieldName) { diff --git a/src/ServiceStack.OrmLite/Expressions/SqlExpression.cs b/src/ServiceStack.OrmLite/Expressions/SqlExpression.cs index df70b1f08..2853cccc8 100644 --- a/src/ServiceStack.OrmLite/Expressions/SqlExpression.cs +++ b/src/ServiceStack.OrmLite/Expressions/SqlExpression.cs @@ -1,49 +1,76 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; -using System.Collections.ObjectModel; using System.Linq.Expressions; +using System.Text.RegularExpressions; +using ServiceStack.Text; namespace ServiceStack.OrmLite { - public abstract partial class SqlExpression : ISqlExpression + public abstract partial class SqlExpression : ISqlExpression, IHasUntypedSqlExpression, IHasDialectProvider { + public const string TrueLiteral = "(1=1)"; + public const string FalseLiteral = "(1=0)"; + private Expression> underlyingExpression; - private List orderByProperties = new List(); + private List orderByProperties = new(); private string selectExpression = string.Empty; private string fromExpression = null; private string whereExpression; private string groupBy = string.Empty; private string havingExpression; private string orderBy = string.Empty; + public HashSet OnlyFields { get; protected set; } - IList updateFields = new List(); - IList insertFields = new List(); + public List UpdateFields { get; set; } + public List InsertFields { get; set; } private string sep = string.Empty; - protected bool useFieldName = false; - protected bool selectDistinct = false; - protected bool CustomSelect { get; set; } - private ModelDefinition modelDef; + protected ModelDefinition modelDef; + public string TableAlias { get; set; } + public IOrmLiteDialectProvider DialectProvider { get; set; } + public List Params { get; set; } + public Func SqlFilter { get; set; } + public static Action> SelectFilter { get; set; } + public int? Rows { get; set; } + public int? Offset { get; set; } public bool PrefixFieldWithTableName { get; set; } + public bool UseSelectPropertiesAsAliases { get; set; } public bool WhereStatementWithoutWhereString { get; set; } - public IOrmLiteDialectProvider DialectProvider { get; set; } + public ISet Tags { get; } = new HashSet(); - protected string Sep - { - get { return sep; } - } + protected bool CustomSelect { get; set; } + protected bool useFieldName = false; + protected bool selectDistinct = false; + protected bool visitedExpressionIsTableColumn = false; + protected bool skipParameterizationForThisExpression = false; + protected bool isSelectExpression = false; + private bool hasEnsureConditions = false; + private bool inSqlMethodCall = false; + + protected string Sep => sep; - public SqlExpression(IOrmLiteDialectProvider dialectProvider) + protected SqlExpression(IOrmLiteDialectProvider dialectProvider) { + UpdateFields = new List(); + InsertFields = new List(); + modelDef = typeof(T).GetModelDefinition(); - PrefixFieldWithTableName = false; + PrefixFieldWithTableName = OrmLiteConfig.IncludeTablePrefixes; WhereStatementWithoutWhereString = false; + DialectProvider = dialectProvider; + Params = new List(); tableDefs.Add(modelDef); + + var initFilter = OrmLiteConfig.SqlExpressionInitFilter; + initFilter?.Invoke(this.GetUntyped()); } public SqlExpression Clone() @@ -51,26 +78,143 @@ public SqlExpression Clone() return CopyTo(DialectProvider.SqlExpression()); } + public virtual void AddTag(string tag) + { + Debug.Assert(!string.IsNullOrEmpty(tag)); + Tags.Add(tag); + } + protected virtual SqlExpression CopyTo(SqlExpression to) { - to.underlyingExpression = underlyingExpression; - to.orderByProperties = orderByProperties; + to.modelDef = modelDef; + to.tableDefs = tableDefs; + + to.UpdateFields = UpdateFields; + to.InsertFields = InsertFields; + to.selectExpression = selectExpression; - to.selectDistinct = selectDistinct; - to.CustomSelect = CustomSelect; + to.OnlyFields = OnlyFields != null ? new HashSet(OnlyFields, StringComparer.OrdinalIgnoreCase) : null; + + to.TableAlias = TableAlias; to.fromExpression = fromExpression; to.whereExpression = whereExpression; to.groupBy = groupBy; to.havingExpression = havingExpression; to.orderBy = orderBy; - to.updateFields = updateFields; - to.insertFields = insertFields; - to.modelDef = modelDef; + to.orderByProperties = orderByProperties; + + to.Offset = Offset; + to.Rows = Rows; + + to.CustomSelect = CustomSelect; to.PrefixFieldWithTableName = PrefixFieldWithTableName; + to.useFieldName = useFieldName; + to.selectDistinct = selectDistinct; to.WhereStatementWithoutWhereString = WhereStatementWithoutWhereString; + to.visitedExpressionIsTableColumn = visitedExpressionIsTableColumn; + to.skipParameterizationForThisExpression = skipParameterizationForThisExpression; + to.UseSelectPropertiesAsAliases = UseSelectPropertiesAsAliases; + to.hasEnsureConditions = hasEnsureConditions; + + to.Params = new List(Params); + + to.underlyingExpression = underlyingExpression; + to.SqlFilter = SqlFilter; + return to; } + /// + /// Generate a unique SHA1 hash of expression with param values for caching + /// + public string ComputeHash(bool includeParams = true) + { + var uniqueExpr = Dump(includeParams); + // fastest up to 500 chars https://wintermute79.wordpress.com/2014/10/10/c-sha-1-benchmark/ + using var sha1 = new System.Security.Cryptography.SHA1Managed(); + var hash = sha1.ComputeHash(Encoding.ASCII.GetBytes(uniqueExpr)); + var hexFormat = hash.ToHex(); + + return hexFormat; + } + + /// + /// Dump internal state of this SqlExpression into a string + /// + /// + /// + public string Dump(bool includeParams) + { + var sb = StringBuilderCache.Allocate(); + + sb.Append('<').Append(ModelDef.Name); + foreach (var tableDef in tableDefs) + { + sb.Append(',').Append(tableDef); + } + sb.Append('>').AppendLine(); + + if (!UpdateFields.IsEmpty()) + sb.AppendLine(UpdateFields.Join(",")); + if (!InsertFields.IsEmpty()) + sb.AppendLine(InsertFields.Join(",")); + + if (!string.IsNullOrEmpty(selectExpression)) + sb.AppendLine(selectExpression); + if (!OnlyFields.IsEmpty()) + sb.AppendLine(OnlyFields.Join(",")); + + if (!string.IsNullOrEmpty(TableAlias)) + sb.AppendLine(TableAlias); + if (!string.IsNullOrEmpty(fromExpression)) + sb.AppendLine(fromExpression); + + if (!string.IsNullOrEmpty(whereExpression)) + sb.AppendLine(whereExpression); + + if (!string.IsNullOrEmpty(groupBy)) + sb.AppendLine(groupBy); + + if (!string.IsNullOrEmpty(havingExpression)) + sb.AppendLine(havingExpression); + + if (!string.IsNullOrEmpty(orderBy)) + sb.AppendLine(orderBy); + if (!orderByProperties.IsEmpty()) + sb.AppendLine(orderByProperties.Join(",")); + + if (Offset != null || Rows != null) + sb.Append(Offset ?? 0).Append(',').Append(Rows ?? 0).AppendLine(); + + sb.Append("FLAGS:"); + sb.Append(CustomSelect ? "1" : "0"); + sb.Append(PrefixFieldWithTableName ? "1" : "0"); + sb.Append(useFieldName ? "1" : "0"); + sb.Append(selectDistinct ? "1" : "0"); + sb.Append(WhereStatementWithoutWhereString ? "1" : "0"); + sb.Append(visitedExpressionIsTableColumn ? "1" : "0"); + sb.Append(skipParameterizationForThisExpression ? "1" : "0"); + sb.Append(UseSelectPropertiesAsAliases ? "1" : "0"); + sb.Append(hasEnsureConditions ? "1" : "0"); + sb.AppendLine(); + + if (includeParams) + { + sb.Append("PARAMS:").Append(Params.Count).AppendLine(); + if (Params.Count > 0) + { + foreach (var p in Params) + { + sb.Append(p.ParameterName).Append('='); + sb.AppendLine(p.Value.ConvertTo()); + } + } + } + + var uniqueExpr = StringBuilderCache.ReturnAndFree(sb); + return uniqueExpr; + } + /// /// Clear select expression. All properties will be selected. /// @@ -79,1000 +223,2071 @@ public virtual SqlExpression Select() return Select(string.Empty); } + internal SqlExpression SelectIfDistinct(string selectExpression) => + selectDistinct ? SelectDistinct(selectExpression) : Select(selectExpression); + /// /// set the specified selectExpression. /// /// - /// raw Select expression: "Select SomeField1, SomeField2 from SomeTable" + /// raw Select expression: "SomeField1, SomeField2 from SomeTable" /// public virtual SqlExpression Select(string selectExpression) { - if (string.IsNullOrEmpty(selectExpression)) + selectExpression?.SqlVerifyFragment(); + + return UnsafeSelect(selectExpression); + } + + /// + /// set the specified DISTINCT selectExpression. + /// + /// + /// raw Select expression: "SomeField1, SomeField2 from SomeTable" + /// + public virtual SqlExpression SelectDistinct(string selectExpression) + { + selectExpression?.SqlVerifyFragment(); + + return UnsafeSelect(selectExpression, distinct: true); + } + + public virtual SqlExpression UnsafeSelect(string rawSelect) => UnsafeSelect(rawSelect, distinct: false); + + public virtual SqlExpression UnsafeSelect(string rawSelect, bool distinct) + { + if (string.IsNullOrEmpty(rawSelect)) { - BuildSelectExpression(string.Empty, false); + BuildSelectExpression(string.Empty, distinct: distinct); } else { - selectExpression.SqlVerifyFragment(); - this.selectExpression = "SELECT " + selectExpression; + this.selectExpression = "SELECT " + (distinct ? "DISTINCT " : "") + rawSelect; this.CustomSelect = true; + OnlyFields = null; } return this; } /// - /// Fields to be selected. + /// Set the specified selectExpression using matching fields. /// /// - /// x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} + /// Matching Fields: "SomeField1, SomeField2" /// - /// - /// objectWithProperties - /// - public virtual SqlExpression Select(Expression> fields) - { - sep = string.Empty; - useFieldName = true; - BuildSelectExpression(Visit(fields).ToString(), false); - return this; - } + public virtual SqlExpression Select(string[] fields) => Select(fields, distinct: false); + + /// + /// Set the specified DISTINCT selectExpression using matching fields. + /// + /// + /// Matching Fields: "SomeField1, SomeField2" + /// + public virtual SqlExpression SelectDistinct(string[] fields) => Select(fields, distinct: true); - public virtual SqlExpression SelectDistinct(Expression> fields) + internal virtual SqlExpression Select(string[] fields, bool distinct) { - sep = string.Empty; + if (fields == null || fields.Length == 0) + return Select(string.Empty); + useFieldName = true; - BuildSelectExpression(Visit(fields).ToString(), true); - return this; - } - public virtual SqlExpression From(string tables) - { - if (string.IsNullOrEmpty(tables)) - { - FromExpression = null; - } - else + var allTableDefs = GetAllTables(); + + var fieldsList = new List(); + var sb = StringBuilderCache.Allocate(); + foreach (var field in fields) { - tables.SqlVerifyFragment(); - var singleTable = tables.ToLower().IndexOfAny("join", ",") == -1; - FromExpression = singleTable - ? " \nFROM " + DialectProvider.GetQuotedTableName(tables) - : " \nFROM " + tables; + if (string.IsNullOrEmpty(field)) + continue; + + if (field.EndsWith(".*")) + { + var tableName = field.Substring(0, field.Length - 2); + var tableDef = allTableDefs.FirstOrDefault(x => string.Equals(x.Name, tableName, StringComparison.OrdinalIgnoreCase)); + if (tableDef != null) + { + foreach (var fieldDef in tableDef.FieldDefinitionsArray) + { + var qualifiedField = GetQuotedColumnName(tableDef, fieldDef.Name); + if (fieldDef.CustomSelect != null) + qualifiedField += " AS " + fieldDef.Name; + + if (sb.Length > 0) + sb.Append(", "); + + sb.Append(qualifiedField); + fieldsList.Add(fieldDef.Name); + } + } + } + else + { + fieldsList.Add(field); //Could be non-matching referenced property + + var match = FirstMatchingField(field); + if (match == null) + continue; + + var fieldDef = match.Item2; + var qualifiedName = GetQuotedColumnName(match.Item1, fieldDef.Name); + if (fieldDef.CustomSelect != null) + qualifiedName += " AS " + fieldDef.Name; + + if (sb.Length > 0) + sb.Append(", "); + + sb.Append(qualifiedName); + } } - return this; - } + UnsafeSelect(StringBuilderCache.ReturnAndFree(sb), distinct: distinct); + OnlyFields = new HashSet(fieldsList, StringComparer.OrdinalIgnoreCase); - public virtual SqlExpression Where() - { - if (underlyingExpression != null) underlyingExpression = null; //Where() clears the expression - whereExpression = null; return this; } - public virtual SqlExpression Where(string sqlFilter, params object[] filterParams) + private SqlExpression InternalSelect(Expression fields, bool distinct = false) { - AppendToWhere("AND", sqlFilter.SqlFmt(filterParams).SqlVerifyFragment()); - return this; - } + Reset(sep = string.Empty); - public virtual SqlExpression And(string sqlFilter, params object[] filterParams) - { - AppendToWhere("AND", sqlFilter.SqlFmt(filterParams).SqlVerifyFragment()); + CustomSelect = true; + + isSelectExpression = true; + var selectSql = Visit(fields); + isSelectExpression = false; + + if (!IsSqlClass(selectSql)) + { + selectSql = ConvertToParam(selectSql); + } + BuildSelectExpression(selectSql.ToString(), distinct: distinct); return this; } - public virtual SqlExpression Or(string sqlFilter, params object[] filterParams) + /// + /// Fields to be selected. + /// + /// + /// x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} + /// + public virtual SqlExpression Select(Expression> fields) { - AppendToWhere("OR", sqlFilter.SqlFmt(filterParams).SqlVerifyFragment()); - return this; + return InternalSelect(fields); } - public virtual SqlExpression AddCondition(string condition, string sqlFilter, params object[] filterParams) + public virtual SqlExpression Select(Expression> fields) { - AppendToWhere(condition, sqlFilter.SqlFmt(filterParams).SqlVerifyFragment()); - return this; + return InternalSelect(fields); } - public virtual SqlExpression Where(Expression> predicate) + public virtual SqlExpression Select(Expression> fields) { - AppendToWhere("AND", predicate); - return this; + return InternalSelect(fields); } - public virtual SqlExpression And(Expression> predicate) + public virtual SqlExpression Select(Expression> fields) { - AppendToWhere("AND", predicate); - return this; + return InternalSelect(fields); } - public virtual SqlExpression Or(Expression> predicate) + public virtual SqlExpression Select(Expression> fields) { - AppendToWhere("OR", predicate); - return this; + return InternalSelect(fields); } - protected void AppendToWhere(string condition, Expression predicate) + public virtual SqlExpression Select(Expression> fields) { - if (predicate == null) - return; - - useFieldName = true; - sep = " "; - var newExpr = Visit(predicate).ToString(); - AppendToWhere(condition, newExpr); + return InternalSelect(fields); } - protected void AppendToWhere(string condition, string sqlExpression) + public virtual SqlExpression Select(Expression> fields) { - whereExpression = string.IsNullOrEmpty(whereExpression) - ? (WhereStatementWithoutWhereString ? "" : "WHERE ") - : whereExpression + " " + condition + " "; - - whereExpression += sqlExpression; + return InternalSelect(fields); } - public virtual SqlExpression GroupBy() + public virtual SqlExpression Select(Expression> fields) { - return GroupBy(string.Empty); + return InternalSelect(fields); } - public virtual SqlExpression GroupBy(string groupBy) + public virtual SqlExpression Select(Expression> fields) { - groupBy.SqlVerifyFragment(); - this.groupBy = groupBy; - return this; + return InternalSelect(fields); } - public virtual SqlExpression GroupBy(Expression> keySelector) + public virtual SqlExpression Select(Expression> fields) { - sep = string.Empty; - useFieldName = true; - groupBy = Visit(keySelector).ToString(); - if (!string.IsNullOrEmpty(groupBy)) groupBy = string.Format("GROUP BY {0}", groupBy); - return this; + return InternalSelect(fields); } - - public virtual SqlExpression Having() + public virtual SqlExpression Select(Expression> fields) { - return Having(string.Empty); + return InternalSelect(fields); } - public virtual SqlExpression Having(string sqlFilter, params object[] filterParams) + public virtual SqlExpression Select(Expression> fields) { - havingExpression = !string.IsNullOrEmpty(sqlFilter) ? sqlFilter.SqlFmt(filterParams) : string.Empty; - if (!string.IsNullOrEmpty(havingExpression)) havingExpression = "HAVING " + havingExpression; - return this; + return InternalSelect(fields); } - public virtual SqlExpression Having(Expression> predicate) + public virtual SqlExpression Select(Expression> fields) { - if (predicate != null) - { - useFieldName = true; - sep = " "; - havingExpression = Visit(predicate).ToString(); - if (!string.IsNullOrEmpty(havingExpression)) havingExpression = "HAVING " + havingExpression; - } - else - havingExpression = string.Empty; - - return this; + return InternalSelect(fields); } - public virtual SqlExpression OrderBy() + public virtual SqlExpression SelectDistinct(Expression> fields) { - return OrderBy(string.Empty); + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression OrderBy(string orderBy) + public virtual SqlExpression SelectDistinct(Expression> fields) { - orderBy.SqlVerifyFragment(); - orderByProperties.Clear(); - this.orderBy = string.IsNullOrEmpty(orderBy) - ? null - : "ORDER BY " + orderBy; - return this; + return InternalSelect(fields, distinct: true); } - public ModelDefinition GetModelDefinition(FieldDefinition fieldDef) + public virtual SqlExpression SelectDistinct(Expression> fields) { - if (modelDef.FieldDefinitions.Any(x => x == fieldDef)) - return modelDef; - - return tableDefs - .FirstOrDefault(tableDef => tableDef.FieldDefinitions.Any(x => x == fieldDef)); + return InternalSelect(fields, distinct: true); } - private SqlExpression OrderByFields(string orderBySuffix, FieldDefinition[] fields) + public virtual SqlExpression SelectDistinct(Expression> fields) { - orderByProperties.Clear(); - - var sbOrderBy = new StringBuilder(); - foreach (var field in fields) - { - var tableDef = GetModelDefinition(field); - var qualifiedName = modelDef != null - ? DialectProvider.GetQuotedColumnName(tableDef, field) - : DialectProvider.GetQuotedColumnName(field); - - if (sbOrderBy.Length > 0) - sbOrderBy.Append(", "); - - sbOrderBy.Append(qualifiedName + orderBySuffix); - } - - this.orderBy = sbOrderBy.Length == 0 - ? null - : "ORDER BY " + sbOrderBy; - return this; + return InternalSelect(fields, distinct: true); } - static class OrderBySuffix + public virtual SqlExpression SelectDistinct(Expression> fields) { - public const string Asc = ""; - public const string Desc = " DESC"; + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression OrderByFields(params FieldDefinition[] fields) + public virtual SqlExpression SelectDistinct(Expression> fields) { - return OrderByFields(OrderBySuffix.Asc, fields); + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression OrderByFieldsDescending(params FieldDefinition[] fields) + public virtual SqlExpression SelectDistinct(Expression> fields) { - return OrderByFields(OrderBySuffix.Desc, fields); + return InternalSelect(fields, distinct: true); } - private SqlExpression OrderByFields(string orderBySuffix, string[] fieldNames) + public virtual SqlExpression SelectDistinct(Expression> fields) { - orderByProperties.Clear(); - - var sbOrderBy = new StringBuilder(); - foreach (var fieldName in fieldNames) - { - var reverse = fieldName.StartsWith("-"); - var useSuffix = reverse - ? (orderBySuffix == OrderBySuffix.Asc ? OrderBySuffix.Desc : OrderBySuffix.Asc) - : orderBySuffix; - var useName = reverse ? fieldName.Substring(1) : fieldName; - - var field = FirstMatchingField(useName); - if (field == null) - throw new ArgumentException("Could not find field " + useName); - var qualifiedName = DialectProvider.GetQuotedColumnName(field.Item1, field.Item2); - - if (sbOrderBy.Length > 0) - sbOrderBy.Append(", "); - - sbOrderBy.Append(qualifiedName + useSuffix); - } - - this.orderBy = sbOrderBy.Length == 0 - ? null - : "ORDER BY " + sbOrderBy; - return this; + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression OrderByFields(params string[] fieldNames) + public virtual SqlExpression SelectDistinct(Expression> fields) { - return OrderByFields("", fieldNames); + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression OrderByFieldsDescending(params string[] fieldNames) + public virtual SqlExpression SelectDistinct(Expression> fields) { - return OrderByFields(" DESC", fieldNames); + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression OrderBy(Expression> keySelector) + public virtual SqlExpression SelectDistinct(Expression> fields) { - return OrderByInternal(keySelector); + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression OrderBy
(Expression> keySelector) + public virtual SqlExpression SelectDistinct(Expression> fields) { - return OrderByInternal(keySelector); + return InternalSelect(fields, distinct: true); } - private SqlExpression OrderByInternal(Expression keySelector) + public virtual SqlExpression SelectDistinct(Expression> fields) { - sep = string.Empty; - useFieldName = true; - orderByProperties.Clear(); - var fields = Visit(keySelector).ToString(); - orderByProperties.Add(fields); - BuildOrderByClauseInternal(); - return this; + return InternalSelect(fields, distinct: true); } - public virtual SqlExpression ThenBy(string orderBy) + public virtual SqlExpression SelectDistinct() { - orderBy.SqlVerifyFragment(); - orderByProperties.Add(orderBy); - BuildOrderByClauseInternal(); + selectDistinct = true; return this; } - public virtual SqlExpression ThenBy(Expression> keySelector) + public virtual SqlExpression From(string tables) { - return ThenByInternal(keySelector); - } + tables?.SqlVerifyFragment(); - public virtual SqlExpression ThenBy
(Expression> keySelector) - { - return ThenByInternal(keySelector); + return UnsafeFrom(tables); } - private SqlExpression ThenByInternal(Expression keySelector) + public virtual SqlExpression IncludeTablePrefix() { - sep = string.Empty; - useFieldName = true; - var fields = Visit(keySelector).ToString(); - orderByProperties.Add(fields); - BuildOrderByClauseInternal(); + PrefixFieldWithTableName = true; return this; } - public virtual SqlExpression OrderByDescending(Expression> keySelector) - { - return OrderByDescendingInternal(keySelector); - } - - public virtual SqlExpression OrderByDescending
(Expression> keySelector) + public virtual SqlExpression SetTableAlias(string tableAlias) { - return OrderByDescendingInternal(keySelector); + PrefixFieldWithTableName = tableAlias != null; + TableAlias = tableAlias; + return this; } - private SqlExpression OrderByDescendingInternal(Expression keySelector) + public virtual SqlExpression UnsafeFrom(string rawFrom) { - sep = string.Empty; - useFieldName = true; - orderByProperties.Clear(); - var fields = Visit(keySelector).ToString().Split(','); - foreach (var field in fields) + if (string.IsNullOrEmpty(rawFrom)) { - orderByProperties.Add(field.Trim() + " DESC"); + FromExpression = null; } - BuildOrderByClauseInternal(); + else + { + var singleTable = rawFrom.ToLower().IndexOfAny("join", ",") == -1; + FromExpression = singleTable + ? " \nFROM " + DialectProvider.GetQuotedTableName(rawFrom) + : " \nFROM " + rawFrom; + } + return this; } - public virtual SqlExpression ThenByDescending(string orderBy) + public virtual SqlExpression Where() { - orderBy.SqlVerifyFragment(); - orderByProperties.Add(orderBy + " DESC"); - BuildOrderByClauseInternal(); + underlyingExpression = null; //Where() clears the expression + + whereExpression = null; return this; } - public virtual SqlExpression ThenByDescending(Expression> keySelector) + private string FormatFilter(string sqlFilter, params object[] filterParams) { - return ThenByDescendingInternal(keySelector); - } - - public virtual SqlExpression ThenByDescending
(Expression> keySelector) - { - return ThenByDescendingInternal(keySelector); - } + if (string.IsNullOrEmpty(sqlFilter)) + return null; - private SqlExpression ThenByDescendingInternal(Expression keySelector) - { - sep = string.Empty; - useFieldName = true; - var fields = Visit(keySelector).ToString().Split(','); - foreach (var field in fields) + for (var i = 0; i < filterParams.Length; i++) { - orderByProperties.Add(field.Trim() + " DESC"); + var pLiteral = "{" + i + "}"; + var filterParam = filterParams[i]; + + if (filterParam is SqlInValues sqlParams) + { + if (sqlParams.Count > 0) + { + var sqlIn = CreateInParamSql(sqlParams.GetValues()); + sqlFilter = sqlFilter.Replace(pLiteral, sqlIn); + } + else + { + sqlFilter = sqlFilter.Replace(pLiteral, SqlInValues.EmptyIn); + } + } + else + { + var p = AddParam(filterParam); + sqlFilter = sqlFilter.Replace(pLiteral, p.ParameterName); + } } - BuildOrderByClauseInternal(); - return this; + return sqlFilter; } - private void BuildOrderByClauseInternal() + private string CreateInParamSql(IEnumerable values) { - if (orderByProperties.Count > 0) + var sbParams = StringBuilderCache.Allocate(); + foreach (var item in values) { - var sb = new StringBuilder(); - foreach (var prop in orderByProperties) - { - if (sb.Length > 0) - sb.Append(", "); + var p = AddParam(item); - sb.Append(prop); - } - orderBy = "ORDER BY " + sb; - } - else - { - orderBy = null; + if (sbParams.Length > 0) + sbParams.Append(","); + + sbParams.Append(p.ParameterName); } + var sqlIn = StringBuilderCache.ReturnAndFree(sbParams); + return sqlIn; } - /// - /// Offset of the first row to return. The offset of the initial row is 0 - /// - public virtual SqlExpression Skip(int? skip = null) + public virtual SqlExpression UnsafeWhere(string rawSql, params object[] filterParams) { - Offset = skip; - return this; + return AppendToWhere("AND", FormatFilter(rawSql, filterParams)); } - /// - /// Number of rows returned by a SELECT statement - /// - public virtual SqlExpression Take(int? take = null) + public virtual SqlExpression Where(string sqlFilter, params object[] filterParams) { - Rows = take; - return this; + return AppendToWhere("AND", FormatFilter(sqlFilter.SqlVerifyFragment(), filterParams)); } - /// - /// Set the specified offset and rows for SQL Limit clause. - /// - /// - /// Offset of the first row to return. The offset of the initial row is 0 - /// - /// - /// Number of rows returned by a SELECT statement - /// - public virtual SqlExpression Limit(int skip, int rows) + public virtual SqlExpression UnsafeAnd(string rawSql, params object[] filterParams) { - Offset = skip; - Rows = rows; - return this; + return AppendToWhere("AND", FormatFilter(rawSql, filterParams)); } - /// - /// Set the specified offset and rows for SQL Limit clause where they exist. - /// - /// - /// Offset of the first row to return. The offset of the initial row is 0 - /// - /// - /// Number of rows returned by a SELECT statement - /// - public virtual SqlExpression Limit(int? skip, int? rows) + public virtual SqlExpression And(string sqlFilter, params object[] filterParams) { - Offset = skip; - Rows = rows; - return this; + return AppendToWhere("AND", FormatFilter(sqlFilter.SqlVerifyFragment(), filterParams)); } - /// - /// Set the specified rows for Sql Limit clause. - /// - /// - /// Number of rows returned by a SELECT statement - /// - public virtual SqlExpression Limit(int rows) + public virtual SqlExpression UnsafeOr(string rawSql, params object[] filterParams) { - Offset = null; - Rows = rows; - return this; + return AppendToWhere("OR", FormatFilter(rawSql, filterParams)); } - /// - /// Clear Sql Limit clause - /// - public virtual SqlExpression Limit() + public virtual SqlExpression Or(string sqlFilter, params object[] filterParams) { - Offset = null; - Rows = null; - return this; + return AppendToWhere("OR", FormatFilter(sqlFilter.SqlVerifyFragment(), filterParams)); } - /// - /// Clear Offset and Limit clauses. Alias for Limit() - /// - /// - public virtual SqlExpression ClearLimits() + public virtual SqlExpression AddCondition(string condition, string sqlFilter, params object[] filterParams) { - return Limit(); + return AppendToWhere(condition, FormatFilter(sqlFilter.SqlVerifyFragment(), filterParams)); } - /// - /// Fields to be updated. - /// - /// - /// IList containing Names of properties to be updated - /// - public virtual SqlExpression Update(IList updateFields) - { - this.updateFields = updateFields; - return this; - } + public virtual SqlExpression Where(Expression> predicate) => AppendToWhere("AND", predicate); + public virtual SqlExpression Where(Expression> predicate, params object[] filterParams) => + AppendToWhere("AND", predicate, filterParams); - /// - /// Fields to be updated. - /// - /// - /// x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} - /// - /// - /// objectWithProperties - /// - public virtual SqlExpression Update(Expression> fields) - { - sep = string.Empty; - useFieldName = false; - updateFields = Visit(fields).ToString().Split(',').ToList(); - return this; - } + public virtual SqlExpression And(Expression> predicate) => AppendToWhere("AND", predicate); + public virtual SqlExpression And(Expression> predicate, params object[] filterParams) => + AppendToWhere("AND", predicate, filterParams); - /// - /// Clear UpdateFields list ( all fields will be updated) - /// - public virtual SqlExpression Update() - { - this.updateFields = new List(); - return this; - } + public virtual SqlExpression Or(Expression> predicate) => AppendToWhere("OR", predicate); - /// - /// Fields to be inserted. - /// - /// - /// x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} - /// - /// - /// objectWithProperties - /// - public virtual SqlExpression Insert(Expression> fields) - { - sep = string.Empty; - useFieldName = false; - insertFields = Visit(fields).ToString().Split(',').ToList(); - return this; - } + public virtual SqlExpression Or(Expression> predicate, params object[] filterParams) => + AppendToWhere("OR", predicate, filterParams); - /// - /// fields to be inserted. - /// - /// - /// IList<string> containing Names of properties to be inserted - /// - public virtual SqlExpression Insert(IList insertFields) - { - this.insertFields = insertFields; - return this; - } + private LambdaExpression originalLambda; - /// - /// Clear InsertFields list ( all fields will be inserted) - /// - public virtual SqlExpression Insert() + void Reset(string sep = " ", bool useFieldName = true) { - this.insertFields = new List(); - return this; + this.sep = sep; + this.useFieldName = useFieldName; + this.originalLambda = null; } - public string SqlTable(ModelDefinition modelDef) + protected SqlExpression AppendToWhere(string condition, Expression predicate, object[] filterParams) { - return DialectProvider.GetQuotedTableName(modelDef); + if (predicate == null) + return this; + + Reset(); + + var newExpr = WhereExpressionToString(Visit(predicate)); + var formatExpr = FormatFilter(newExpr, filterParams); + return AppendToWhere(condition, formatExpr); } - public string SqlColumn(string columnName) + protected SqlExpression AppendToWhere(string condition, Expression predicate) { - return DialectProvider.GetQuotedColumnName(columnName); + if (predicate == null) + return this; + + Reset(); + + var newExpr = WhereExpressionToString(Visit(predicate)); + return AppendToWhere(condition, newExpr); } - public virtual string ToDeleteRowStatement() + private static string WhereExpressionToString(object expression) { - return string.Format("DELETE FROM {0} {1}", - DialectProvider.GetQuotedTableName(modelDef), WhereExpression); + if (expression is bool b) + return b ? TrueLiteral : FalseLiteral; + return expression.ToString(); } - public virtual string ToUpdateStatement(T item, bool excludeDefaults = false) + protected SqlExpression AppendToWhere(string condition, string sqlExpression) { - var setFields = new StringBuilder(); + var addExpression = string.IsNullOrEmpty(whereExpression) + ? (WhereStatementWithoutWhereString ? "" : "WHERE ") + sqlExpression + : " " + condition + " " + sqlExpression; - foreach (var fieldDef in modelDef.FieldDefinitions) + if (!hasEnsureConditions) { - if (fieldDef.ShouldSkipUpdate()) continue; - if (fieldDef.IsRowVersion) continue; - if (updateFields.Count > 0 && !updateFields.Contains(fieldDef.Name)) continue; // added - - var value = fieldDef.GetValue(item); - if (excludeDefaults && (value == null || value.Equals(value.GetType().GetDefaultValue()))) continue; //GetDefaultValue? - - fieldDef.GetQuotedValue(item, DialectProvider); - - if (setFields.Length > 0) - setFields.Append(", "); - - setFields - .Append(DialectProvider.GetQuotedColumnName(fieldDef.FieldName)) - .Append("=") - .Append(DialectProvider.GetQuotedValue(value, fieldDef.FieldType)); + whereExpression += addExpression; } + else + { + if (whereExpression[whereExpression.Length - 1] != ')') + throw new NotSupportedException("Invalid whereExpression Expression with Ensure Conditions"); - return string.Format("UPDATE {0} SET {1} {2}", - DialectProvider.GetQuotedTableName(modelDef), setFields, WhereExpression); + // insert before normal WHERE parens: {EnsureConditions} AND (1+1) + if (whereExpression.EndsWith(TrueLiteral, StringComparison.Ordinal)) // insert before ^1+1) + { + whereExpression = whereExpression.Substring(0, whereExpression.Length - (TrueLiteral.Length - 1)) + + sqlExpression + ")"; + } + else // insert before ^) + { + whereExpression = whereExpression.Substring(0, whereExpression.Length - 1) + + addExpression + ")"; + } + } + return this; } - public virtual string ToSelectStatement() + public virtual SqlExpression Ensure(Expression> predicate) => AppendToEnsure(predicate); + public virtual SqlExpression Ensure(Expression> predicate) => AppendToEnsure(predicate); + public virtual SqlExpression Ensure(Expression> predicate) => AppendToEnsure(predicate); + public virtual SqlExpression Ensure(Expression> predicate) => AppendToEnsure(predicate); + public virtual SqlExpression Ensure(Expression> predicate) => AppendToEnsure(predicate); + public virtual SqlExpression Ensure(Expression> predicate) => AppendToEnsure(predicate); + + protected SqlExpression AppendToEnsure(Expression predicate) { - var sql = DialectProvider - .ToSelectStatement(modelDef, SelectExpression, BodyExpression, OrderByExpression, Offset, Rows); + if (predicate == null) + return this; - return sql; - } + Reset(); - public virtual string ToCountStatement() - { - return "SELECT COUNT(*)" + BodyExpression; + var newExpr = WhereExpressionToString(Visit(predicate)); + return Ensure(newExpr); } - public string SelectExpression + /// + /// Add a WHERE Condition to always be applied, irrespective of other WHERE conditions + /// + public SqlExpression Ensure(string sqlFilter, params object[] filterParams) { - get + var condition = FormatFilter(sqlFilter, filterParams); + if (string.IsNullOrEmpty(whereExpression)) { - if (string.IsNullOrEmpty(selectExpression)) - BuildSelectExpression(string.Empty, false); - return selectExpression; + whereExpression = "WHERE " + condition + + " AND " + TrueLiteral; //allow subsequent WHERE conditions to be inserted before parens } - set + else { - selectExpression = value; + if (!hasEnsureConditions) + { + var existingExpr = whereExpression.StartsWith("WHERE ", StringComparison.OrdinalIgnoreCase) + ? whereExpression.Substring("WHERE ".Length) + : whereExpression; + + whereExpression = "WHERE " + condition + " AND (" + existingExpr + ")"; + } + else + { + if (!whereExpression.StartsWith("WHERE ", StringComparison.OrdinalIgnoreCase)) + throw new NotSupportedException("Invalid whereExpression Expression with Ensure Conditions"); + + whereExpression = "WHERE " + condition + " AND " + whereExpression.Substring("WHERE ".Length); + } } + + hasEnsureConditions = true; + return this; } - public string FromExpression + private string ListExpression(Expression expr, string strExpr) { - get + if (expr is LambdaExpression lambdaExpr) { - return string.IsNullOrEmpty(fromExpression) - ? " \nFROM " + DialectProvider.GetQuotedTableName(modelDef) - : fromExpression; + if (lambdaExpr.Parameters.Count == 1 && lambdaExpr.Body is MemberExpression me) + { + var tableDef = lambdaExpr.Parameters[0].Type.GetModelMetadata(); + var fieldDef = tableDef?.GetFieldDefinition(me.Member.Name); + if (fieldDef != null) + return DialectProvider.GetQuotedColumnName(tableDef, me.Member.Name); + } } - set { fromExpression = value; } + return strExpr; } - public string BodyExpression + public virtual SqlExpression GroupBy() { - get - { - return FromExpression - + (string.IsNullOrEmpty(WhereExpression) ? "" : "\n" + WhereExpression) - + (string.IsNullOrEmpty(GroupByExpression) ? "" : "\n" + GroupByExpression) - + (string.IsNullOrEmpty(HavingExpression) ? "" : "\n" + HavingExpression); - } + return GroupBy(string.Empty); } - public string WhereExpression + public virtual SqlExpression GroupBy(string groupBy) { - get - { - return whereExpression; - } - set - { - whereExpression = value; - } + return UnsafeGroupBy(groupBy.SqlVerifyFragment()); } - public string GroupByExpression + public virtual SqlExpression UnsafeGroupBy(string groupBy) { - get - { - return groupBy; - } - set - { - groupBy = value; - } + if (!string.IsNullOrEmpty(groupBy)) + this.groupBy = "GROUP BY " + groupBy; + return this; } - public string HavingExpression + private SqlExpression InternalGroupBy(Expression expr) { - get + Reset(sep = string.Empty); + + var groupByExpr = Visit(expr); + if (IsSqlClass(groupByExpr)) { - return havingExpression; + StripAliases(groupByExpr as SelectList); // No "AS ColumnAlias" in GROUP BY, just the column names/expressions + + return GroupBy(groupByExpr.ToString()); } - set + if (groupByExpr is string strExpr) { - havingExpression = value; + return GroupBy(ListExpression(expr, strExpr)); } - } + return this; + } - public string OrderByExpression + public virtual SqlExpression GroupBy
(Expression> keySelector) { - get - { - return string.IsNullOrEmpty(orderBy) ? "" : "\n" + orderBy; - } - set - { - orderBy = value; - } + return InternalGroupBy(keySelector); } - public int? Rows { get; set; } - public int? Offset { get; set; } + public virtual SqlExpression GroupBy(Expression> keySelector) + { + return InternalGroupBy(keySelector); + } - public IList UpdateFields + public virtual SqlExpression GroupBy(Expression> keySelector) { - get - { - return updateFields; - } - set - { - updateFields = value; - } + return InternalGroupBy(keySelector); } - public IList InsertFields + public virtual SqlExpression GroupBy(Expression> keySelector) { - get - { - return insertFields; - } - set - { - insertFields = value; - } + return InternalGroupBy(keySelector); } - protected internal ModelDefinition ModelDef + public virtual SqlExpression GroupBy(Expression> keySelector) { - get + return InternalGroupBy(keySelector); + } + + public virtual SqlExpression Having() + { + return Having(string.Empty); + } + + public virtual SqlExpression Having(string sqlFilter, params object[] filterParams) + { + havingExpression = FormatFilter(sqlFilter.SqlVerifyFragment(), filterParams); + + if (havingExpression != null) + havingExpression = "HAVING " + havingExpression; + + return this; + } + + public virtual SqlExpression UnsafeHaving(string sqlFilter, params object[] filterParams) + { + havingExpression = FormatFilter(sqlFilter, filterParams); + + if (havingExpression != null) + havingExpression = "HAVING " + havingExpression; + + return this; + } + + protected SqlExpression AppendHaving(Expression predicate) + { + if (predicate != null) + { + Reset(); + + havingExpression = WhereExpressionToString(Visit(predicate)); + if (!string.IsNullOrEmpty(havingExpression)) + havingExpression = "HAVING " + havingExpression; + } + else + havingExpression = string.Empty; + + return this; + } + + public virtual SqlExpression Having(Expression> predicate) => AppendHaving(predicate); + public virtual SqlExpression Having
(Expression> predicate) => AppendHaving(predicate); + public virtual SqlExpression Having(Expression> predicate) => AppendHaving(predicate); + public virtual SqlExpression Having(Expression> predicate) => AppendHaving(predicate); + + public virtual SqlExpression OrderBy() => OrderBy(string.Empty); + + public virtual SqlExpression OrderBy(string orderBy) => UnsafeOrderBy(orderBy.SqlVerifyFragment()); + + public virtual SqlExpression OrderBy(long columnIndex) => UnsafeOrderBy(columnIndex.ToString()); + + public virtual SqlExpression UnsafeOrderBy(string orderBy) + { + orderByProperties.Clear(); + if (!string.IsNullOrEmpty(orderBy)) { + orderByProperties.Add(orderBy); + } + BuildOrderByClauseInternal(); + return this; + } + + public virtual SqlExpression OrderByRandom() => OrderBy(DialectProvider.SqlRandom); + + public ModelDefinition GetModelDefinition(FieldDefinition fieldDef) + { + if (modelDef.FieldDefinitions.Any(x => x == fieldDef)) return modelDef; + + return tableDefs + .FirstOrDefault(tableDef => tableDef.FieldDefinitions.Any(x => x == fieldDef)); + } + + private SqlExpression OrderByFields(string orderBySuffix, FieldDefinition[] fields) + { + orderByProperties.Clear(); + + if (fields.Length == 0) + { + this.orderBy = null; + return this; + } + + useFieldName = true; + + var sbOrderBy = StringBuilderCache.Allocate(); + foreach (var field in fields) + { + var tableDef = GetModelDefinition(field); + var qualifiedName = tableDef != null + ? GetQuotedColumnName(tableDef, field.Name) + : DialectProvider.GetQuotedColumnName(field); + + if (sbOrderBy.Length > 0) + sbOrderBy.Append(", "); + + sbOrderBy.Append(qualifiedName + orderBySuffix); + } + + this.orderBy = "ORDER BY " + StringBuilderCache.ReturnAndFree(sbOrderBy); + return this; + } + + static class OrderBySuffix + { + public const string Asc = ""; + public const string Desc = " DESC"; + } + + public virtual SqlExpression OrderByFields(params FieldDefinition[] fields) => OrderByFields(OrderBySuffix.Asc, fields); + + public virtual SqlExpression OrderByFieldsDescending(params FieldDefinition[] fields) => OrderByFields(OrderBySuffix.Desc, fields); + + private SqlExpression OrderByFields(string orderBySuffix, string[] fieldNames) + { + orderByProperties.Clear(); + + if (fieldNames.Length == 0) + { + this.orderBy = null; + return this; + } + + useFieldName = true; + + var sbOrderBy = StringBuilderCache.Allocate(); + foreach (var fieldName in fieldNames) + { + var reverse = fieldName.StartsWith("-"); + var useSuffix = reverse + ? (orderBySuffix == OrderBySuffix.Asc ? OrderBySuffix.Desc : OrderBySuffix.Asc) + : orderBySuffix; + var useName = reverse ? fieldName.Substring(1) : fieldName; + + var field = FirstMatchingField(useName); + var qualifiedName = field != null + ? GetQuotedColumnName(field.Item1, field.Item2.Name) + : string.Equals("Random", useName, StringComparison.OrdinalIgnoreCase) + ? DialectProvider.SqlRandom + : throw new ArgumentException("Could not find field " + useName); + + if (sbOrderBy.Length > 0) + sbOrderBy.Append(", "); + + sbOrderBy.Append(qualifiedName + useSuffix); + } + + this.orderBy = "ORDER BY " + StringBuilderCache.ReturnAndFree(sbOrderBy); + return this; + } + + public virtual SqlExpression OrderByFields(params string[] fieldNames) => OrderByFields("", fieldNames); + + public virtual SqlExpression OrderByFieldsDescending(params string[] fieldNames) => OrderByFields(" DESC", fieldNames); + + public virtual SqlExpression OrderBy(Expression> keySelector) => OrderByInternal(keySelector); + + public virtual SqlExpression OrderBy
(Expression> fields) => OrderByInternal(fields); + public virtual SqlExpression OrderBy(Expression> fields) => OrderByInternal(fields); + public virtual SqlExpression OrderBy(Expression> fields) => OrderByInternal(fields); + public virtual SqlExpression OrderBy(Expression> fields) => OrderByInternal(fields); + public virtual SqlExpression OrderBy(Expression> fields) => OrderByInternal(fields); + + private SqlExpression OrderByInternal(Expression expr) + { + Reset(sep = string.Empty); + + orderByProperties.Clear(); + var orderBySql = Visit(expr); + if (IsSqlClass(orderBySql)) + { + var fields = orderBySql.ToString(); + orderByProperties.Add(fields); + BuildOrderByClauseInternal(); + } + else if (orderBySql is string strExpr) + { + return GroupBy(ListExpression(expr, strExpr)); + } + return this; + } + + public static bool IsSqlClass(object obj) + { + return obj != null && + (obj is PartialSqlString || + obj is SelectList); + } + + public virtual SqlExpression ThenBy(string orderBy) + { + orderBy.SqlVerifyFragment(); + orderByProperties.Add(orderBy); + BuildOrderByClauseInternal(); + return this; + } + + public virtual SqlExpression ThenBy(Expression> keySelector) => ThenByInternal(keySelector); + public virtual SqlExpression ThenBy
(Expression> fields) => ThenByInternal(fields); + public virtual SqlExpression ThenBy(Expression> fields) => ThenByInternal(fields); + public virtual SqlExpression ThenBy(Expression> fields) => ThenByInternal(fields); + public virtual SqlExpression ThenBy(Expression> fields) => ThenByInternal(fields); + public virtual SqlExpression ThenBy(Expression> fields) => ThenByInternal(fields); + + private SqlExpression ThenByInternal(Expression keySelector) + { + Reset(sep = string.Empty); + + var orderBySql = Visit(keySelector); + if (IsSqlClass(orderBySql)) + { + var fields = orderBySql.ToString(); + orderByProperties.Add(fields); + BuildOrderByClauseInternal(); + } + return this; + } + + public virtual SqlExpression OrderByDescending(Expression> keySelector) + { + return OrderByDescendingInternal(keySelector); + } + + public virtual SqlExpression OrderByDescending
(Expression> keySelector) => OrderByDescendingInternal(keySelector); + public virtual SqlExpression OrderByDescending(Expression> fields) => OrderByDescendingInternal(fields); + public virtual SqlExpression OrderByDescending(Expression> fields) => OrderByDescendingInternal(fields); + public virtual SqlExpression OrderByDescending(Expression> fields) => OrderByDescendingInternal(fields); + public virtual SqlExpression OrderByDescending(Expression> fields) => OrderByDescendingInternal(fields); + + private SqlExpression OrderByDescendingInternal(Expression keySelector) + { + Reset(sep = string.Empty); + + orderByProperties.Clear(); + var orderBySql = Visit(keySelector); + if (IsSqlClass(orderBySql)) + { + var fields = orderBySql.ToString(); + fields.ParseTokens() + .Each(x => orderByProperties.Add(x + " DESC")); + BuildOrderByClauseInternal(); + } + return this; + } + + public virtual SqlExpression OrderByDescending(string orderBy) => UnsafeOrderByDescending(orderBy.SqlVerifyFragment()); + + public virtual SqlExpression OrderByDescending(long columnIndex) => UnsafeOrderByDescending(columnIndex.ToString()); + + private SqlExpression UnsafeOrderByDescending(string orderBy) + { + orderByProperties.Clear(); + orderByProperties.Add(orderBy + " DESC"); + BuildOrderByClauseInternal(); + return this; + } + + public virtual SqlExpression ThenByDescending(string orderBy) + { + orderBy.SqlVerifyFragment(); + orderByProperties.Add(orderBy + " DESC"); + BuildOrderByClauseInternal(); + return this; + } + + public virtual SqlExpression ThenByDescending(Expression> keySelector) => ThenByDescendingInternal(keySelector); + public virtual SqlExpression ThenByDescending
(Expression> fields) => ThenByDescendingInternal(fields); + public virtual SqlExpression ThenByDescending(Expression> fields) => ThenByDescendingInternal(fields); + public virtual SqlExpression ThenByDescending(Expression> fields) => ThenByDescendingInternal(fields); + public virtual SqlExpression ThenByDescending(Expression> fields) => ThenByDescendingInternal(fields); + public virtual SqlExpression ThenByDescending(Expression> fields) => ThenByDescendingInternal(fields); + + private SqlExpression ThenByDescendingInternal(Expression keySelector) + { + Reset(sep = string.Empty); + + var orderBySql = Visit(keySelector); + if (IsSqlClass(orderBySql)) + { + var fields = orderBySql.ToString(); + fields.ParseTokens() + .Each(x => orderByProperties.Add(x + " DESC")); + BuildOrderByClauseInternal(); + } + return this; + } + + private void BuildOrderByClauseInternal() + { + if (orderByProperties.Count > 0) + { + var sb = StringBuilderCache.Allocate(); + foreach (var prop in orderByProperties) + { + if (sb.Length > 0) + sb.Append(", "); + + sb.Append(prop); + } + orderBy = "ORDER BY " + StringBuilderCache.ReturnAndFree(sb); } - set + else { - modelDef = value; + orderBy = null; } } - protected internal bool UseFieldName + /// + /// Offset of the first row to return. The offset of the initial row is 0 + /// + public virtual SqlExpression Skip(int? skip = null) + { + Offset = skip; + return this; + } + + /// + /// Number of rows returned by a SELECT statement + /// + public virtual SqlExpression Take(int? take = null) + { + Rows = take; + return this; + } + + /// + /// Set the specified offset and rows for SQL Limit clause. + /// + /// + /// Offset of the first row to return. The offset of the initial row is 0 + /// + /// + /// Number of rows returned by a SELECT statement + /// + public virtual SqlExpression Limit(int skip, int rows) + { + Offset = skip; + Rows = rows; + return this; + } + + /// + /// Set the specified offset and rows for SQL Limit clause where they exist. + /// + /// + /// Offset of the first row to return. The offset of the initial row is 0 + /// + /// + /// Number of rows returned by a SELECT statement + /// + public virtual SqlExpression Limit(int? skip, int? rows) + { + Offset = skip; + Rows = rows; + return this; + } + + /// + /// Set the specified rows for Sql Limit clause. + /// + /// + /// Number of rows returned by a SELECT statement + /// + public virtual SqlExpression Limit(int rows) + { + Offset = null; + Rows = rows; + return this; + } + + /// + /// Clear Sql Limit clause + /// + public virtual SqlExpression Limit() + { + Offset = null; + Rows = null; + return this; + } + + /// + /// Clear Offset and Limit clauses. Alias for Limit() + /// + /// + public virtual SqlExpression ClearLimits() + { + return Limit(); + } + + /// + /// Fields to be updated. + /// + /// + /// List<string> containing Names of properties to be updated + /// + public virtual SqlExpression Update(List updateFields) + { + this.UpdateFields = updateFields; + return this; + } + + /// + /// Fields to be updated. + /// + /// + /// IEnumerable<string> containing Names of properties to be updated + /// + public virtual SqlExpression Update(IEnumerable updateFields) + { + this.UpdateFields = new List(updateFields); + return this; + } + + /// + /// Fields to be updated. + /// + /// + /// x=> x.SomeProperty1 or x=> new { x.SomeProperty1, x.SomeProperty2 } + /// + public virtual SqlExpression Update(Expression> fields) + { + Reset(sep = string.Empty, useFieldName = false); + this.UpdateFields = fields.GetFieldNames().ToList(); + return this; + } + + /// + /// Clear UpdateFields list ( all fields will be updated) + /// + public virtual SqlExpression Update() + { + this.UpdateFields = new List(); + return this; + } + + /// + /// Fields to be inserted. + /// + /// + /// x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2} + /// + /// + /// objectWithProperties + /// + public virtual SqlExpression Insert(Expression> fields) + { + Reset(sep = string.Empty, useFieldName = false); + var fieldList = Visit(fields); + InsertFields = fieldList.ToString().Split(',').Select(f => f.Trim()).ToList(); + return this; + } + + /// + /// fields to be inserted. + /// + /// + /// IList<string> containing Names of properties to be inserted + /// + public virtual SqlExpression Insert(List insertFields) + { + this.InsertFields = insertFields; + return this; + } + + /// + /// Clear InsertFields list ( all fields will be inserted) + /// + public virtual SqlExpression Insert() + { + this.InsertFields = new List(); + return this; + } + + public virtual SqlExpression WithSqlFilter(Func sqlFilter) + { + this.SqlFilter = sqlFilter; + return this; + } + + public string SqlTable(ModelDefinition modelDef) + { + return DialectProvider.GetQuotedTableName(modelDef); + } + + public string SqlColumn(string columnName) + { + return DialectProvider.GetQuotedColumnName(columnName); + } + + public virtual IDbDataParameter AddParam(object value) + { + var paramName = Params.Count.ToString(); + var paramValue = value; + + var parameter = CreateParam(paramName, paramValue); + DialectProvider.InitQueryParam(parameter); + Params.Add(parameter); + return parameter; + } + + public string ConvertToParam(object value) + { + var p = AddParam(value); + return p.ParameterName; + } + + public virtual void CopyParamsTo(IDbCommand dbCmd) + { + try + { + foreach (var sqlParam in Params) + { + dbCmd.Parameters.Add(sqlParam); + } + } + catch (Exception) + { + //SQL Server + PostgreSql doesn't allow re-using db params in multiple queries + foreach (var sqlParam in Params) + { + var p = dbCmd.CreateParameter(); + p.PopulateWith(sqlParam); + dbCmd.Parameters.Add(p); + } + } + } + + public virtual string ToDeleteRowStatement() + { + string sql; + var hasTableJoin = tableDefs.Count > 1; + if (hasTableJoin) + { + var clone = this.Clone(); + var pk = DialectProvider.GetQuotedColumnName(modelDef, modelDef.PrimaryKey); + clone.Select(pk); + var subSql = clone.ToSelectStatement(QueryType.Select); + sql = $"DELETE FROM {DialectProvider.GetQuotedTableName(modelDef)} WHERE {pk} IN ({subSql})"; + } + else + { + sql = $"DELETE FROM {DialectProvider.GetQuotedTableName(modelDef)} {WhereExpression}"; + } + + return SqlFilter != null + ? SqlFilter(sql) + : sql; + } + + public virtual void PrepareUpdateStatement(IDbCommand dbCmd, T item, bool excludeDefaults = false) + { + CopyParamsTo(dbCmd); + + var setFields = StringBuilderCache.Allocate(); + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (fieldDef.ShouldSkipUpdate()) + continue; + if (fieldDef.IsRowVersion) + continue; + if (UpdateFields.Count > 0 + && !UpdateFields.Contains(fieldDef.Name)) continue; // added + + var value = fieldDef.GetValue(item); + if (excludeDefaults + && (value == null || (!fieldDef.IsNullable && value.Equals(value.GetType().GetDefaultValue())))) + continue; + + if (setFields.Length > 0) + setFields.Append(", "); + + setFields + .Append(DialectProvider.GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(DialectProvider.GetUpdateParam(dbCmd, value, fieldDef)); + } + + if (setFields.Length == 0) + throw new ArgumentException($"No non-null or non-default values were provided for type: {typeof(T).Name}"); + + var sql = $"UPDATE {DialectProvider.GetQuotedTableName(modelDef)} " + + $"SET {StringBuilderCache.ReturnAndFree(setFields)} {WhereExpression}"; + + dbCmd.CommandText = SqlFilter != null + ? SqlFilter(sql) + : sql; + } + + public virtual void PrepareUpdateStatement(IDbCommand dbCmd, Dictionary updateFields) + { + CopyParamsTo(dbCmd); + + var setFields = StringBuilderCache.Allocate(); + + foreach (var entry in updateFields) + { + var fieldDef = ModelDef.AssertFieldDefinition(entry.Key); + if (fieldDef.ShouldSkipUpdate()) + continue; + if (fieldDef.IsRowVersion) + continue; + + if (UpdateFields.Count > 0 + && !UpdateFields.Contains(fieldDef.Name)) // added + continue; + + var value = entry.Value; + if (value == null && !fieldDef.IsNullable) + continue; + + if (setFields.Length > 0) + setFields.Append(", "); + + setFields + .Append(DialectProvider.GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(DialectProvider.GetUpdateParam(dbCmd, value, fieldDef)); + } + + if (setFields.Length == 0) + throw new ArgumentException($"No non-null or non-default values were provided for type: {typeof(T).Name}"); + + var sql = $"UPDATE {DialectProvider.GetQuotedTableName(modelDef)} " + + $"SET {StringBuilderCache.ReturnAndFree(setFields)} {WhereExpression}"; + + dbCmd.CommandText = SqlFilter != null + ? SqlFilter(sql) + : sql; + } + + public virtual string ToSelectStatement() => ToSelectStatement(QueryType.Select); + + public virtual string ToSelectStatement(QueryType forType) + { + SelectFilter?.Invoke(this); + OrmLiteConfig.SqlExpressionSelectFilter?.Invoke(GetUntyped()); + + var sql = DialectProvider + .ToSelectStatement(forType, modelDef, SelectExpression, BodyExpression, OrderByExpression, offset: Offset, rows: Rows, Tags); + + return SqlFilter != null + ? SqlFilter(sql) + : sql; + } + + /// + /// Merge params into an encapsulated SQL Statement with embedded param values + /// + public virtual string ToMergedParamsSelectStatement() + { + var sql = this.ToSelectStatement(QueryType.Select); + var mergedSql = DialectProvider.MergeParamsIntoSql(sql, Params); + return mergedSql; + } + + public virtual string ToCountStatement() + { + SelectFilter?.Invoke(this); + OrmLiteConfig.SqlExpressionSelectFilter?.Invoke(GetUntyped()); + + var sql = "SELECT COUNT(*)" + BodyExpression; + + return SqlFilter != null + ? SqlFilter(sql) + : sql; + } + + public string SelectExpression + { + get + { + if (string.IsNullOrEmpty(selectExpression)) + BuildSelectExpression(string.Empty, false); + return selectExpression; + } + set => selectExpression = value; + } + + public string FromExpression + { + get => string.IsNullOrEmpty(fromExpression) + ? " \nFROM " + DialectProvider.GetQuotedTableName(modelDef) + (TableAlias != null ? " " + DialectProvider.GetQuotedName(TableAlias) : "") + : fromExpression; + set => fromExpression = value; + } + + public string BodyExpression => FromExpression + + (string.IsNullOrEmpty(WhereExpression) ? "" : "\n" + WhereExpression) + + (string.IsNullOrEmpty(GroupByExpression) ? "" : "\n" + GroupByExpression) + + (string.IsNullOrEmpty(HavingExpression) ? "" : "\n" + HavingExpression); + + public string WhereExpression + { + get => whereExpression; + set => whereExpression = value; + } + + public string GroupByExpression + { + get => groupBy; + set => groupBy = value; + } + + public string HavingExpression + { + get => havingExpression; + set => havingExpression = value; + } + + + public string OrderByExpression + { + get => string.IsNullOrEmpty(orderBy) ? "" : "\n" + orderBy; + set => orderBy = value; + } + + public ModelDefinition ModelDef + { + get => modelDef; + protected set => modelDef = value; + } + + protected internal bool UseFieldName + { + get => useFieldName; + set => useFieldName = value; + } + + public virtual object Visit(Expression exp) + { + visitedExpressionIsTableColumn = false; + + if (exp == null) + return string.Empty; + + switch (exp.NodeType) + { + case ExpressionType.Lambda: + return VisitLambda(exp as LambdaExpression); + case ExpressionType.MemberAccess: + return VisitMemberAccess(exp as MemberExpression); + case ExpressionType.Constant: + return VisitConstant(exp as ConstantExpression); + case ExpressionType.Add: + case ExpressionType.AddChecked: + case ExpressionType.Subtract: + case ExpressionType.SubtractChecked: + case ExpressionType.Multiply: + case ExpressionType.MultiplyChecked: + case ExpressionType.Divide: + case ExpressionType.Modulo: + case ExpressionType.AndAlso: + case ExpressionType.OrElse: + case ExpressionType.LessThan: + case ExpressionType.LessThanOrEqual: + case ExpressionType.GreaterThan: + case ExpressionType.GreaterThanOrEqual: + case ExpressionType.Equal: + case ExpressionType.NotEqual: + case ExpressionType.Coalesce: + case ExpressionType.ArrayIndex: + case ExpressionType.And: + case ExpressionType.Or: + case ExpressionType.ExclusiveOr: + case ExpressionType.RightShift: + case ExpressionType.LeftShift: + //return "(" + VisitBinary(exp as BinaryExpression) + ")"; + return VisitBinary(exp as BinaryExpression); + case ExpressionType.Negate: + case ExpressionType.NegateChecked: + case ExpressionType.Not: + case ExpressionType.Convert: + case ExpressionType.ConvertChecked: + case ExpressionType.ArrayLength: + case ExpressionType.Quote: + case ExpressionType.TypeAs: + return VisitUnary(exp as UnaryExpression); + case ExpressionType.Parameter: + return VisitParameter(exp as ParameterExpression); + case ExpressionType.Call: + return VisitMethodCall(exp as MethodCallExpression); + case ExpressionType.New: + return VisitNew(exp as NewExpression); + case ExpressionType.NewArrayInit: + case ExpressionType.NewArrayBounds: + return VisitNewArray(exp as NewArrayExpression); + case ExpressionType.MemberInit: + return VisitMemberInit(exp as MemberInitExpression); + case ExpressionType.Index: + return VisitIndexExpression(exp as IndexExpression); + case ExpressionType.Conditional: + return VisitConditional(exp as ConditionalExpression); + default: + return exp.ToString(); + } + } + + protected virtual object VisitJoin(Expression exp) + { + skipParameterizationForThisExpression = true; + var visitedExpression = Visit(exp); + skipParameterizationForThisExpression = false; + return visitedExpression; + } + + protected virtual object VisitLambda(LambdaExpression lambda) + { + if (originalLambda == null) + originalLambda = lambda; + + if (lambda.Body.NodeType == ExpressionType.MemberAccess && sep == " ") + { + MemberExpression m = lambda.Body as MemberExpression; + + if (m.Expression != null) + { + var r = VisitMemberAccess(m); + if (!(r is PartialSqlString)) + return r; + + if (m.Expression.Type.IsNullableType()) + return r.ToString(); + + return $"{r}={GetQuotedTrueValue()}"; + } + + } + else if (lambda.Body.NodeType == ExpressionType.Conditional && sep == " ") + { + var c = lambda.Body as ConditionalExpression; + + var r = VisitConditional(c); + if (r is not PartialSqlString) + return r; + + return $"{r}={GetQuotedTrueValue()}"; + } + + return Visit(lambda.Body); + } + + public virtual object GetValue(object value, Type type) + { + if (skipParameterizationForThisExpression) + return DialectProvider.GetQuotedValue(value, type); + + var paramValue = DialectProvider.GetParamValue(value, type); + return paramValue ?? "null"; + } + + protected virtual object VisitBinary(BinaryExpression b) + { + object originalLeft = null, originalRight = null, left, right; + var operand = BindOperant(b.NodeType); //sep= " " ?? + if (operand is "AND" or "OR") + { + if (IsBooleanComparison(b.Left)) + { + left = VisitMemberAccess((MemberExpression)b.Left); + if (left is PartialSqlString) + left = new PartialSqlString($"{left}={GetQuotedTrueValue()}"); + } + else if (b.Left is ConditionalExpression expr) + { + left = VisitConditional(expr); + if (left is PartialSqlString) + left = new PartialSqlString($"{left}={GetQuotedTrueValue()}"); + } + else left = Visit(b.Left); + + if (IsBooleanComparison(b.Right)) + { + right = VisitMemberAccess((MemberExpression)b.Right); + if (right is PartialSqlString) + right = new PartialSqlString($"{right}={GetQuotedTrueValue()}"); + } + else if (b.Right is ConditionalExpression expr) + { + right = VisitConditional(expr); + if (right is PartialSqlString) + right = new PartialSqlString($"{right}={GetQuotedTrueValue()}"); + } + else right = Visit(b.Right); + + if (left is not PartialSqlString && right is not PartialSqlString) + { + var result = CachedExpressionCompiler.Evaluate(PreEvaluateBinary(b, left, right)); + return result; + } + + if (left is not PartialSqlString) + left = ((bool)left) ? GetTrueExpression() : GetFalseExpression(); + if (right is not PartialSqlString) + right = ((bool)right) ? GetTrueExpression() : GetFalseExpression(); + } + else if ((operand is "=" or "<>") && b.Left is MethodCallExpression methodExpr && methodExpr.Method.Name == "CompareString") + { + //Handle VB.NET converting (x => x.Name == "Foo") into (x => CompareString(x.Name, "Foo", False) + var args = this.VisitExpressionList(methodExpr.Arguments); + right = GetValue(args[1], typeof(string)); + ConvertToPlaceholderAndParameter(ref right); + return new PartialSqlString($"({args[0]} {operand} {right})"); + } + else + { + originalLeft = left = Visit(b.Left); + originalRight = right = Visit(b.Right); + + // Handle "expr = true/false", including with the constant on the left + if (operand is "=" or "<>") + { + if (left is bool) + { + Swap(ref left, ref right); // Should be safe to swap for equality/inequality checks + } + + if (right is bool && + (left == null || left.ToString().Equals("null", StringComparison.OrdinalIgnoreCase))) + { + if (operand == "=") + return false; // "null == true/false" becomes "false" + if (operand == "<>") + return true; // "null != true/false" becomes "true" + } + + // Don't change anything when "expr" is a column name or ConditionalExpression - then we really want "ColName = 1" or (Case When 1=0 Then 1 Else 0 End = 1) + if (right is bool rightBool && !IsFieldName(left) && b.Left is not ConditionalExpression) + { + if (operand == "=") + return rightBool ? left : GetNotValue(left); // "expr == true" becomes "expr", "expr == false" becomes "not (expr)" + if (operand == "<>") + return rightBool ? GetNotValue(left) : left; // "expr != true" becomes "not (expr)", "expr != false" becomes "expr" + } + } + + EnumMemberAccess leftEnum = left as EnumMemberAccess; + + //The real type should be read when a non-direct member is accessed. For example Sql.TableAlias(x.State, "p"),alias conversion should be performed when "x.State" is an enum + if (leftEnum == null && left is PartialSqlString pss && pss.EnumMember != null) leftEnum = pss.EnumMember; + + var rightEnum = right as EnumMemberAccess; + + var rightNeedsCoercing = leftEnum != null && rightEnum == null; + var leftNeedsCoercing = rightEnum != null && leftEnum == null; + + if (rightNeedsCoercing) + { + var rightPartialSql = right as PartialSqlString; + if (rightPartialSql == null) + { + right = GetValue(right, leftEnum.EnumType); + } + } + else if (leftNeedsCoercing) + { + if (left is not PartialSqlString) + { + left = DialectProvider.GetQuotedValue(left, rightEnum.EnumType); + } + } + else if (left is not PartialSqlString && right is not PartialSqlString) + { + var evaluatedValue = CachedExpressionCompiler.Evaluate(PreEvaluateBinary(b, left, right)); + var result = VisitConstant(Expression.Constant(evaluatedValue)); + return result; + } + else if (left is not PartialSqlString) + { + left = DialectProvider.GetQuotedValue(left, left?.GetType()); + } + else if (right is not PartialSqlString) + { + right = GetValue(right, right?.GetType()); + } + } + + if (left.ToString().Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Swap(ref left, ref right); // "null is x" will not work, so swap the operands + } + + var separator = sep; + if (right.ToString().Equals("null", StringComparison.OrdinalIgnoreCase)) + { + if (operand == "=") + operand = "is"; + else if (operand == "<>") + operand = "is not"; + + separator = " "; + } + + if (operand == "+" && b.Left.Type == typeof(string) && b.Right.Type == typeof(string)) + return BuildConcatExpression(new List { left, right }); + + VisitFilter(operand, originalLeft, originalRight, ref left, ref right); + + switch (operand) + { + case "MOD": + case "COALESCE": + return new PartialSqlString($"{operand}({left},{right})"); + default: + return new PartialSqlString("(" + left + separator + operand + separator + right + ")"); + } + } + + private BinaryExpression PreEvaluateBinary(BinaryExpression b, object left, object right) + { + var visitedBinaryExp = b; + + if (IsParameterAccess(b.Left) || IsParameterAccess(b.Right)) + { + var eLeft = !IsParameterAccess(b.Left) ? b.Left : Expression.Constant(left, b.Left.Type); + var eRight = !IsParameterAccess(b.Right) ? b.Right : Expression.Constant(right, b.Right.Type); + if (b.NodeType == ExpressionType.Coalesce) + visitedBinaryExp = Expression.Coalesce(eLeft, eRight, b.Conversion); + else + visitedBinaryExp = Expression.MakeBinary(b.NodeType, eLeft, eRight, b.IsLiftedToNull, b.Method); + } + + return visitedBinaryExp; + } + + /// + /// Determines whether the expression is the parameter inside MemberExpression which should be compared with TrueExpression. + /// + /// Returns true if the specified expression is the parameter inside MemberExpression which should be compared with TrueExpression; + /// otherwise, false. + protected virtual bool IsBooleanComparison(Expression e) + { + if (e is not MemberExpression m) + return false; + + if (m.Member.DeclaringType.IsNullableType() && + m.Member.Name == "HasValue") //nameof(Nullable.HasValue) + return false; + + return IsParameterAccess(m); + } + + /// + /// Determines whether the expression is the parameter. + /// + /// Returns true if the specified expression is parameter; + /// otherwise, false. + protected virtual bool IsParameterAccess(Expression e) + { + return CheckExpressionForTypes(e, new[] { ExpressionType.Parameter }); + } + + /// + /// Determines whether the expression is a Parameter or Convert Expression. + /// + /// Returns true if the specified expression is parameter or convert; + /// otherwise, false. + protected virtual bool IsParameterOrConvertAccess(Expression e) + { + return CheckExpressionForTypes(e, new[] { ExpressionType.Parameter, ExpressionType.Convert }); + } + + /// + /// Check whether the expression is a constant expression to determine + /// whether we should use the expression value instead of Column Name + /// + protected virtual bool IsConstantExpression(Expression e) + { + return CheckExpressionForTypes(e, new[] { ExpressionType.Constant }); + } + + protected bool CheckExpressionForTypes(Expression e, ExpressionType[] types) + { + while (e != null) + { + if (types.Contains(e.NodeType)) + { + var subUnaryExpr = e as UnaryExpression; + var isSubExprAccess = subUnaryExpr?.Operand is IndexExpression; + if (!isSubExprAccess) + return true; + } + + if (e is BinaryExpression binaryExpr) + { + if (CheckExpressionForTypes(binaryExpr.Left, types)) + return true; + + if (CheckExpressionForTypes(binaryExpr.Right, types)) + return true; + } + + if (e is MethodCallExpression methodCallExpr) + { + for (var i = 0; i < methodCallExpr.Arguments.Count; i++) + { + if (CheckExpressionForTypes(methodCallExpr.Arguments[i], types)) + return true; + } + + if (CheckExpressionForTypes(methodCallExpr.Object, types)) + return true; + } + + if (e is UnaryExpression unaryExpr) + { + if (CheckExpressionForTypes(unaryExpr.Operand, types)) + return true; + } + + if (e is ConditionalExpression condExpr) + { + if (CheckExpressionForTypes(condExpr.Test, types)) + return true; + + if (CheckExpressionForTypes(condExpr.IfTrue, types)) + return true; + + if (CheckExpressionForTypes(condExpr.IfFalse, types)) + return true; + } + + var memberExpr = e as MemberExpression; + e = memberExpr?.Expression; + } + + return false; + } + + private static void Swap(ref object left, ref object right) + { + var temp = right; + right = left; + left = temp; + } + + protected virtual void VisitFilter(string operand, object originalLeft, object originalRight, ref object left, ref object right) + { + if (skipParameterizationForThisExpression || visitedExpressionIsTableColumn) + return; + + if (originalLeft is EnumMemberAccess && originalRight is EnumMemberAccess) + return; + + if (operand == "AND" || operand == "OR" || operand == "is" || operand == "is not") + return; + + if (!(right is PartialSqlString)) + { + ConvertToPlaceholderAndParameter(ref right); + } + } + + protected virtual void ConvertToPlaceholderAndParameter(ref object right) + { + var parameter = AddParam(right); + + right = parameter.ParameterName; + } + + protected virtual object VisitMemberAccess(MemberExpression m) + { + if (m.Expression != null) + { + if (m.Member.DeclaringType.IsNullableType()) + { + if (m.Member.Name == nameof(Nullable.Value)) + return Visit(m.Expression); + if (m.Member.Name == nameof(Nullable.HasValue)) + { + var doesNotEqualNull = Expression.MakeBinary(ExpressionType.NotEqual, m.Expression, Expression.Constant(null)); + return Visit(doesNotEqualNull); // Nullable.HasValue is equivalent to "!= null" + } + + throw new ArgumentException($"Expression '{m}' accesses unsupported property '{m.Member}' of Nullable"); + } + + if (m.Member.DeclaringType == typeof(string) && + m.Member.Name == nameof(string.Length)) + { + return VisitLengthStringProperty(m); + } + + if (IsParameterOrConvertAccess(m)) + { + // We don't want to use the Column Name for constant expressions unless we're in a Sql. method call + if (inSqlMethodCall || !IsConstantExpression(m)) + return GetMemberExpression(m); + } + } + + return CachedExpressionCompiler.Evaluate(m); + } + + protected virtual object GetMemberExpression(MemberExpression m) + { + var propertyInfo = m.Member as PropertyInfo; + + var modelType = m.Expression.Type; + if (m.Expression.NodeType == ExpressionType.Convert) + { + if (m.Expression is UnaryExpression unaryExpr) + { + modelType = unaryExpr.Operand.Type; + } + } + + OnVisitMemberType(modelType); + + var tableDef = modelType.GetModelDefinition(); + + var tableAlias = GetTableAlias(m); + var columnName = tableAlias == null + ? GetQuotedColumnName(tableDef, m.Member.Name) + : GetQuotedColumnName(tableDef, tableAlias, m.Member.Name); + + if (propertyInfo != null && propertyInfo.PropertyType.IsEnum) + return new EnumMemberAccess(columnName, propertyInfo.PropertyType); + + return new PartialSqlString(columnName); + } + + protected virtual string GetTableAlias(MemberExpression m) { - get - { - return useFieldName; - } - set + if (originalLambda == null) + return null; + + if (m.Expression is ParameterExpression pe) { - useFieldName = value; + var tableParamName = originalLambda.Parameters.Count > 0 && originalLambda.Parameters[0].Type == ModelDef.ModelType + ? originalLambda.Parameters[0].Name + : null; + + if (pe.Type == ModelDef.ModelType && pe.Name == tableParamName) + return TableAlias; + + var joinType = joinAlias?.ModelDef?.ModelType; + var joinParamName = originalLambda.Parameters.Count > 1 && originalLambda.Parameters[1].Type == joinType + ? originalLambda.Parameters[1].Name + : null; + + if (pe.Type == joinType && pe.Name == joinParamName) + return joinAlias.Alias; } + + return null; } - protected internal virtual object Visit(Expression exp) + protected virtual void OnVisitMemberType(Type modelType) { + var tableDef = modelType.GetModelDefinition(); + if (tableDef != null) + visitedExpressionIsTableColumn = true; + } - if (exp == null) return string.Empty; - switch (exp.NodeType) - { - case ExpressionType.Lambda: - return VisitLambda(exp as LambdaExpression); - case ExpressionType.MemberAccess: - return VisitMemberAccess(exp as MemberExpression); - case ExpressionType.Constant: - return VisitConstant(exp as ConstantExpression); - case ExpressionType.Add: - case ExpressionType.AddChecked: - case ExpressionType.Subtract: - case ExpressionType.SubtractChecked: - case ExpressionType.Multiply: - case ExpressionType.MultiplyChecked: - case ExpressionType.Divide: - case ExpressionType.Modulo: - case ExpressionType.And: - case ExpressionType.AndAlso: - case ExpressionType.Or: - case ExpressionType.OrElse: - case ExpressionType.LessThan: - case ExpressionType.LessThanOrEqual: - case ExpressionType.GreaterThan: - case ExpressionType.GreaterThanOrEqual: - case ExpressionType.Equal: - case ExpressionType.NotEqual: - case ExpressionType.Coalesce: - case ExpressionType.ArrayIndex: - case ExpressionType.RightShift: - case ExpressionType.LeftShift: - case ExpressionType.ExclusiveOr: - //return "(" + VisitBinary(exp as BinaryExpression) + ")"; - return VisitBinary(exp as BinaryExpression); - case ExpressionType.Negate: - case ExpressionType.NegateChecked: - case ExpressionType.Not: - case ExpressionType.Convert: - case ExpressionType.ConvertChecked: - case ExpressionType.ArrayLength: - case ExpressionType.Quote: - case ExpressionType.TypeAs: - return VisitUnary(exp as UnaryExpression); - case ExpressionType.Parameter: - return VisitParameter(exp as ParameterExpression); - case ExpressionType.Call: - return VisitMethodCall(exp as MethodCallExpression); - case ExpressionType.New: - return VisitNew(exp as NewExpression); - case ExpressionType.NewArrayInit: - case ExpressionType.NewArrayBounds: - return VisitNewArray(exp as NewArrayExpression); - case ExpressionType.MemberInit: - return VisitMemberInit(exp as MemberInitExpression); - default: - return exp.ToString(); - } + protected virtual object VisitMemberInit(MemberInitExpression exp) + { + return CachedExpressionCompiler.Evaluate(exp); } - protected virtual object VisitLambda(LambdaExpression lambda) + protected virtual object VisitNew(NewExpression nex) { - if (lambda.Body.NodeType == ExpressionType.MemberAccess && sep == " ") + var isAnonType = nex.Type.Name.StartsWith("<>"); + if (isAnonType) { - MemberExpression m = lambda.Body as MemberExpression; - - if (m.Expression != null) + var exprs = VisitExpressionList(nex.Arguments); + if (isSelectExpression) { - string r = VisitMemberAccess(m).ToString(); - return string.Format("{0}={1}", r, GetQuotedTrueValue()); + for (var i = 0; i < exprs.Count; ++i) + { + exprs[i] = SetAnonTypePropertyNamesForSelectExpression(exprs[i], nex.Arguments[i], nex.Members[i]); + } } + return new SelectList(exprs); } - return Visit(lambda.Body); + + return CachedExpressionCompiler.Evaluate(nex); } - protected virtual object VisitBinary(BinaryExpression b) + bool IsLambdaArg(Expression expr) { - object left, right; - var operand = BindOperant(b.NodeType); //sep= " " ?? - if (operand == "AND" || operand == "OR") - { - var m = b.Left as MemberExpression; - if (m != null && m.Expression != null - && m.Expression.NodeType == ExpressionType.Parameter) - left = new PartialSqlString(string.Format("{0}={1}", VisitMemberAccess(m), GetQuotedTrueValue())); - else - left = Visit(b.Left); - - m = b.Right as MemberExpression; - if (m != null && m.Expression != null - && m.Expression.NodeType == ExpressionType.Parameter) - right = new PartialSqlString(string.Format("{0}={1}", VisitMemberAccess(m), GetQuotedTrueValue())); - else - right = Visit(b.Right); + if (expr is ParameterExpression pe) + return IsLambdaArg(pe.Name); + if (expr is UnaryExpression ue && ue.Operand is ParameterExpression uepe) + return IsLambdaArg(uepe.Name); + return false; + } - if (left as PartialSqlString == null && right as PartialSqlString == null) + bool IsLambdaArg(string name) + { + var args = originalLambda?.Parameters; + if (args != null) + { + foreach (var x in args) { - var result = Expression.Lambda(b).Compile().DynamicInvoke(); - return new PartialSqlString(DialectProvider.GetQuotedValue(result, result.GetType())); + if (x.Name == name) + return true; } - - if (left as PartialSqlString == null) - left = ((bool)left) ? GetTrueExpression() : GetFalseExpression(); - if (right as PartialSqlString == null) - right = ((bool)right) ? GetTrueExpression() : GetFalseExpression(); } - else + return false; + } + + private object SetAnonTypePropertyNamesForSelectExpression(object expr, Expression arg, MemberInfo member) + { + // When selecting a column use the anon type property name, rather than the table property name, as the returned column name + if (arg is MemberExpression propExpr && IsLambdaArg(propExpr.Expression)) { - left = Visit(b.Left); - right = Visit(b.Right); + if (UseSelectPropertiesAsAliases || // Use anon property alias when explicitly requested + propExpr.Member.Name != member.Name || // or when names don't match + propExpr.Expression.Type != ModelDef.ModelType || // or when selecting a field from a different table + member.Name != ModelDef.FieldDefinitions.First(x => x.Name == member.Name).FieldName) //or when name and alias don't match + return new SelectItemExpression(DialectProvider, expr.ToString(), member.Name); - var leftEnum = left as EnumMemberAccess; - var rightEnum = right as EnumMemberAccess; - var rightNeedsCoercing = leftEnum != null && rightEnum == null; - var leftNeedsCoercing = rightEnum != null && leftEnum == null; + return expr; + } - if (rightNeedsCoercing) - { - var rightPartialSql = right as PartialSqlString; - if (rightPartialSql == null) - { - right = DialectProvider.GetQuotedValue(right, leftEnum.EnumType); - } - } - else if (leftNeedsCoercing) + // When selecting an entire table use the anon type property name as a prefix for the returned column name + // to allow the caller to distinguish properties with the same names from different tables + + var selectList = arg is ParameterExpression paramExpr && paramExpr.Name != member.Name + ? expr as SelectList + : null; + if (selectList != null) + { + foreach (var item in selectList.Items) { - var leftPartialSql = left as PartialSqlString; - if (leftPartialSql == null) + if (item is SelectItem selectItem) { - left = DialectProvider.GetQuotedValue(left, rightEnum.EnumType); + if (!string.IsNullOrEmpty(selectItem.Alias)) + { + selectItem.Alias = member.Name + selectItem.Alias; + } + else + { + if (item is SelectItemColumn columnItem) + { + columnItem.Alias = member.Name + columnItem.ColumnName; + } + } } } - else if (left as PartialSqlString == null && right as PartialSqlString == null) + } + + var methodCallExpr = arg as MethodCallExpression; + var mi = methodCallExpr?.Method; + var declareType = mi?.DeclaringType; + if (declareType != null && declareType.Name == nameof(Sql)) + { + if (mi.Name == nameof(Sql.TableAlias) || mi.Name == nameof(Sql.JoinAlias)) { - var result = Expression.Lambda(b).Compile().DynamicInvoke(); - return result; + if (expr is PartialSqlString ps && ps.Text.IndexOf(',') >= 0) + return ps; // new { buyer = Sql.TableAlias(b, "buyer") + return new PartialSqlString(expr + " AS " + member.Name); // new { BuyerName = Sql.TableAlias(b.Name, "buyer") } } - else if (left as PartialSqlString == null) - left = DialectProvider.GetQuotedValue(left, left != null ? left.GetType() : null); - else if (right as PartialSqlString == null) - right = DialectProvider.GetQuotedValue(right, right != null ? right.GetType() : null); + if (mi.Name != nameof(Sql.Desc) && mi.Name != nameof(Sql.Asc) && mi.Name != nameof(Sql.As) && mi.Name != nameof(Sql.AllFields)) + return new PartialSqlString(expr + " AS " + member.Name); // new { Alias = Sql.Count("*") } } - if (operand == "=" && right.ToString().Equals("null", StringComparison.OrdinalIgnoreCase)) operand = "is"; - else if (operand == "<>" && right.ToString().Equals("null", StringComparison.OrdinalIgnoreCase)) operand = "is not"; + if (expr is string s && s == Sql.EOT) // new { t1 = Sql.EOT, t2 = "0 EOT" } + return new PartialSqlString(s); - switch (operand) + if (arg is ConditionalExpression ce || // new { Alias = x.Value > 1 ? 1 : x.Value } + arg is BinaryExpression be || // new { Alias = x.First + " " + x.Last } + arg is MemberExpression me || // new { Alias = DateTime.UtcNow } + arg is ConstantExpression ct) // new { Alias = 1 } { - case "MOD": - case "COALESCE": - return new PartialSqlString(string.Format("{0}({1},{2})", operand, left, right)); - default: - return new PartialSqlString("(" + left + sep + operand + sep + right + ")"); + IOrmLiteConverter converter; + var strExpr = !(expr is PartialSqlString) && (converter = DialectProvider.GetConverterBestMatch(expr.GetType())) != null + ? converter.ToQuotedString(expr.GetType(), expr) + : expr.ToString(); + + return new PartialSqlString(OrmLiteUtils.UnquotedColumnName(strExpr) != member.Name + ? strExpr + " AS " + member.Name + : strExpr); } + + var usePropertyAlias = UseSelectPropertiesAsAliases || + (expr is PartialSqlString p && Equals(p, PartialSqlString.Null)); // new { Alias = (DateTime?)null } + return usePropertyAlias + ? new SelectItemExpression(DialectProvider, expr.ToString(), member.Name) + : expr; } - protected virtual object VisitMemberAccess(MemberExpression m) + private static void StripAliases(SelectList selectList) { - if (m.Expression != null - && (m.Expression.NodeType == ExpressionType.Parameter || m.Expression.NodeType == ExpressionType.Convert)) - { - var propertyInfo = (PropertyInfo)m.Member; + if (selectList == null) + return; - var modelType = m.Expression.Type; - if (m.Expression.NodeType == ExpressionType.Convert) + foreach (var item in selectList.Items) + { + if (item is SelectItem selectItem) + { + selectItem.Alias = null; + } + else if (item is PartialSqlString p) { - var unaryExpr = m.Expression as UnaryExpression; - if (unaryExpr != null) + if (p.Text.IndexOf(' ') >= 0) { - modelType = unaryExpr.Operand.Type; + var right = p.Text.RightPart(' '); + if (right.StartsWithIgnoreCase("AS ")) + { + p.Text = p.Text.LeftPart(' '); + } } } - - var tableDef = modelType.GetModelDefinition(); - if (propertyInfo.PropertyType.IsEnum) - return new EnumMemberAccess( - GetQuotedColumnName(tableDef, m.Member.Name), propertyInfo.PropertyType); - - return new PartialSqlString(GetQuotedColumnName(tableDef, m.Member.Name)); } - - var member = Expression.Convert(m, typeof(object)); - var lambda = Expression.Lambda>(member); - var getter = lambda.Compile(); - return getter(); } - protected virtual object VisitMemberInit(MemberInitExpression exp) + private class SelectList { - return Expression.Lambda(exp).Compile().DynamicInvoke(); - } + public readonly IEnumerable Items; - protected virtual object VisitNew(NewExpression nex) - { - // TODO : check ! - var member = Expression.Convert(nex, typeof(object)); - var lambda = Expression.Lambda>(member); - try + public SelectList(IEnumerable items) { - var getter = lambda.Compile(); - return getter(); + this.Items = items; } - catch (InvalidOperationException) - { // FieldName ? - var exprs = VisitExpressionList(nex.Arguments); - var r = new StringBuilder(); - foreach (object e in exprs) - { - if (r.Length > 0) - r.Append(","); - r.Append(e); - } - return r.ToString(); + public override string ToString() + { + return Items.ToSelectString(); } - } protected virtual object VisitParameter(ParameterExpression p) { + var paramModelDef = p.Type.GetModelDefinition(); + if (paramModelDef != null) + { + var tablePrefix = paramModelDef == ModelDef && TableAlias != null + ? TableAlias + : paramModelDef.ModelName; + return new SelectList(DialectProvider.GetColumnNames(paramModelDef, tablePrefix)); + } + return p.Name; } - public Dictionary Params = new Dictionary(); - protected virtual object VisitConstant(ConstantExpression c) { if (c.Value == null) - return new PartialSqlString("null"); + return PartialSqlString.Null; return c.Value; } @@ -1083,40 +2298,170 @@ protected virtual object VisitUnary(UnaryExpression u) { case ExpressionType.Not: var o = Visit(u.Operand); - - if (o as PartialSqlString == null) - return !((bool)o); - - if (IsFieldName(o)) - o = o + "=" + GetQuotedTrueValue(); - - return new PartialSqlString("NOT (" + o + ")"); + return GetNotValue(o); case ExpressionType.Convert: if (u.Method != null) - return Expression.Lambda(u).Compile().DynamicInvoke(); + { + var e = u.Operand; + if (IsParameterAccess(e)) + return Visit(e); + + return CachedExpressionCompiler.Evaluate(u); + } break; } - return Visit(u.Operand); + } + + protected virtual object VisitIndexExpression(IndexExpression e) + { + var arg = e.Arguments[0]; + var oIndex = arg is ConstantExpression constant + ? constant.Value + : CachedExpressionCompiler.Evaluate(arg); + + var index = (int)Convert.ChangeType(oIndex, typeof(int)); + var oCollection = CachedExpressionCompiler.Evaluate(e.Object); + + if (oCollection is List list) + return list[index]; + + throw new NotImplementedException("Unknown Expression: " + e); + } + + protected virtual object VisitConditional(ConditionalExpression e) + { + var test = IsBooleanComparison(e.Test) + ? new PartialSqlString($"{VisitMemberAccess((MemberExpression)e.Test)}={GetQuotedTrueValue()}") + : Visit(e.Test); + + if (test is bool) + { + if ((bool)test) + { + var ifTrue = Visit(e.IfTrue); + if (!IsSqlClass(ifTrue)) + { + if (sep == " ") + ifTrue = new PartialSqlString(ConvertToParam(ifTrue)); + } + else if (e.IfTrue.Type == typeof(bool)) + { + var isBooleanComparison = IsBooleanComparison(e.IfTrue); + if (!isBooleanComparison) + { + if (sep == " ") + ifTrue = ifTrue.ToString(); + else + ifTrue = new PartialSqlString($"(CASE WHEN {ifTrue} THEN {1} ELSE {0} END)"); + } + } + + return ifTrue; + } + + var ifFalse = Visit(e.IfFalse); + if (!IsSqlClass(ifFalse)) + { + if (sep == " ") + ifFalse = new PartialSqlString(ConvertToParam(ifFalse)); + } + else if (e.IfFalse.Type == typeof(bool)) + { + var isBooleanComparison = IsBooleanComparison(e.IfFalse); + if (!isBooleanComparison) + { + if (sep == " ") + ifFalse = ifFalse.ToString(); + else + ifFalse = new PartialSqlString($"(CASE WHEN {ifFalse} THEN {1} ELSE {0} END)"); + } + } + + return ifFalse; + } + else + { + var ifTrue = Visit(e.IfTrue); + if (!IsSqlClass(ifTrue)) + ifTrue = ConvertToParam(ifTrue); + else if (e.IfTrue.Type == typeof(bool)) + { + var isBooleanComparison = IsBooleanComparison(e.IfTrue); + if (!isBooleanComparison) + { + ifTrue = $"(CASE WHEN {ifTrue} THEN {GetQuotedTrueValue()} ELSE {GetQuotedFalseValue()} END)"; + } + } + + var ifFalse = Visit(e.IfFalse); + if (!IsSqlClass(ifFalse)) + ifFalse = ConvertToParam(ifFalse); + else if (e.IfFalse.Type == typeof(bool)) + { + var isBooleanComparison = IsBooleanComparison(e.IfFalse); + if (!isBooleanComparison) + { + ifFalse = $"(CASE WHEN {ifFalse} THEN {GetQuotedTrueValue()} ELSE {GetQuotedFalseValue()} END)"; + } + } + + return new PartialSqlString($"(CASE WHEN {test} THEN {ifTrue} ELSE {ifFalse} END)"); + } + } + + private object GetNotValue(object o) + { + if (!(o is PartialSqlString)) + return !(bool)o; + + if (IsFieldName(o)) + return new PartialSqlString(o + "=" + GetQuotedFalseValue()); + return new PartialSqlString("NOT (" + o + ")"); } - private bool IsColumnAccess(MethodCallExpression m) + protected virtual bool IsColumnAccess(MethodCallExpression m) { - if (m.Object != null && m.Object as MethodCallExpression != null) - return IsColumnAccess(m.Object as MethodCallExpression); - + if (m.Object == null) + { + foreach (var arg in m.Arguments) + { + if (!(arg is LambdaExpression) && + IsParameterAccess(arg)) + { + return true; + } + } + + return false; + } + + if (m.Object is MethodCallExpression methCallExp) + return IsColumnAccess(methCallExp); + + if (m.Object is ConditionalExpression condExp) + return IsParameterAccess(condExp); + + if (m.Object is UnaryExpression unaryExp) + return IsParameterAccess(unaryExp); + var exp = m.Object as MemberExpression; - return exp != null - && exp.Expression != null - && IsJoinedTable(exp.Expression.Type) - && exp.Expression.NodeType == ExpressionType.Parameter; + return IsParameterAccess(exp) + && IsJoinedTable(exp.Expression.Type); } + protected virtual object VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(Sql)) - return VisitSqlMethodCall(m); + { + var hold = inSqlMethodCall; + inSqlMethodCall = true; + var ret = VisitSqlMethodCall(m); + inSqlMethodCall = hold; + return ret; + } if (IsStaticArrayMethod(m)) return VisitStaticArrayMethodCall(m); @@ -1124,54 +2469,104 @@ protected virtual object VisitMethodCall(MethodCallExpression m) if (IsEnumerableMethod(m)) return VisitEnumerableMethodCall(m); + if (IsStaticStringMethod(m)) + return VisitStaticStringMethodCall(m); + if (IsColumnAccess(m)) return VisitColumnAccessMethod(m); - return Expression.Lambda(m).Compile().DynamicInvoke(); + return EvaluateExpression(m); + } + + private object EvaluateExpression(Expression m) + { + try + { + return CachedExpressionCompiler.Evaluate(m); + } + catch (InvalidOperationException) + { + if (originalLambda == null) + throw; + + // Can't use expression.Compile() if lambda expression contains captured parameters. + // Fallback invokes expression with default parameters from original lambda expression + + var lambda = Expression.Lambda(m, originalLambda.Parameters).Compile(); + + var exprParams = new object[originalLambda.Parameters.Count]; + for (var i = 0; i < originalLambda.Parameters.Count; i++) + { + var p = originalLambda.Parameters[i]; + exprParams[i] = p.Type.CreateInstance(); + } + + var ret = lambda.DynamicInvoke(exprParams); + return ret; + } } - protected virtual List VisitExpressionList(ReadOnlyCollection original) + protected virtual List VisitExpressionList(ReadOnlyCollection original) { - List list = new List(); + var list = new List(); for (int i = 0, n = original.Count; i < n; i++) { - if (original[i].NodeType == ExpressionType.NewArrayInit || - original[i].NodeType == ExpressionType.NewArrayBounds) + var e = original[i]; + if (e.NodeType == ExpressionType.NewArrayInit || + e.NodeType == ExpressionType.NewArrayBounds) { + list.AddRange(VisitNewArrayFromExpressionList(e as NewArrayExpression)); + } + else + { + list.Add(Visit(e)); + } + } + return list; + } - list.AddRange(VisitNewArrayFromExpressionList(original[i] as NewArrayExpression)); + protected virtual List VisitInSqlExpressionList(ReadOnlyCollection original) + { + var list = new List(); + for (int i = 0, n = original.Count; i < n; i++) + { + var e = original[i]; + if (e.NodeType == ExpressionType.NewArrayInit || + e.NodeType == ExpressionType.NewArrayBounds) + { + list.AddRange(VisitNewArrayFromExpressionList(e as NewArrayExpression)); + } + else if (e.NodeType == ExpressionType.MemberAccess) + { + list.Add(VisitMemberAccess(e as MemberExpression)); + } + else + { + list.Add(Visit(e)); } - else - list.Add(Visit(original[i])); - } return list; } protected virtual object VisitNewArray(NewArrayExpression na) { - - List exprs = VisitExpressionList(na.Expressions); - StringBuilder r = new StringBuilder(); - foreach (Object e in exprs) + var exprs = VisitExpressionList(na.Expressions); + var sb = StringBuilderCache.Allocate(); + foreach (var e in exprs) { - r.Append(r.Length > 0 ? "," + e : e); + sb.Append(sb.Length > 0 ? "," + e : e); } - - return r.ToString(); + return StringBuilderCache.ReturnAndFree(sb); } - protected virtual List VisitNewArrayFromExpressionList(NewArrayExpression na) + protected virtual List VisitNewArrayFromExpressionList(NewArrayExpression na) { - - List exprs = VisitExpressionList(na.Expressions); + var exprs = VisitExpressionList(na.Expressions); return exprs; } - protected virtual string BindOperant(ExpressionType e) { - switch (e) { case ExpressionType.Equal: @@ -1202,22 +2597,46 @@ protected virtual string BindOperant(ExpressionType e) return "MOD"; case ExpressionType.Coalesce: return "COALESCE"; + case ExpressionType.And: + return "&"; + case ExpressionType.Or: + return "|"; + case ExpressionType.ExclusiveOr: + return "^"; + case ExpressionType.LeftShift: + return "<<"; + case ExpressionType.RightShift: + return ">>"; default: return e.ToString(); } } - protected virtual string GetQuotedColumnName(ModelDefinition tableDef, string memberName) + protected virtual string GetQuotedColumnName(ModelDefinition tableDef, string memberName) => // Always call if no tableAlias to exec overrides + GetQuotedColumnName(tableDef, null, memberName); + + protected virtual string GetQuotedColumnName(ModelDefinition tableDef, string tableAlias, string memberName) { if (useFieldName) { var fd = tableDef.FieldDefinitions.FirstOrDefault(x => x.Name == memberName); - var fieldName = fd != null - ? fd.FieldName + var fieldName = fd != null + ? fd.FieldName : memberName; - return PrefixFieldWithTableName - ? DialectProvider.GetQuotedColumnName(tableDef, fieldName) + if (tableDef.ModelType.IsInterface && this.ModelDef.ModelType.HasInterface(tableDef.ModelType)) + { + tableDef = this.ModelDef; + } + + if (fd?.CustomSelect != null) + return fd.CustomSelect; + + var includePrefix = PrefixFieldWithTableName && !tableDef.ModelType.IsInterface; + return includePrefix + ? (tableAlias == null + ? DialectProvider.GetQuotedColumnName(tableDef, fieldName) + : DialectProvider.GetQuotedColumnName(tableDef, tableAlias, fieldName)) : DialectProvider.GetQuotedColumnName(fieldName); } return memberName; @@ -1225,7 +2644,6 @@ protected virtual string GetQuotedColumnName(ModelDefinition tableDef, string me protected string RemoveQuoteFromAlias(string exp) { - if ((exp.StartsWith("\"") || exp.StartsWith("`") || exp.StartsWith("'")) && (exp.EndsWith("\"") || exp.EndsWith("`") || exp.EndsWith("'"))) @@ -1236,44 +2654,58 @@ protected string RemoveQuoteFromAlias(string exp) return exp; } - protected bool IsFieldName(object quotedExp) + protected virtual bool IsFieldName(object quotedExp) { var fieldExpr = quotedExp.ToString().StripTablePrefixes(); - var fieldNames = modelDef.FieldDefinitions.Map(x => - DialectProvider.GetQuotedColumnName(x.FieldName)); + var unquotedExpr = fieldExpr.StripDbQuotes(); + + var isTableField = modelDef.FieldDefinitionsArray + .Any(x => GetColumnName(x.FieldName) == unquotedExpr); + if (isTableField) + return true; + + var isJoinedField = tableDefs.Any(t => t.FieldDefinitionsArray + .Any(x => GetColumnName(x.FieldName) == unquotedExpr)); - return fieldNames.Any(x => x == fieldExpr); + return isJoinedField; + } + + protected string GetColumnName(string fieldName) + { + return DialectProvider.NamingStrategy.GetColumnName(fieldName); } protected object GetTrueExpression() { - return new PartialSqlString(string.Format("({0}={1})", GetQuotedTrueValue(), GetQuotedTrueValue())); + return new PartialSqlString($"({GetQuotedTrueValue()}={GetQuotedTrueValue()})"); } protected object GetFalseExpression() { - return new PartialSqlString(string.Format("({0}={1})", GetQuotedTrueValue(), GetQuotedFalseValue())); + return new PartialSqlString($"({GetQuotedTrueValue()}={GetQuotedFalseValue()})"); } + private string quotedTrue; protected object GetQuotedTrueValue() { - return new PartialSqlString(DialectProvider.GetQuotedValue(true, typeof(bool))); + return new PartialSqlString(quotedTrue ??= DialectProvider.GetQuotedValue(true, typeof(bool))); } + private string quotedFalse; protected object GetQuotedFalseValue() { - return new PartialSqlString(DialectProvider.GetQuotedValue(false, typeof(bool))); + return new PartialSqlString(quotedFalse ??= DialectProvider.GetQuotedValue(false, typeof(bool))); } private void BuildSelectExpression(string fields, bool distinct) { + OnlyFields = null; selectDistinct = distinct; - selectExpression = string.Format("SELECT {0}{1}", - (selectDistinct ? "DISTINCT " : ""), - (string.IsNullOrEmpty(fields) ? - DialectProvider.GetColumnNames(modelDef) : - fields)); + selectExpression = $"SELECT {(selectDistinct ? "DISTINCT " : "")}" + + (string.IsNullOrEmpty(fields) + ? DialectProvider.GetColumnNames(modelDef, PrefixFieldWithTableName ? TableAlias ?? ModelDef.ModelName : null).ToSelectString() + : fields); } public IList GetAllFields() @@ -1281,14 +2713,11 @@ public IList GetAllFields() return modelDef.FieldDefinitions.ConvertAll(r => r.Name); } - private bool IsStaticArrayMethod(MethodCallExpression m) + protected virtual bool IsStaticArrayMethod(MethodCallExpression m) { - if (m.Object == null && m.Method.Name == "Contains") - { - return m.Arguments.Count == 2; - } - - return false; + return (m.Object == null + && m.Method.Name == "Contains" + && m.Arguments.Count == 2); } protected virtual object VisitStaticArrayMethodCall(MethodCallExpression m) @@ -1296,12 +2725,12 @@ protected virtual object VisitStaticArrayMethodCall(MethodCallExpression m) switch (m.Method.Name) { case "Contains": - List args = this.VisitExpressionList(m.Arguments); - object quotedColName = args[1]; + List args = this.VisitExpressionList(m.Arguments); + object quotedColName = args.Last(); Expression memberExpr = m.Arguments[0]; if (memberExpr.NodeType == ExpressionType.MemberAccess) - memberExpr = (m.Arguments[0] as MemberExpression); + memberExpr = m.Arguments[0] as MemberExpression; return ToInPartialString(memberExpr, quotedColName); @@ -1310,17 +2739,13 @@ protected virtual object VisitStaticArrayMethodCall(MethodCallExpression m) } } - private bool IsEnumerableMethod(MethodCallExpression m) + private static bool IsEnumerableMethod(MethodCallExpression m) { - if (m.Object != null + return m.Object != null && m.Object.Type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable<>)) && m.Object.Type != typeof(string) - && m.Method.Name == "Contains") - { - return m.Arguments.Count == 1; - } - - return false; + && m.Method.Name == "Contains" + && m.Arguments.Count == 1; } protected virtual object VisitEnumerableMethodCall(MethodCallExpression m) @@ -1328,7 +2753,7 @@ protected virtual object VisitEnumerableMethodCall(MethodCallExpression m) switch (m.Method.Name) { case "Contains": - List args = this.VisitExpressionList(m.Arguments); + List args = this.VisitExpressionList(m.Arguments); object quotedColName = args[0]; return ToInPartialString(m.Object, quotedColName); @@ -1339,205 +2764,369 @@ protected virtual object VisitEnumerableMethodCall(MethodCallExpression m) private object ToInPartialString(Expression memberExpr, object quotedColName) { - var member = Expression.Convert(memberExpr, typeof(object)); - var lambda = Expression.Lambda>(member); - var getter = lambda.Compile(); + var result = EvaluateExpression(memberExpr); + + var inArgs = Sql.Flatten(result as IEnumerable); + + var sqlIn = inArgs.Count > 0 + ? CreateInParamSql(inArgs) + : "NULL"; + + var statement = $"{quotedColName} IN ({sqlIn})"; + return new PartialSqlString(statement); + } + + protected virtual bool IsStaticStringMethod(MethodCallExpression m) + { + return (m.Object == null + && (m.Method.Name == nameof(String.Concat) || m.Method.Name == nameof(String.Compare))); + } + + protected virtual object VisitStaticStringMethodCall(MethodCallExpression m) + { + switch (m.Method.Name) + { + case nameof(String.Concat): + return BuildConcatExpression(VisitExpressionList(m.Arguments)); + case nameof(String.Compare): + return BuildCompareExpression(VisitExpressionList(m.Arguments)); - var inArgs = Sql.Flatten(getter() as IEnumerable); + default: + throw new NotSupportedException(); + } + } - var sIn = new StringBuilder(); - if (inArgs.Count > 0) + private object VisitLengthStringProperty(MemberExpression m) + { + var sql = Visit(m.Expression); + if (!IsSqlClass(sql)) { - foreach (object e in inArgs) - { - if (sIn.Length > 0) - sIn.Append(","); + if (sql == null) + return 0; - sIn.Append(DialectProvider.GetQuotedValue(e, e.GetType())); - } + sql = ((string)sql).Length; + return sql; } - else + + return ToLengthPartialString(sql); + } + + protected virtual PartialSqlString ToLengthPartialString(object arg) + { + return new PartialSqlString($"CHAR_LENGTH({arg})"); + } + + private PartialSqlString BuildConcatExpression(List args) + { + for (int i = 0; i < args.Count; i++) { - sIn.Append("NULL"); + if (!(args[i] is PartialSqlString)) + args[i] = ConvertToParam(args[i]); } + return ToConcatPartialString(args); + } - var statement = string.Format("{0} {1} ({2})", quotedColName, "In", sIn); - return new PartialSqlString(statement); + private PartialSqlString BuildCompareExpression(List args) + { + for (int i = 0; i < args.Count; i++) + { + if (!(args[i] is PartialSqlString)) + args[i] = ConvertToParam(args[i]); + } + return ToComparePartialString(args); + } + + protected PartialSqlString ToConcatPartialString(List args) + { + return new PartialSqlString(DialectProvider.SqlConcat(args)); + } + + protected virtual PartialSqlString ToComparePartialString(List args) + { + return new PartialSqlString($"(CASE WHEN {args[0]} = {args[1]} THEN 0 WHEN {args[0]} > {args[1]} THEN 1 ELSE -1 END)"); } protected virtual object VisitSqlMethodCall(MethodCallExpression m) { - List args = this.VisitExpressionList(m.Arguments); + List args = this.VisitInSqlExpressionList(m.Arguments); object quotedColName = args[0]; + var columnEnumMemberAccess = args[0] as EnumMemberAccess; args.RemoveAt(0); string statement; switch (m.Method.Name) { - case "In": + case nameof(Sql.In): + statement = ConvertInExpressionToSql(m, quotedColName); + break; + case nameof(Sql.Asc): + statement = $"{quotedColName} ASC"; + break; + case nameof(Sql.Desc): + statement = $"{quotedColName} DESC"; + break; + case nameof(Sql.As): + statement = $"{quotedColName} AS {DialectProvider.GetQuotedColumnName(RemoveQuoteFromAlias(args[0].ToString()))}"; + break; + case nameof(Sql.Cast): + statement = DialectProvider.SqlCast(quotedColName, args[0].ToString()); + break; + case nameof(Sql.Sum): + case nameof(Sql.Count): + case nameof(Sql.Min): + case nameof(Sql.Max): + case nameof(Sql.Avg): + statement = $"{m.Method.Name}({quotedColName}{(args.Count == 1 ? $",{args[0]}" : "")})"; + break; + case nameof(Sql.CountDistinct): + statement = $"COUNT(DISTINCT {quotedColName})"; + break; + case nameof(Sql.AllFields): + var argDef = m.Arguments[0].Type.GetModelMetadata(); + statement = DialectProvider.GetQuotedTableName(argDef) + ".*"; + break; + case nameof(Sql.JoinAlias): + case nameof(Sql.TableAlias): + if (quotedColName is SelectList && m.Arguments.Count == 2 && m.Arguments[0] is ParameterExpression p) + { + var paramModelDef = p.Type.GetModelDefinition(); + var alias = Visit(m.Arguments[1]).ToString(); + statement = new SelectList(DialectProvider.GetColumnNames(paramModelDef, alias)).ToString(); + } + else + { + statement = args[0] + "." + quotedColName.ToString().LastRightPart('.'); + } + break; + case nameof(Sql.Custom): + statement = quotedColName.ToString(); + break; + default: + throw new NotSupportedException(); + } - var member = Expression.Convert(m.Arguments[1], typeof(object)); - var lambda = Expression.Lambda>(member); - var getter = lambda.Compile(); + return new PartialSqlString(statement, columnEnumMemberAccess); + } - var inArgs = Sql.Flatten(getter() as IEnumerable); + protected string ConvertInExpressionToSql(MethodCallExpression m, object quotedColName) + { + var argValue = EvaluateExpression(m.Arguments[1]); - var sIn = new StringBuilder(); - foreach (object e in inArgs) - { - if (!(e is ICollection)) - { - if (sIn.Length > 0) - sIn.Append(","); + if (argValue == null) + return FalseLiteral; // "column IN (NULL)" is always false - sIn.Append(DialectProvider.GetQuotedValue(e, e.GetType())); - } - else - { - var listArgs = e as ICollection; - foreach (object el in listArgs) - { - if (sIn.Length > 0) - sIn.Append(","); + if (argValue is IEnumerable enumerableArg) + { + var inArgs = Sql.Flatten(enumerableArg); + if (inArgs.Count == 0) + return FalseLiteral; // "column IN ([])" is always false - sIn.Append(DialectProvider.GetQuotedValue(el, el.GetType())); - } - } + string sqlIn = CreateInParamSql(inArgs); + return $"{quotedColName} IN ({sqlIn})"; + } + + if (argValue is ISqlExpression exprArg) + { + var subSelect = exprArg.ToSelectStatement(QueryType.Select); + var renameParams = new List>(); + foreach (var p in exprArg.Params) + { + var oldName = p.ParameterName; + var newName = DialectProvider.GetParam(Params.Count.ToString()); + if (oldName != newName) + { + var pClone = DialectProvider.CreateParam().PopulateWith(p); + renameParams.Add(Tuple.Create(oldName, newName)); + pClone.ParameterName = newName; + Params.Add(pClone); + } + else + { + Params.Add(p); } + } - statement = string.Format("{0} {1} ({2})", quotedColName, m.Method.Name, sIn.ToString()); - break; - case "Desc": - statement = string.Format("{0} DESC", quotedColName); - break; - case "As": - statement = string.Format("{0} As {1}", quotedColName, - DialectProvider.GetQuotedColumnName(RemoveQuoteFromAlias(args[0].ToString()))); - break; - case "Sum": - case "Count": - case "Min": - case "Max": - case "Avg": - statement = string.Format("{0}({1}{2})", - m.Method.Name, - quotedColName, - args.Count == 1 ? string.Format(",{0}", args[0]) : ""); - break; - default: - throw new NotSupportedException(); + // regex replace doesn't work when param is at end of string "AND a = :0" + var lastChar = subSelect[subSelect.Length - 1]; + if (!(char.IsWhiteSpace(lastChar) || lastChar == ')')) + subSelect += " "; + + for (var i = renameParams.Count - 1; i >= 0; i--) + { + //Replace complete db params [@1] and not partial tokens [@1]0 + var paramsRegex = new Regex(renameParams[i].Item1 + "([^\\d])"); + subSelect = paramsRegex.Replace(subSelect, renameParams[i].Item2 + "$1"); + } + + return CreateInSubQuerySql(quotedColName, subSelect); } - return new PartialSqlString(statement); + throw new NotSupportedException($"In({argValue.GetType()})"); + } + + protected virtual string CreateInSubQuerySql(object quotedColName, string subSelect) + { + return $"{quotedColName} IN ({subSelect})"; } protected virtual object VisitColumnAccessMethod(MethodCallExpression m) { - List args = this.VisitExpressionList(m.Arguments); + List args = this.VisitExpressionList(m.Arguments); var quotedColName = Visit(m.Object); + if (!IsSqlClass(quotedColName)) + quotedColName = ConvertToParam(quotedColName); + var statement = ""; - var wildcardArg = args.Count > 0 ? DialectProvider.EscapeWildcards(args[0].ToString()) : ""; + var arg = args.Count > 0 ? args[0] : null; + var wildcardArg = arg != null ? DialectProvider.EscapeWildcards(arg.ToString()) : ""; var escapeSuffix = wildcardArg.IndexOf('^') >= 0 ? " escape '^'" : ""; switch (m.Method.Name) { case "Trim": - statement = string.Format("ltrim(rtrim({0}))", quotedColName); + statement = $"ltrim(rtrim({quotedColName}))"; break; case "LTrim": - statement = string.Format("ltrim({0})", quotedColName); + statement = $"ltrim({quotedColName})"; break; case "RTrim": - statement = string.Format("rtrim({0})", quotedColName); + statement = $"rtrim({quotedColName})"; break; case "ToUpper": - statement = string.Format("upper({0})", quotedColName); + statement = $"upper({quotedColName})"; break; case "ToLower": - statement = string.Format("lower({0})", quotedColName); + statement = $"lower({quotedColName})"; + break; + case "Equals": + var argType = arg?.GetType(); + var converter = argType != null && argType != typeof(string) + ? DialectProvider.GetConverterBestMatch(argType) + : null; + statement = converter != null + ? $"{quotedColName}={ConvertToParam(converter.ToDbValue(argType, arg))}" + : $"{quotedColName}={ConvertToParam(arg)}"; break; case "StartsWith": - if (!OrmLiteConfig.StripUpperInLike) - { - statement = string.Format("upper({0}) like {1}{2}", - quotedColName, DialectProvider.GetQuotedValue( - wildcardArg.ToUpper() + "%"), escapeSuffix); - } - else - { - statement = string.Format("{0} like {1}{2}", - quotedColName, DialectProvider.GetQuotedValue( - wildcardArg + "%"), escapeSuffix); - } + statement = !OrmLiteConfig.StripUpperInLike + ? $"upper({quotedColName}) like {ConvertToParam(wildcardArg.ToUpper() + "%")}{escapeSuffix}" + : $"{quotedColName} like {ConvertToParam(wildcardArg + "%")}{escapeSuffix}"; break; case "EndsWith": - if (!OrmLiteConfig.StripUpperInLike) - { - statement = string.Format("upper({0}) like {1}{2}", - quotedColName, DialectProvider.GetQuotedValue("%" + - wildcardArg.ToUpper()), escapeSuffix); - } - else - { - statement = string.Format("{0} like {1}{2}", - quotedColName, DialectProvider.GetQuotedValue("%" + - wildcardArg), escapeSuffix); - } + statement = !OrmLiteConfig.StripUpperInLike + ? $"upper({quotedColName}) like {ConvertToParam("%" + wildcardArg.ToUpper())}{escapeSuffix}" + : $"{quotedColName} like {ConvertToParam("%" + wildcardArg)}{escapeSuffix}"; break; case "Contains": - if (!OrmLiteConfig.StripUpperInLike) - { - statement = string.Format("upper({0}) like {1}{2}", - quotedColName, DialectProvider.GetQuotedValue("%" + - wildcardArg.ToUpper() + "%"), escapeSuffix); - } - else - { - statement = string.Format("{0} like {1}{2}", - quotedColName, DialectProvider.GetQuotedValue("%" + - wildcardArg + "%"), escapeSuffix); - } + statement = !OrmLiteConfig.StripUpperInLike + ? $"upper({quotedColName}) like {ConvertToParam("%" + wildcardArg.ToUpper() + "%")}{escapeSuffix}" + : $"{quotedColName} like {ConvertToParam("%" + wildcardArg + "%")}{escapeSuffix}"; break; case "Substring": - var startIndex = Int32.Parse(args[0].ToString()) + 1; - if (args.Count == 2) - { - var length = Int32.Parse(args[1].ToString()); - statement = string.Format("substring({0} from {1} for {2})", - quotedColName, - startIndex, - length); - } - else - statement = string.Format("substring({0} from {1})", - quotedColName, - startIndex); + var startIndex = int.Parse(args[0].ToString()) + 1; + statement = args.Count == 2 + ? GetSubstringSql(quotedColName, startIndex, int.Parse(args[1].ToString())) + : GetSubstringSql(quotedColName, startIndex); + break; + case "ToString": + statement = m.Object?.Type == typeof(string) + ? $"({quotedColName})" + : ToCast(quotedColName.ToString()); break; default: throw new NotSupportedException(); } return new PartialSqlString(statement); } + + protected virtual string ToCast(string quotedColName) + { + return $"cast({quotedColName} as varchar(1000))"; + } + + public virtual string GetSubstringSql(object quotedColumn, int startIndex, int? length = null) + { + return length != null + ? $"substring({quotedColumn} from {startIndex} for {length.Value})" + : $"substring({quotedColumn} from {startIndex})"; + } + + public IDbDataParameter CreateParam(string name, + object value = null, + ParameterDirection direction = ParameterDirection.Input, + DbType? dbType = null, + DataRowVersion sourceVersion = DataRowVersion.Default) + { + var p = DialectProvider.CreateParam(); + p.ParameterName = DialectProvider.GetParam(name); + p.Direction = direction; + + if (!DialectProvider.IsMySqlConnector()) //throws NotSupportedException + { + p.SourceVersion = sourceVersion; + } + + DialectProvider.ConfigureParam(p, value, dbType); + + return p; + } + + public IUntypedSqlExpression GetUntyped() + { + return new UntypedSqlExpressionProxy(this); + } } public interface ISqlExpression { + List Params { get; } + string ToSelectStatement(); + string ToSelectStatement(QueryType forType); string SelectInto(); + string SelectInto(QueryType forType); + } + + public enum QueryType + { + Select, + Single, + Scalar, + } + + public interface IHasDialectProvider + { + IOrmLiteDialectProvider DialectProvider { get; } } public class PartialSqlString { - public PartialSqlString(string text) + public static PartialSqlString Null = new("null"); + + public PartialSqlString(string text) : this(text, null) + { + } + + public PartialSqlString(string text, EnumMemberAccess enumMember) { Text = text; + EnumMember = enumMember; } - public string Text { get; set; } - public override string ToString() + public string Text { get; internal set; } + public readonly EnumMemberAccess EnumMember; + + public override string ToString() => Text; + + protected bool Equals(PartialSqlString other) => Text == other.Text; + public override bool Equals(object obj) { - return Text; + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((PartialSqlString)obj); } + public override int GetHashCode() => (Text != null ? Text.GetHashCode() : 0); } public class EnumMemberAccess : PartialSqlString @@ -1545,7 +3134,7 @@ public class EnumMemberAccess : PartialSqlString public EnumMemberAccess(string text, Type enumType) : base(text) { - if (!enumType.IsEnum) throw new ArgumentException("Type not valid", "enumType"); + if (!enumType.IsEnum) throw new ArgumentException("Type not valid", nameof(enumType)); EnumType = enumType; } @@ -1553,5 +3142,214 @@ public EnumMemberAccess(string text, Type enumType) public Type EnumType { get; private set; } } + public abstract class SelectItem + { + protected SelectItem(IOrmLiteDialectProvider dialectProvider, string alias) + { + DialectProvider = dialectProvider ?? throw new ArgumentNullException(nameof(dialectProvider)); + + Alias = alias; + } + + /// + /// Unquoted alias for the column or expression being selected. + /// + public string Alias { get; set; } + + protected IOrmLiteDialectProvider DialectProvider { get; set; } + + public abstract override string ToString(); + } + + public class SelectItemExpression : SelectItem + { + public SelectItemExpression(IOrmLiteDialectProvider dialectProvider, string selectExpression, string alias) + : base(dialectProvider, alias) + { + if (string.IsNullOrEmpty(selectExpression)) + throw new ArgumentNullException(nameof(selectExpression)); + if (string.IsNullOrEmpty(alias)) + throw new ArgumentNullException(nameof(alias)); + + SelectExpression = selectExpression; + Alias = alias; + } + + /// + /// The SQL expression being selected, including any necessary quoting. + /// + public string SelectExpression { get; set; } + + public override string ToString() + { + var text = SelectExpression; + if (!string.IsNullOrEmpty(Alias)) // Note that even though Alias must be non-empty in the constructor it may be set to null/empty later + return text + " AS " + DialectProvider.GetQuotedName(Alias); + + return text; + } + } + + public class SelectItemColumn : SelectItem + { + public SelectItemColumn(IOrmLiteDialectProvider dialectProvider, string columnName, string columnAlias = null, string quotedTableAlias = null) + : base(dialectProvider, columnAlias) + { + if (string.IsNullOrEmpty(columnName)) + throw new ArgumentNullException(nameof(columnName)); + + ColumnName = columnName; + QuotedTableAlias = quotedTableAlias; + } + + /// + /// Unquoted column name being selected. + /// + public string ColumnName { get; set; } + /// + /// Table name or alias used to prefix the column name, if any. Already quoted. + /// + public string QuotedTableAlias { get; set; } + + public override string ToString() + { + var text = DialectProvider.GetQuotedColumnName(ColumnName); + + if (!string.IsNullOrEmpty(QuotedTableAlias)) + text = QuotedTableAlias + "." + text; + if (!string.IsNullOrEmpty(Alias)) + text += " AS " + DialectProvider.GetQuotedName(Alias); + + return text; + } + } + + public class OrmLiteDataParameter : IDbDataParameter + { + public DbType DbType { get; set; } + public ParameterDirection Direction { get; set; } + public bool IsNullable { get; set; } + public string ParameterName { get; set; } + public string SourceColumn { get; set; } + public DataRowVersion SourceVersion { get; set; } + public object Value { get; set; } + public byte Precision { get; set; } + public byte Scale { get; set; } + public int Size { get; set; } + } + + public static class DbDataParameterExtensions + { + public static IDbDataParameter CreateParam(this IDbConnection db, + string name, + object value = null, + Type fieldType = null, + DbType? dbType = null, + byte? precision = null, + byte? scale = null, + int? size = null) + { + return db.GetDialectProvider().CreateParam(name, value, fieldType, dbType, precision, scale, size); + } + + public static IDbDataParameter CreateParam(this IOrmLiteDialectProvider dialectProvider, + string name, + object value = null, + Type fieldType = null, + DbType? dbType = null, + byte? precision = null, + byte? scale = null, + int? size = null) + { + var p = dialectProvider.CreateParam(); + + p.ParameterName = dialectProvider.GetParam(name); + + dialectProvider.ConfigureParam(p, value, dbType); + + if (precision != null) + p.Precision = precision.Value; + if (scale != null) + p.Scale = scale.Value; + if (size != null) + p.Size = size.Value; + + return p; + } + + internal static void ConfigureParam(this IOrmLiteDialectProvider dialectProvider, IDbDataParameter p, object value, DbType? dbType) + { + if (value != null) + { + dialectProvider.InitDbParam(p, value.GetType()); + p.Value = dialectProvider.GetParamValue(value, value.GetType()); + } + else + { + p.Value = DBNull.Value; + } + + // Can't check DbType in PostgreSQL before p.Value is assinged + if (p.Value is string strValue && strValue.Length > p.Size) + { + var stringConverter = dialectProvider.GetStringConverter(); + p.Size = strValue.Length > stringConverter.StringLength + ? strValue.Length + : stringConverter.StringLength; + } + + if (dbType != null) + p.DbType = dbType.Value; + } + + public static IDbDataParameter AddQueryParam(this IOrmLiteDialectProvider dialectProvider, + IDbCommand dbCmd, + object value, + FieldDefinition fieldDef) => dialectProvider.AddParam(dbCmd, value, fieldDef, paramFilter: dialectProvider.InitQueryParam); + + public static IDbDataParameter AddUpdateParam(this IOrmLiteDialectProvider dialectProvider, + IDbCommand dbCmd, + object value, + FieldDefinition fieldDef) => dialectProvider.AddParam(dbCmd, value, fieldDef, paramFilter: dialectProvider.InitUpdateParam); + + public static IDbDataParameter AddParam(this IOrmLiteDialectProvider dialectProvider, + IDbCommand dbCmd, + object value, + FieldDefinition fieldDef, Action paramFilter) + { + var paramName = dbCmd.Parameters.Count.ToString(); + var parameter = dialectProvider.CreateParam(paramName, value, fieldDef?.ColumnType); + + paramFilter?.Invoke(parameter); + + if (fieldDef != null) + dialectProvider.SetParameter(fieldDef, parameter); + + dbCmd.Parameters.Add(parameter); + return parameter; + } + + public static string GetInsertParam(this IOrmLiteDialectProvider dialectProvider, + IDbCommand dbCmd, + object value, + FieldDefinition fieldDef) + { + var p = dialectProvider.AddUpdateParam(dbCmd, value, fieldDef); + return fieldDef.CustomInsert != null + ? string.Format(fieldDef.CustomInsert, p.ParameterName) + : p.ParameterName; + } + + public static string GetUpdateParam(this IOrmLiteDialectProvider dialectProvider, + IDbCommand dbCmd, + object value, + FieldDefinition fieldDef) + { + var p = dialectProvider.AddUpdateParam(dbCmd, value, fieldDef); + return fieldDef.CustomUpdate != null + ? string.Format(fieldDef.CustomUpdate, p.ParameterName) + : p.ParameterName; + } + } } diff --git a/src/ServiceStack.OrmLite/Expressions/SqlExpressionVisitor.cs b/src/ServiceStack.OrmLite/Expressions/SqlExpressionVisitor.cs index 83fa8bdb6..de50f31bb 100644 --- a/src/ServiceStack.OrmLite/Expressions/SqlExpressionVisitor.cs +++ b/src/ServiceStack.OrmLite/Expressions/SqlExpressionVisitor.cs @@ -73,7 +73,7 @@ protected virtual Expression Visit(Expression exp) case ExpressionType.ListInit: return this.VisitListInit((ListInitExpression)exp); default: - throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType)); + throw new Exception($"Unhandled expression type: '{exp.NodeType}'"); } } @@ -88,7 +88,7 @@ protected virtual MemberBinding VisitBinding(MemberBinding binding) case MemberBindingType.ListBinding: return this.VisitMemberListBinding((MemberListBinding)binding); default: - throw new Exception(string.Format("Unhandled binding type '{0}'", binding.BindingType)); + throw new Exception($"Unhandled binding type '{binding.BindingType}'"); } } diff --git a/src/ServiceStack.OrmLite/Expressions/WriteExpressionCommandExtensions.cs b/src/ServiceStack.OrmLite/Expressions/WriteExpressionCommandExtensions.cs index a6799cb73..c957de767 100644 --- a/src/ServiceStack.OrmLite/Expressions/WriteExpressionCommandExtensions.cs +++ b/src/ServiceStack.OrmLite/Expressions/WriteExpressionCommandExtensions.cs @@ -1,193 +1,393 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Linq.Expressions; using System.Text; +using ServiceStack.Data; using ServiceStack.Text; namespace ServiceStack.OrmLite { internal static class WriteExpressionCommandExtensions { - public static int UpdateOnly(this IDbCommand dbCmd, T model, Func, SqlExpression> onlyFields) + public static int UpdateOnlyFields(this IDbCommand dbCmd, + T model, + SqlExpression onlyFields, + Action commandFilter = null) { - return dbCmd.UpdateOnly(model, onlyFields(dbCmd.GetDialectProvider().SqlExpression())); + OrmLiteUtils.AssertNotAnonType(); + + UpdateOnlySql(dbCmd, model, onlyFields); + commandFilter?.Invoke(dbCmd); + return dbCmd.ExecNonQuery(); } - public static int UpdateOnly(this IDbCommand dbCmd, T model, SqlExpression onlyFields) + internal static void UpdateOnlySql(this IDbCommand dbCmd, T model, SqlExpression onlyFields) { - var sql = UpdateOnlySql(dbCmd, model, onlyFields); - return dbCmd.ExecuteSql(sql); - } - - internal static string UpdateOnlySql(this IDbCommand dbCmd, T model, SqlExpression onlyFields) - { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, model); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, model); var fieldsToUpdate = onlyFields.UpdateFields.Count == 0 ? onlyFields.GetAllFields() : onlyFields.UpdateFields; - var sql = dbCmd.GetDialectProvider().ToUpdateRowStatement(model, fieldsToUpdate); + onlyFields.CopyParamsTo(dbCmd); + + dbCmd.GetDialectProvider().PrepareUpdateRowStatement(dbCmd, model, fieldsToUpdate); - if (!onlyFields.WhereExpression.IsNullOrEmpty()) sql += " " + onlyFields.WhereExpression; - return sql; + if (!onlyFields.WhereExpression.IsNullOrEmpty()) + dbCmd.CommandText += " " + onlyFields.WhereExpression; } - public static int UpdateOnly(this IDbCommand dbCmd, T obj, - Expression> onlyFields = null, - Expression> where = null) + internal static int UpdateOnlyFields(this IDbCommand dbCmd, T obj, + Expression> onlyFields = null, + Expression> where = null, + Action commandFilter = null) { + OrmLiteUtils.AssertNotAnonType(); + if (onlyFields == null) - throw new ArgumentNullException("onlyFields"); + throw new ArgumentNullException(nameof(onlyFields)); var q = dbCmd.GetDialectProvider().SqlExpression(); q.Update(onlyFields); q.Where(where); - return dbCmd.UpdateOnly(obj, q); + return dbCmd.UpdateOnlyFields(obj, q, commandFilter); } - public static int UpdateNonDefaults(this IDbCommand dbCmd, T item, Expression> obj) + internal static int UpdateOnlyFields(this IDbCommand dbCmd, T obj, + string[] onlyFields = null, + Expression> where = null, + Action commandFilter = null) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, item); + OrmLiteUtils.AssertNotAnonType(); + + if (onlyFields == null) + throw new ArgumentNullException(nameof(onlyFields)); var q = dbCmd.GetDialectProvider().SqlExpression(); - q.Where(obj); - var sql = q.ToUpdateStatement(item, excludeDefaults: true); - return dbCmd.ExecuteSql(sql); + q.Update(onlyFields); + q.Where(where); + return dbCmd.UpdateOnlyFields(obj, q, commandFilter); } - public static int Update(this IDbCommand dbCmd, T item, Expression> expression) + internal static int UpdateOnly(this IDbCommand dbCmd, + Expression> updateFields, + SqlExpression q, + Action commandFilter = null) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, item); + OrmLiteUtils.AssertNotAnonType(); + + var cmd = dbCmd.InitUpdateOnly(updateFields, q); + commandFilter?.Invoke(cmd); + return cmd.ExecNonQuery(); + } - var q = dbCmd.GetDialectProvider().SqlExpression(); - q.Where(expression); - var sql = q.ToUpdateStatement(item); - return dbCmd.ExecuteSql(sql); + internal static IDbCommand InitUpdateOnly(this IDbCommand dbCmd, Expression> updateFields, SqlExpression q) + { + if (updateFields == null) + throw new ArgumentNullException(nameof(updateFields)); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateFields.EvalFactoryFn()); + + q.CopyParamsTo(dbCmd); + + var updateFieldValues = updateFields.AssignedValues(); + dbCmd.GetDialectProvider().PrepareUpdateRowStatement(dbCmd, updateFieldValues, q.WhereExpression); + + return dbCmd; } - public static int Update(this IDbCommand dbCmd, object updateOnly, Expression> where = null) + internal static int UpdateOnly(this IDbCommand dbCmd, + Expression> updateFields, + string whereExpression, + IEnumerable dbParams, + Action commandFilter = null) { - var updateSql = UpdateSql(dbCmd.GetDialectProvider(), updateOnly, where); - return dbCmd.ExecuteSql(updateSql); + OrmLiteUtils.AssertNotAnonType(); + + var cmd = dbCmd.InitUpdateOnly(updateFields, whereExpression, dbParams); + commandFilter?.Invoke(cmd); + return cmd.ExecNonQuery(); } - internal static string UpdateSql(IOrmLiteDialectProvider dialectProvider, object updateOnly, Expression> @where) + internal static IDbCommand InitUpdateOnly(this IDbCommand dbCmd, Expression> updateFields, string whereExpression, IEnumerable sqlParams) { - var ev = dialectProvider.SqlExpression(); - var whereSql = ev.Where(@where).WhereExpression; - var sql = new StringBuilder(); - var modelDef = typeof(T).GetModelDefinition(); - var fields = modelDef.FieldDefinitionsArray; + if (updateFields == null) + throw new ArgumentNullException(nameof(updateFields)); - foreach (var setField in updateOnly.GetType().GetPublicProperties()) - { - var fieldDef = fields.FirstOrDefault(x => - string.Equals(x.Name, setField.Name, StringComparison.OrdinalIgnoreCase)); - if (fieldDef == null || fieldDef.ShouldSkipUpdate()) continue; + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateFields.EvalFactoryFn()); - if (sql.Length > 0) - sql.Append(", "); + dbCmd.SetParameters(sqlParams); - sql.AppendFormat("{0}={1}", - dialectProvider.GetQuotedColumnName(fieldDef.FieldName), - dialectProvider.GetQuotedValue(setField.GetPropertyGetterFn()(updateOnly), fieldDef.FieldType)); - } + var updateFieldValues = updateFields.AssignedValues(); + dbCmd.GetDialectProvider().PrepareUpdateRowStatement(dbCmd, updateFieldValues, whereExpression); - var updateSql = string.Format("UPDATE {0} SET {1} {2}", - dialectProvider.GetQuotedTableName(modelDef), sql, whereSql); - return updateSql; + return dbCmd; + } + + public static int UpdateAdd(this IDbCommand dbCmd, + Expression> updateFields, + SqlExpression q, + Action commandFilter) + { + var cmd = dbCmd.InitUpdateAdd(updateFields, q); + commandFilter?.Invoke(cmd); + return cmd.ExecNonQuery(); } - public static int UpdateFmt(this IDbCommand dbCmd, string set = null, string where = null) + internal static IDbCommand InitUpdateAdd(this IDbCommand dbCmd, Expression> updateFields, SqlExpression q) { - return dbCmd.UpdateFmt(typeof(T).GetModelDefinition().ModelName, set, where); + if (updateFields == null) + throw new ArgumentNullException(nameof(updateFields)); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateFields.EvalFactoryFn()); + + q.CopyParamsTo(dbCmd); + + var updateFieldValues = updateFields.AssignedValues(); + dbCmd.GetDialectProvider().PrepareUpdateRowAddStatement(dbCmd, updateFieldValues, q.WhereExpression); + + return dbCmd; } - public static int UpdateFmt(this IDbCommand dbCmd, string table = null, string set = null, string where = null) + public static int UpdateOnly(this IDbCommand dbCmd, + Dictionary updateFields, + Expression> where, + Action commandFilter = null) { - var sql = UpdateFmtSql(dbCmd.GetDialectProvider(), table, set, @where); - return dbCmd.ExecuteSql(sql.ToString()); + OrmLiteUtils.AssertNotAnonType(); + + if (updateFields == null) + throw new ArgumentNullException(nameof(updateFields)); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateFields.ToFilterType()); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(where); + q.PrepareUpdateStatement(dbCmd, updateFields); + return dbCmd.UpdateAndVerify(commandFilter, updateFields.ContainsKey(ModelDefinition.RowVersionName)); } - internal static StringBuilder UpdateFmtSql(IOrmLiteDialectProvider dialectProvider, string table, string set, string @where) + internal static string GetUpdateOnlyWhereExpression(this IOrmLiteDialectProvider dialectProvider, + Dictionary updateFields, out object[] args) { - if (table == null) - throw new ArgumentNullException("table"); - if (set == null) - throw new ArgumentNullException("set"); + var modelDef = typeof(T).GetModelDefinition(); + var pkField = modelDef.PrimaryKey; + if (pkField == null) + throw new NotSupportedException($"'{typeof(T).Name}' does not have a primary key"); + + var idValue = updateFields.TryRemove(pkField.Name, out var nameValue) + ? nameValue + : pkField.Alias != null && updateFields.TryRemove(pkField.Alias, out var aliasValue) + ? aliasValue + : null; - var sql = new StringBuilder("UPDATE "); - sql.Append(dialectProvider.GetQuotedTableName(table)); - sql.Append(" SET "); - sql.Append(set.SqlVerifyFragment()); - if (!string.IsNullOrEmpty(@where)) + if (idValue == null) { - sql.Append(" WHERE "); - sql.Append(@where.SqlVerifyFragment()); + var caseInsensitiveMap = + new Dictionary(updateFields, StringComparer.InvariantCultureIgnoreCase); + idValue = caseInsensitiveMap.TryRemove(pkField.Name, out nameValue) + ? nameValue + : pkField.Alias != null && caseInsensitiveMap.TryRemove(pkField.Alias, out aliasValue) + ? aliasValue + : new NotSupportedException( + $"UpdateOnly<{typeof(T).Name}> requires a '{pkField.Name}' Primary Key Value"); } - return sql; + + if (modelDef.RowVersion == null || !updateFields.TryGetValue(ModelDefinition.RowVersionName, out var rowVersion)) + { + args = new[] { idValue }; + return "(" + dialectProvider.GetQuotedColumnName(pkField.FieldName) + " = {0})"; + } + + args = new[] { idValue, rowVersion }; + return "(" + dialectProvider.GetQuotedColumnName(pkField.FieldName) + " = {0} AND " + dialectProvider.GetRowVersionColumn(modelDef.RowVersion) + " = {1})"; + } + + public static int UpdateOnly(this IDbCommand dbCmd, + Dictionary updateFields, + Action commandFilter = null) + { + var whereExpr = dbCmd.GetDialectProvider().GetUpdateOnlyWhereExpression(updateFields, out var exprArgs); + dbCmd.PrepareUpdateOnly(updateFields, whereExpr, exprArgs); + return dbCmd.UpdateAndVerify(commandFilter, updateFields.ContainsKey(ModelDefinition.RowVersionName)); } - public static void InsertOnly(this IDbCommand dbCmd, T obj, Func, SqlExpression> onlyFields) + public static int UpdateOnly(this IDbCommand dbCmd, + Dictionary updateFields, + string whereExpression, + object[] whereParams, + Action commandFilter = null) { - dbCmd.InsertOnly(obj, onlyFields(dbCmd.GetDialectProvider().SqlExpression())); + dbCmd.PrepareUpdateOnly(updateFields, whereExpression, whereParams); + return dbCmd.UpdateAndVerify(commandFilter, updateFields.ContainsKey(ModelDefinition.RowVersionName)); } - public static void InsertOnly(this IDbCommand dbCmd, T obj, SqlExpression onlyFields) + internal static void PrepareUpdateOnly(this IDbCommand dbCmd, Dictionary updateFields, string whereExpression, object[] whereParams) { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, obj); + if (updateFields == null) + throw new ArgumentNullException(nameof(updateFields)); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateFields.ToFilterType()); - var sql = dbCmd.GetDialectProvider().ToInsertRowStatement(dbCmd, obj, onlyFields.InsertFields); - dbCmd.ExecuteSql(sql); + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(whereExpression, whereParams); + q.PrepareUpdateStatement(dbCmd, updateFields); } - public static int Delete(this IDbCommand dbCmd, Expression> where) + public static int UpdateNonDefaults(this IDbCommand dbCmd, T item, Expression> where) { - var ev = dbCmd.GetDialectProvider().SqlExpression(); - ev.Where(where); - return dbCmd.Delete(ev); + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, item); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(@where); + q.PrepareUpdateStatement(dbCmd, item, excludeDefaults: true); + return dbCmd.ExecNonQuery(); } - public static int Delete(this IDbCommand dbCmd, Func, SqlExpression> where) + public static int Update(this IDbCommand dbCmd, T item, Expression> expression, Action commandFilter = null) { - return dbCmd.Delete(where(dbCmd.GetDialectProvider().SqlExpression())); + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, item); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(expression); + q.PrepareUpdateStatement(dbCmd, item); + commandFilter?.Invoke(dbCmd); + return dbCmd.ExecNonQuery(); } - public static int Delete(this IDbCommand dbCmd, SqlExpression where) + public static int Update(this IDbCommand dbCmd, object updateOnly, Expression> where = null, Action commandFilter = null) { - var sql = where.ToDeleteRowStatement(); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, updateOnly.ToFilterType()); + + var q = dbCmd.GetDialectProvider().SqlExpression(); + var whereSql = q.Where(where).WhereExpression; + q.CopyParamsTo(dbCmd); + var hadRowVersion = dbCmd.PrepareUpdateAnonSql(dbCmd.GetDialectProvider(), updateOnly, whereSql); + + return dbCmd.UpdateAndVerify(commandFilter, hadRowVersion); + } + + internal static bool PrepareUpdateAnonSql(this IDbCommand dbCmd, IOrmLiteDialectProvider dialectProvider, object updateOnly, string whereSql) + { + var sql = StringBuilderCache.Allocate(); + var modelDef = typeof(T).GetModelDefinition(); + var fields = modelDef.FieldDefinitionsArray; + + var fieldDefs = new List(); + if (updateOnly is IDictionary d) + { + foreach (DictionaryEntry entry in d) + { + var fieldDef = modelDef.GetFieldDefinition((string)entry.Key); + if (fieldDef == null || fieldDef.ShouldSkipUpdate()) + continue; + fieldDefs.Add(fieldDef); + } + } + else + { + foreach (var setField in updateOnly.GetType().GetPublicProperties()) + { + var fieldDef = fields.FirstOrDefault(x => + string.Equals(x.Name, setField.Name, StringComparison.OrdinalIgnoreCase)); + if (fieldDef == null || fieldDef.ShouldSkipUpdate()) + continue; + fieldDefs.Add(fieldDef); + } + } + + var hadRowVersion = false; + foreach (var fieldDef in fieldDefs) + { + var value = fieldDef.GetValue(updateOnly); + if (fieldDef.IsPrimaryKey || fieldDef.AutoIncrement || fieldDef.IsRowVersion) + { + if (fieldDef.IsRowVersion) + hadRowVersion = true; + + whereSql += string.IsNullOrEmpty(whereSql) ? "WHERE " : " AND "; + whereSql += $"{dialectProvider.GetQuotedColumnName(fieldDef.FieldName)} = {dialectProvider.AddQueryParam(dbCmd, value, fieldDef).ParameterName}"; + continue; + } + + if (sql.Length > 0) + sql.Append(", "); + + sql + .Append(dialectProvider.GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(dialectProvider.GetUpdateParam(dbCmd, value, fieldDef)); + } + + dbCmd.CommandText = $"UPDATE {dialectProvider.GetQuotedTableName(modelDef)} " + + $"SET {StringBuilderCache.ReturnAndFree(sql)} {whereSql}"; + + return hadRowVersion; + } + + public static long InsertOnly(this IDbCommand dbCmd, T obj, string[] onlyFields, bool selectIdentity) + { + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); + + var dialectProvider = dbCmd.GetDialectProvider(); + var sql = dialectProvider.ToInsertRowStatement(dbCmd, obj, onlyFields); + + dialectProvider.SetParameterValues(dbCmd, obj); + + if (selectIdentity) + return dbCmd.ExecLongScalar(sql + dialectProvider.GetLastInsertIdSqlSuffix()); + return dbCmd.ExecuteSql(sql); } - public static int DeleteFmt(this IDbCommand dbCmd, string where = null) + public static long InsertOnly(this IDbCommand dbCmd, Expression> insertFields, bool selectIdentity) { - return dbCmd.DeleteFmt(typeof(T).GetModelDefinition().ModelName, where); + dbCmd.InitInsertOnly(insertFields); + + if (selectIdentity) + return dbCmd.ExecLongScalar(dbCmd.CommandText + dbCmd.GetDialectProvider().GetLastInsertIdSqlSuffix()); + + return dbCmd.ExecuteNonQuery(); } - public static int DeleteFmt(this IDbCommand dbCmd, string table = null, string where = null) + internal static IDbCommand InitInsertOnly(this IDbCommand dbCmd, Expression> insertFields) { - var sql = DeleteFmtSql(dbCmd.GetDialectProvider(), table, @where); - return dbCmd.ExecuteSql(sql.ToString()); + if (insertFields == null) + throw new ArgumentNullException(nameof(insertFields)); + + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, insertFields.EvalFactoryFn()); + + var fieldValuesMap = insertFields.AssignedValues(); + dbCmd.GetDialectProvider().PrepareInsertRowStatement(dbCmd, fieldValuesMap); + return dbCmd; } - internal static StringBuilder DeleteFmtSql(IOrmLiteDialectProvider dialectProvider, string table, string @where) + public static int Delete(this IDbCommand dbCmd, Expression> where, Action commandFilter = null) { - if (table == null) - throw new ArgumentNullException("table"); - if (@where == null) - throw new ArgumentNullException("where"); + var ev = dbCmd.GetDialectProvider().SqlExpression(); + ev.Where(where); + return dbCmd.Delete(ev, commandFilter); + } - var sql = new StringBuilder(); - sql.AppendFormat("DELETE FROM {0} WHERE {1}", - dialectProvider.GetQuotedTableName(table), - @where.SqlVerifyFragment()); - return sql; + public static int Delete(this IDbCommand dbCmd, SqlExpression where, Action commandFilter = null) + { + var sql = where.ToDeleteRowStatement(); + return dbCmd.ExecuteSql(sql, where.Params, commandFilter); + } + + public static int DeleteWhere(this IDbCommand dbCmd, string whereFilter, object[] whereParams) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + q.Where(whereFilter, whereParams); + var sql = q.ToDeleteRowStatement(); + return dbCmd.ExecuteSql(sql, q.Params); } } } diff --git a/src/ServiceStack.OrmLite/FieldDefinition.cs b/src/ServiceStack.OrmLite/FieldDefinition.cs index e415bd61f..e76812449 100644 --- a/src/ServiceStack.OrmLite/FieldDefinition.cs +++ b/src/ServiceStack.OrmLite/FieldDefinition.cs @@ -4,12 +4,13 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // using System; +using System.Collections; using System.Reflection; namespace ServiceStack.OrmLite @@ -20,19 +21,15 @@ public class FieldDefinition public string Alias { get; set; } - public string FieldName - { - get { return this.Alias ?? this.Name; } - } + public string FieldName => this.Alias ?? this.Name; public Type FieldType { get; set; } + public object FieldTypeDefaultValue { get; set; } + public Type TreatAsType { get; set; } - public Type ColumnType - { - get { return TreatAsType ?? FieldType; } - } + public Type ColumnType => TreatAsType ?? FieldType; public PropertyInfo PropertyInfo { get; set; } @@ -40,15 +37,19 @@ public Type ColumnType public bool AutoIncrement { get; set; } + public bool AutoId { get; set; } + public bool IsNullable { get; set; } public bool IsIndexed { get; set; } - public bool IsUnique { get; set; } + public bool IsUniqueIndex { get; set; } public bool IsClustered { get; set; } public bool IsNonClustered { get; set; } + + public string IndexName { get; set; } public bool IsRowVersion { get; set; } @@ -58,21 +59,48 @@ public Type ColumnType public string DefaultValue { get; set; } + public string CheckConstraint { get; set; } + + public bool IsUniqueConstraint { get; set; } + + public int Order { get; set; } + public ForeignKeyConstraint ForeignKey { get; set; } - public PropertyGetterDelegate GetValueFn { get; set; } + public GetMemberDelegate GetValueFn { get; set; } - public PropertySetterDelegate SetValueFn { get; set; } + public SetMemberDelegate SetValueFn { get; set; } - public object GetValue(object onInstance) + public object GetValue(object instance) { - return this.GetValueFn == null ? null : this.GetValueFn(onInstance); + var type = instance.GetType(); + if (PropertyInfo.DeclaringType?.IsAssignableFrom(type) != true) + { + if (instance is IDictionary d) + return d[Name]; + + var accessor = TypeProperties.Get(type).GetAccessor(Name); + return accessor?.PublicGetter(instance); + } + + return this.GetValueFn?.Invoke(instance); + } + + public void SetValue(object instance, object value) + { + if (instance is IDictionary d) + { + d[Name] = value; + return; + } + + this.SetValueFn?.Invoke(instance, value); } public string GetQuotedName(IOrmLiteDialectProvider dialectProvider) { return IsRowVersion - ? dialectProvider.GetRowVersionColumnName(this) + ? dialectProvider.GetRowVersionSelectColumn(this).ToString() : dialectProvider.GetQuotedColumnName(FieldName); } @@ -85,9 +113,16 @@ public string GetQuotedValue(object fromInstance, IOrmLiteDialectProvider dialec public string Sequence { get; set; } public bool IsComputed { get; set; } + public bool IsPersisted { get; set; } public string ComputeExpression { get; set; } + public string CustomSelect { get; set; } + public string CustomInsert { get; set; } + public string CustomUpdate { get; set; } + + public bool RequiresAlias => Alias != null || CustomSelect != null; + public string BelongToModelName { get; set; } public bool IsReference { get; set; } @@ -96,20 +131,19 @@ public string GetQuotedValue(object fromInstance, IOrmLiteDialectProvider dialec public bool IsRefType { get; set; } - public bool ShouldSkipInsert() - { - return AutoIncrement || IsComputed || IsRowVersion; - } + public bool IgnoreOnUpdate { get; set; } - public bool ShouldSkipUpdate() - { - return IsComputed; - } + public bool IgnoreOnInsert { get; set; } - public bool ShouldSkipDelete() - { - return IsComputed; - } + public bool ReturnOnInsert { get; set; } + + public override string ToString() => Name; + + public bool ShouldSkipInsert() => IgnoreOnInsert || AutoIncrement || (IsComputed && !IsPersisted) || IsRowVersion; + + public bool ShouldSkipUpdate() => IgnoreOnUpdate || (IsComputed && !IsPersisted); + + public bool ShouldSkipDelete() => (IsComputed && !IsPersisted); public bool IsSelfRefField(FieldDefinition fieldDef) { @@ -122,6 +156,48 @@ public bool IsSelfRefField(string name) return (Alias != null && Alias + "Id" == name) || Name + "Id" == name; } + + public FieldDefinition Clone(Action modifier = null) + { + var fieldDef = new FieldDefinition + { + Name = Name, + Alias = Alias, + FieldType = FieldType, + FieldTypeDefaultValue = FieldTypeDefaultValue, + TreatAsType = TreatAsType, + PropertyInfo = PropertyInfo, + IsPrimaryKey = IsPrimaryKey, + AutoIncrement = AutoIncrement, + AutoId = AutoId, + IsNullable = IsNullable, + IsIndexed = IsIndexed, + IsUniqueIndex = IsUniqueIndex, + IsClustered = IsClustered, + IsNonClustered = IsNonClustered, + IsRowVersion = IsRowVersion, + FieldLength = FieldLength, + Scale = Scale, + DefaultValue = DefaultValue, + CheckConstraint = CheckConstraint, + IsUniqueConstraint = IsUniqueConstraint, + ForeignKey = ForeignKey, + GetValueFn = GetValueFn, + SetValueFn = SetValueFn, + Sequence = Sequence, + IsComputed = IsComputed, + IsPersisted = IsPersisted, + ComputeExpression = ComputeExpression, + CustomSelect = CustomSelect, + BelongToModelName = BelongToModelName, + IsReference = IsReference, + CustomFieldDefinition = CustomFieldDefinition, + IsRefType = IsRefType, + }; + + modifier?.Invoke(fieldDef); + return fieldDef; + } } public class ForeignKeyConstraint @@ -139,22 +215,22 @@ public ForeignKeyConstraint(Type type, string onDelete = null, string onUpdate = public string OnUpdate { get; private set; } public string ForeignKeyName { get; private set; } - public string GetForeignKeyName(ModelDefinition modelDef, ModelDefinition refModelDef, INamingStrategy NamingStrategy, FieldDefinition fieldDef) + public string GetForeignKeyName(ModelDefinition modelDef, ModelDefinition refModelDef, INamingStrategy namingStrategy, FieldDefinition fieldDef) { if (ForeignKeyName.IsNullOrEmpty()) { var modelName = modelDef.IsInSchema - ? modelDef.Schema + "_" + NamingStrategy.GetTableName(modelDef.ModelName) - : NamingStrategy.GetTableName(modelDef.ModelName); + ? $"{modelDef.Schema}_{namingStrategy.GetTableName(modelDef.ModelName)}" + : namingStrategy.GetTableName(modelDef.ModelName); var refModelName = refModelDef.IsInSchema - ? refModelDef.Schema + "_" + NamingStrategy.GetTableName(refModelDef.ModelName) - : NamingStrategy.GetTableName(refModelDef.ModelName); + ? $"{refModelDef.Schema}_{namingStrategy.GetTableName(refModelDef.ModelName)}" + : namingStrategy.GetTableName(refModelDef.ModelName); - var fkName = string.Format("FK_{0}_{1}_{2}", modelName, refModelName, fieldDef.FieldName); - return NamingStrategy.ApplyNameRestrictions(fkName); + var fkName = $"FK_{modelName}_{refModelName}_{fieldDef.FieldName}"; + return namingStrategy.ApplyNameRestrictions(fkName); } - else { return ForeignKeyName; } + return ForeignKeyName; } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/IOrmLiteConverter.cs b/src/ServiceStack.OrmLite/IOrmLiteConverter.cs new file mode 100644 index 000000000..427089ec6 --- /dev/null +++ b/src/ServiceStack.OrmLite/IOrmLiteConverter.cs @@ -0,0 +1,156 @@ +using System; +using System.Data; +using ServiceStack.Logging; + +namespace ServiceStack.OrmLite +{ + public interface IOrmLiteConverter + { + IOrmLiteDialectProvider DialectProvider { get; set; } + + DbType DbType { get; } + + string ColumnDefinition { get; } + + string ToQuotedString(Type fieldType, object value); + + void InitDbParam(IDbDataParameter p, Type fieldType); + + object ToDbValue(Type fieldType, object value); + + object FromDbValue(Type fieldType, object value); + + object GetValue(IDataReader reader, int columnIndex, object[] values); + } + + public interface IHasColumnDefinitionLength + { + string GetColumnDefinition(int? length); + } + + public interface IHasColumnDefinitionPrecision + { + string GetColumnDefinition(int? precision, int? scale); + } + + public abstract class OrmLiteConverter : IOrmLiteConverter + { + public static ILog Log = LogManager.GetLogger(typeof(OrmLiteConverter)); + + /// + /// RDBMS Dialect this Converter is for. Injected at registration. + /// + public IOrmLiteDialectProvider DialectProvider { get; set; } + + /// + /// SQL Column Definition used in CREATE Table. + /// + public abstract string ColumnDefinition { get; } + + /// + /// Used in DB Params. Defaults to DbType.String + /// + public virtual DbType DbType => DbType.String; + + /// + /// Quoted Value in SQL Statement + /// + public virtual string ToQuotedString(Type fieldType, object value) + { + return DialectProvider.GetQuotedValue(value.ToString()); + } + + /// + /// Customize how DB Param is initialized. Useful for supporting RDBMS-specific Types. + /// + public virtual void InitDbParam(IDbDataParameter p, Type fieldType) + { + p.DbType = DbType; + } + + /// + /// Parameterized value in parameterized queries + /// + public virtual object ToDbValue(Type fieldType, object value) + { + return value; + } + + /// + /// Value from DB to Populate on POCO Data Model with + /// + public virtual object FromDbValue(Type fieldType, object value) + { + return value; + } + + /// + /// Retrieve Value from ADO.NET IDataReader. Defaults to reader.GetValue() + /// + public virtual object GetValue(IDataReader reader, int columnIndex, object[] values) + { + var value = values != null + ? values[columnIndex] + : reader.GetValue(columnIndex); + + return value == DBNull.Value ? null : value; + } + } + + /// + /// For Types that are natively supported by RDBMS's and shouldn't be quoted + /// + public abstract class NativeValueOrmLiteConverter : OrmLiteConverter + { + public override string ToQuotedString(Type fieldType, object value) + { + return value.ToString(); + } + } + + public static class OrmLiteConverterExtensions + { + public static object ConvertNumber(this IOrmLiteConverter converter, Type toIntegerType, object value) + { + return converter.DialectProvider.ConvertNumber(toIntegerType, value); + } + + public static object ConvertNumber(this IOrmLiteDialectProvider dialectProvider, Type toIntegerType, object value) + { + if (value.GetType() == toIntegerType) + return value; + + var typeCode = toIntegerType.GetUnderlyingTypeCode(); + switch (typeCode) + { + case TypeCode.Byte: + return Convert.ToByte(value); + case TypeCode.SByte: + return Convert.ToSByte(value); + case TypeCode.Int16: + return Convert.ToInt16(value); + case TypeCode.UInt16: + return Convert.ToUInt16(value); + case TypeCode.Int32: + return Convert.ToInt32(value); + case TypeCode.UInt32: + return Convert.ToUInt32(value); + case TypeCode.Int64: + return Convert.ToInt64(value); + case TypeCode.UInt64: + if (value is byte[] byteValue) + return OrmLiteUtils.ConvertToULong(byteValue); + return Convert.ToUInt64(value); + case TypeCode.Single: + return Convert.ToSingle(value); + case TypeCode.Double: + return Convert.ToDouble(value); + case TypeCode.Decimal: + return Convert.ToDecimal(value); + } + + var convertedValue = dialectProvider.StringSerializer.DeserializeFromString(value.ToString(), toIntegerType); + return convertedValue; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/IOrmLiteDialectProvider.cs b/src/ServiceStack.OrmLite/IOrmLiteDialectProvider.cs index e69003166..52cd3c0dc 100644 --- a/src/ServiceStack.OrmLite/IOrmLiteDialectProvider.cs +++ b/src/ServiceStack.OrmLite/IOrmLiteDialectProvider.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // @@ -15,26 +15,47 @@ using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using ServiceStack.OrmLite.Converters; using ServiceStack.Text; namespace ServiceStack.OrmLite { public interface IOrmLiteDialectProvider { + void RegisterConverter(IOrmLiteConverter converter); + + /// + /// Invoked when a DB Connection is opened + /// + Action OnOpenConnection { get; set; } + + IOrmLiteExecFilter ExecFilter { get; set; } - int DefaultStringLength { get; set; } + /// + /// Gets the explicit Converter registered for a specific type + /// + IOrmLiteConverter GetConverter(Type type); + + /// + /// Return best matching converter, falling back to Enum, Value or Ref Type Converters + /// + IOrmLiteConverter GetConverterBestMatch(Type type); + + IOrmLiteConverter GetConverterBestMatch(FieldDefinition fieldDef); string ParamString { get; set; } - bool UseUnicode { get; set; } - string EscapeWildcards(string value); INamingStrategy NamingStrategy { get; set; } IStringSerializer StringSerializer { get; set; } + Func ParamNameFilter { get; set; } + + Dictionary Variables { get; } + /// /// Quote the string so that it can be used inside an SQL-expression /// Escape quotes inside the string @@ -43,60 +64,109 @@ public interface IOrmLiteDialectProvider /// string GetQuotedValue(string paramValue); - void SetDbValue(FieldDefinition fieldDef, IDataReader reader, int colIndex, object instance); + string GetQuotedValue(object value, Type fieldType); - object ConvertDbValue(object value, Type type); + string GetDefaultValue(Type tableType, string fieldName); - string GetQuotedValue(object value, Type fieldType); + string GetDefaultValue(FieldDefinition fieldDef); + + bool HasInsertReturnValues(ModelDefinition modelDef); + + object GetParamValue(object value, Type fieldType); + + // Customize DB Parameters in SELECT or WHERE queries + void InitQueryParam(IDbDataParameter param); + + // Customize UPDATE or INSERT DB Parameters + void InitUpdateParam(IDbDataParameter param); + + object ToDbValue(object value, Type type); + + object FromDbValue(object value, Type type); + + object GetValue(IDataReader reader, int columnIndex, Type type); + + int GetValues(IDataReader reader, object[] values); IDbConnection CreateConnection(string filePath, Dictionary options); + string GetTableName(ModelDefinition modelDef); + + string GetTableName(ModelDefinition modelDef, bool useStrategy); + + string GetTableName(string table, string schema = null); + string GetTableName(string table, string schema, bool useStrategy); + string GetQuotedTableName(ModelDefinition modelDef); string GetQuotedTableName(string tableName, string schema=null); + string GetQuotedTableName(string tableName, string schema, bool useStrategy); + string GetQuotedColumnName(string columnName); - string GetQuotedName(string columnName); + string GetQuotedName(string name); + string GetQuotedName(string name, string schema); string SanitizeFieldNameForParamName(string fieldName); - string GetColumnDefinition( - string fieldName, Type fieldType, bool isPrimaryKey, bool autoIncrement, - bool isNullable, - bool isRowVersion, - int? fieldLength, - int? scale, - string defaultValue, - string customFieldDefinition); + string GetColumnDefinition(FieldDefinition fieldDef); long GetLastInsertId(IDbCommand command); - long InsertAndGetLastInsertId(IDbCommand dbCmd); + string GetLastInsertIdSqlSuffix(); string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams); - string ToSelectStatement(ModelDefinition modelDef, string selectExpression, string bodyExpression, string orderByExpression = null, int? offset = null, int? rows = null); + string ToSelectStatement( + QueryType queryType, + ModelDefinition modelDef, + string selectExpression, + string bodyExpression, + string orderByExpression = null, + int? offset = null, + int? rows = null, + ISet tags=null); - string ToInsertRowStatement(IDbCommand command, object objWithProperties, ICollection InsertFields = null); + string ToInsertRowStatement(IDbCommand cmd, object objWithProperties, ICollection insertFields = null); - void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null); + void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null, Func shouldInclude=null); + /// If had RowVersion bool PrepareParameterizedUpdateStatement(IDbCommand cmd, ICollection updateFields = null); - bool PrepareParameterizedDeleteStatement(IDbCommand cmd, IDictionary delteFieldValues); + /// If had RowVersion + bool PrepareParameterizedDeleteStatement(IDbCommand cmd, IDictionary deleteFieldValues); void PrepareStoredProcedureStatement(IDbCommand cmd, T obj); void SetParameterValues(IDbCommand dbCmd, object obj); + void SetParameter(FieldDefinition fieldDef, IDbDataParameter p); + + void EnableIdentityInsert(IDbCommand cmd); + Task EnableIdentityInsertAsync(IDbCommand cmd, CancellationToken token=default); + void DisableIdentityInsert(IDbCommand cmd); + Task DisableIdentityInsertAsync(IDbCommand cmd, CancellationToken token=default); + + void EnableForeignKeysCheck(IDbCommand cmd); + Task EnableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token=default); + void DisableForeignKeysCheck(IDbCommand cmd); + Task DisableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token=default); + Dictionary GetFieldDefinitionMap(ModelDefinition modelDef); object GetFieldValue(FieldDefinition fieldDef, object value); + object GetFieldValue(Type fieldType, object value); + + void PrepareUpdateRowStatement(IDbCommand dbCmd, object objWithProperties, ICollection updateFields = null); - string ToUpdateRowStatement(object objWithProperties, ICollection UpdateFields = null); + void PrepareUpdateRowStatement(IDbCommand dbCmd, Dictionary args, string sqlFilter); + + void PrepareUpdateRowAddStatement(IDbCommand dbCmd, Dictionary args, string sqlFilter); + + void PrepareInsertRowStatement(IDbCommand dbCmd, Dictionary args); - string ToDeleteRowStatement(object objWithProperties); string ToDeleteStatement(Type tableType, string sqlFilter, params object[] filterParams); IDbCommand CreateParameterizedDeleteStatement(IDbConnection connection, object objWithProperties); @@ -113,6 +183,7 @@ string ToSelectFromProcedureStatement(object fromObjWithProperties, string ToExecuteProcedureStatement(object objWithProperties); + string ToCreateSchemaStatement(string schema); string ToCreateTableStatement(Type tableType); string ToPostCreateTableStatement(ModelDefinition modelDef); string ToPostDropTableStatement(ModelDefinition modelDef); @@ -122,19 +193,32 @@ string ToSelectFromProcedureStatement(object fromObjWithProperties, string ToCreateSequenceStatement(Type tableType, string sequenceName); List SequenceList(Type tableType); - + Task> SequenceListAsync(Type tableType, CancellationToken token=default); + + bool DoesSchemaExist(IDbCommand dbCmd, string schema); + Task DoesSchemaExistAsync(IDbCommand dbCmd, string schema, CancellationToken token=default); bool DoesTableExist(IDbConnection db, string tableName, string schema = null); + Task DoesTableExistAsync(IDbConnection db, string tableName, string schema = null, CancellationToken token=default); bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null); + Task DoesTableExistAsync(IDbCommand dbCmd, string tableName, string schema = null, CancellationToken token=default); + bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null); + Task DoesColumnExistAsync(IDbConnection db, string columnName, string tableName, string schema = null, CancellationToken token=default); + bool DoesSequenceExist(IDbCommand dbCmd, string sequenceName); + Task DoesSequenceExistAsync(IDbCommand dbCmd, string sequenceName, CancellationToken token=default); + + void DropColumn(IDbConnection db, Type modelType, string columnName); + + object FromDbRowVersion(Type fieldType, object value); - bool DoesSequenceExist(IDbCommand dbCmd, string sequencName); + SelectItem GetRowVersionSelectColumn(FieldDefinition field, string tablePrefix = null); + string GetRowVersionColumn(FieldDefinition field, string tablePrefix = null); - string GetRowVersionColumnName(FieldDefinition field); string GetColumnNames(ModelDefinition modelDef); + SelectItem[] GetColumnNames(ModelDefinition modelDef, string tablePrefix); SqlExpression SqlExpression(); - DbType GetColumnDbType(Type valueType); - string GetColumnTypeDefinition(Type fieldType); + IDbDataParameter CreateParam(); //DDL string GetDropForeignKeyConstraints(ModelDefinition modelDef); @@ -151,18 +235,49 @@ string ToCreateIndexStatement(Expression> field, string indexName = null, bool unique = false); //Async - Task OpenAsync(IDbConnection db, CancellationToken token = default(CancellationToken)); - Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken)); - Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken)); - Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken)); - Task ReadAsync(IDataReader reader, CancellationToken token = default(CancellationToken)); - Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = default(CancellationToken)); - Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = default(CancellationToken)); - Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = default(CancellationToken)); + Task OpenAsync(IDbConnection db, CancellationToken token = default); + Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default); + Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default); + Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default); + Task ReadAsync(IDataReader reader, CancellationToken token = default); + Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = default); + Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = default); + Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = default); Task InsertAndGetLastInsertIdAsync(IDbCommand dbCmd, CancellationToken token); - string GetLoadChildrenSubSelect(ModelDefinition modelDef, SqlExpression expr); + string GetLoadChildrenSubSelect(SqlExpression expr); string ToRowCountStatement(string innerSql); + + string ToUpdateStatement(IDbCommand dbCmd, T item, ICollection updateFields = null); + string ToInsertStatement(IDbCommand dbCmd, T item, ICollection insertFields = null); + string MergeParamsIntoSql(string sql, IEnumerable dbParams); + + string ToTableNamesStatement(string schema); + + /// + /// Return table, row count SQL for listing all tables with their row counts + /// + /// If true returns live current row counts of each table (slower), otherwise returns cached row counts from RDBMS table stats + /// The table schema if any + /// + string ToTableNamesWithRowCountsStatement(bool live, string schema); + + string SqlConflict(string sql, string conflictResolution); + + string SqlConcat(IEnumerable args); + string SqlCurrency(string fieldOrValue); + string SqlCurrency(string fieldOrValue, string currencySymbol); + string SqlBool(bool value); + string SqlLimit(int? offset = null, int? rows = null); + string SqlCast(object fieldOrValue, string castAs); + string SqlRandom { get; } + + /// + /// Generates a SQL comment. + /// + /// The comment text. + /// The generated SQL. + string GenerateComment(in string text); } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/IPropertyInvoker.cs b/src/ServiceStack.OrmLite/IPropertyInvoker.cs index e5bafc728..4dfedbd9b 100644 --- a/src/ServiceStack.OrmLite/IPropertyInvoker.cs +++ b/src/ServiceStack.OrmLite/IPropertyInvoker.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // diff --git a/src/ServiceStack.OrmLite/IUntypedApi.cs b/src/ServiceStack.OrmLite/IUntypedApi.cs index 088fea6fe..dccfbbbe0 100644 --- a/src/ServiceStack.OrmLite/IUntypedApi.cs +++ b/src/ServiceStack.OrmLite/IUntypedApi.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Data; using System.Threading; @@ -16,9 +17,12 @@ public interface IUntypedApi Task SaveAsync(object obj, CancellationToken token); void InsertAll(IEnumerable objs); + void InsertAll(IEnumerable objs, Action commandFilter); long Insert(object obj, bool selectIdentity = false); + long Insert(object obj, Action commandFilter, bool selectIdentity = false); int UpdateAll(IEnumerable objs); + int UpdateAll(IEnumerable objs, Action commandFilter); int Update(object obj); int DeleteAll(); diff --git a/src/ServiceStack.OrmLite/IndexFieldsCacheKey.cs b/src/ServiceStack.OrmLite/IndexFieldsCacheKey.cs new file mode 100644 index 000000000..5ca47f3ac --- /dev/null +++ b/src/ServiceStack.OrmLite/IndexFieldsCacheKey.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Data; + +namespace ServiceStack.OrmLite +{ + public class IndexFieldsCacheKey + { + int hashCode; + + public ModelDefinition ModelDefinition { get; private set; } + + public IOrmLiteDialectProvider Dialect { get; private set; } + + public List Fields { get; private set; } + + public IndexFieldsCacheKey(IDataReader reader, ModelDefinition modelDefinition, IOrmLiteDialectProvider dialect) + { + ModelDefinition = modelDefinition; + Dialect = dialect; + + int startPos = 0; + int endPos = reader.FieldCount; + + Fields = new List(endPos - startPos); + + for (int i = startPos; i < endPos; i++) + Fields.Add(reader.GetName(i)); + + unchecked + { + hashCode = 17; + hashCode = hashCode * 23 + ModelDefinition.GetHashCode(); + hashCode = hashCode * 23 + Dialect.GetHashCode(); + hashCode = hashCode * 23 + Fields.Count; + for (int i = 0; i < Fields.Count; i++) + hashCode = hashCode * 23 + Fields[i].Length; + } + } + + public override bool Equals (object obj) + { + var that = obj as IndexFieldsCacheKey; + + if (obj == null) return false; + + return this.ModelDefinition == that.ModelDefinition + && this.Dialect == that.Dialect + && this.Fields.Count == that.Fields.Count + && this.Fields.SequenceEqual(that.Fields); + } + + public override int GetHashCode() + { + return hashCode; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteReadApiAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadApiAsyncLegacy.cs new file mode 100644 index 000000000..bd870b6ac --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadApiAsyncLegacy.cs @@ -0,0 +1,171 @@ +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. +// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Legacy +{ + public static class OrmLiteReadApiAsyncLegacy + { + /// + /// Returns results from using an SqlFormat query. E.g: + /// db.SelectFmt<Person>("Age > {0}", 40) + /// db.SelectFmt<Person>("SELECT * FROM Person WHERE Age > {0}", 40) + /// + [Obsolete(Messages.LegacyApi)] + public static Task> SelectFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(token, sqlFormat, filterParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task> SelectFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(default(CancellationToken), sqlFormat, filterParams)); + } + + /// + /// Returns a partial subset of results from the specified tableType using a SqlFormat query. E.g: + /// db.SelectFmt<EntityWithId>(typeof(Person), "Age > {0}", 40) + /// + [Obsolete(Messages.LegacyApi)] + public static Task> SelectFmtAsync(this IDbConnection dbConn, CancellationToken token, Type fromTableType, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(token, fromTableType, sqlFormat, filterParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task> SelectFmtAsync(this IDbConnection dbConn, Type fromTableType, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(default(CancellationToken), fromTableType, sqlFormat, filterParams)); + } + + /// + /// Returns a single scalar value using an SqlFormat query. E.g: + /// db.ScalarFmt<int>("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40) + /// + [Obsolete(Messages.LegacyApi)] + public static Task ScalarFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ScalarFmtAsync(token, sqlFormat, sqlParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task ScalarFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ScalarFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + } + + /// + /// Returns the first column in a List using a SqlFormat query. E.g: + /// db.ColumnFmt<string>("SELECT LastName FROM Person WHERE Age = {0}", 27) + /// + [Obsolete(Messages.LegacyApi)] + public static Task> ColumnFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ColumnFmtAsync(token, sqlFormat, sqlParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task> ColumnFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ColumnFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + } + + /// + /// Returns the distinct first column values in a HashSet using an SqlFormat query. E.g: + /// db.ColumnDistinctFmt<int>("SELECT Age FROM Person WHERE Age < {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static Task> ColumnDistinctFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctFmtAsync(token, sqlFormat, sqlParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task> ColumnDistinctFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + } + + /// + /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an SqlFormat query. E.g: + /// db.LookupFmt<int, string>("SELECT Age, LastName FROM Person WHERE Age < {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static Task>> LookupFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.LookupFmtAsync(token, sqlFormat, sqlParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task>> LookupFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.LookupFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + } + + /// + /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlFormat query. E.g: + /// db.DictionaryFmt<int, string>("SELECT Id, LastName FROM Person WHERE Age < {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static Task> DictionaryFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.DictionaryFmtAsync(token, sqlFormat, sqlParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task> DictionaryFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.DictionaryFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + } + + /// + /// Returns true if the Query returns any records, using an SqlFormat query. E.g: + /// db.ExistsFmt<Person>("Age = {0}", 42) + /// db.ExistsFmt<Person>("SELECT * FROM Person WHERE Age = {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static Task ExistsFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.ExistsFmtAsync(token, sqlFormat, filterParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task ExistsFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.ExistsFmtAsync(default(CancellationToken), sqlFormat, filterParams)); + } + + /// + /// Returns true if the Query returns any records that match the SqlExpression lambda, E.g: + /// db.Exists<Person>(q => q.Where(x => x.Age < 50)) + /// + [Obsolete("Use db.ExistsAsync(db.From())")] + public static Task ExistsAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + var sql = expression(q).Limit(1); + return dbCmd.SingleAsync(sql, token).Then(x => x != null); + }); + } + + /// + /// Returns results from a Stored Procedure using an SqlFormat query. E.g: + /// + /// + [Obsolete(Messages.LegacyApi)] + public static Task> SqlProcedureFmtAsync(this IDbConnection dbConn, CancellationToken token, + object anonType, + string sqlFilter, + params object[] filterParams) + where TOutputModel : new() + { + return dbConn.Exec(dbCmd => dbCmd.SqlProcedureFmtAsync(token, + anonType, sqlFilter, filterParams)); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteReadApiLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadApiLegacy.cs new file mode 100644 index 000000000..362aaa18d --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadApiLegacy.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + public static class OrmLiteReadApiLegacy + { + /// + /// Returns results from using an SqlFormat query. E.g: + /// db.SelectFmt<Person>("Age > {0}", 40) + /// db.SelectFmt<Person>("SELECT * FROM Person WHERE Age > {0}", 40) + /// + [Obsolete(Messages.LegacyApi)] + public static List SelectFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SelectFmt(sqlFormat, filterParams)); + } + + /// + /// Returns a partial subset of results from the specified tableType using a SqlFormat query. E.g: + /// db.SelectFmt<EntityWithId>(typeof(Person), "Age > {0}", 40) + /// + [Obsolete(Messages.LegacyApi)] + public static List SelectFmt(this IDbConnection dbConn, Type fromTableType, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SelectFmt(fromTableType, sqlFormat, filterParams)); + } + + /// + /// Returns a lazyily loaded stream of results using an SqlFilter query. E.g: + /// db.SelectLazyFmt<Person>("Age > {0}", 40) + /// + [Obsolete(Messages.LegacyApi)] + public static IEnumerable SelectLazyFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + { + return dbConn.ExecLazy(dbCmd => dbCmd.SelectLazyFmt(sqlFormat, filterParams)); + } + + /// + /// Returns the first result using a SqlFormat query. E.g: + /// db.SingleFmt<Person>("Age = {0}", 42) + /// + [Obsolete(Messages.LegacyApi)] + public static T SingleFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SingleFmt(sqlFormat, filterParams)); + } + + /// + /// Returns a single scalar value using an SqlFormat query. E.g: + /// db.ScalarFmt<int>("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40) + /// + [Obsolete(Messages.LegacyApi)] + public static T ScalarFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ScalarFmt(sqlFormat, sqlParams)); + } + + /// + /// Returns the first column in a List using a SqlFormat query. E.g: + /// db.ColumnFmt<string>("SELECT LastName FROM Person WHERE Age = {0}", 27) + /// + [Obsolete(Messages.LegacyApi)] + public static List ColumnFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ColumnFmt(sqlFormat, sqlParams)); + } + + /// + /// Returns the distinct first column values in a HashSet using an SqlFormat query. E.g: + /// db.ColumnDistinctFmt<int>("SELECT Age FROM Person WHERE Age < {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static HashSet ColumnDistinctFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctFmt(sqlFormat, sqlParams)); + } + + /// + /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an SqlFormat query. E.g: + /// db.LookupFmt<int, string>("SELECT Age, LastName FROM Person WHERE Age < {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static Dictionary> LookupFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.LookupFmt(sqlFormat, sqlParams)); + } + + /// + /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlFormat query. E.g: + /// db.DictionaryFmt<int, string>("SELECT Id, LastName FROM Person WHERE Age < {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static Dictionary DictionaryFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.DictionaryFmt(sqlFormat, sqlParams)); + } + + /// + /// Returns true if the Query returns any records, using an SqlFormat query. E.g: + /// db.ExistsFmt<Person>("Age = {0}", 42) + /// db.ExistsFmt<Person>("SELECT * FROM Person WHERE Age = {0}", 50) + /// + [Obsolete(Messages.LegacyApi)] + public static bool ExistsFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.ExistsFmt(sqlFormat, filterParams)); + } + + /// + /// Returns true if the Query returns any records that match the SqlExpression lambda, E.g: + /// db.Exists<Person>(q => q.Where(x => x.Age < 50)) + /// + [Obsolete("Use db.Exists(db.From())")] + public static bool Exists(this IDbConnection dbConn, Func, SqlExpression> expression) + { + return dbConn.Exec(dbCmd => + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + return dbCmd.Scalar(expression(q).Limit(1).Select("'exists'")) != null; + }); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteReadCommandExtensionsAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadCommandExtensionsAsyncLegacy.cs new file mode 100644 index 000000000..02a86dc91 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadCommandExtensionsAsyncLegacy.cs @@ -0,0 +1,79 @@ +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. +// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + internal static class OrmLiteReadCommandExtensionsAsyncLegacy + { + internal static Task SingleFmtAsync(this IDbCommand dbCmd, CancellationToken token, string filter, params object[] filterParams) + { + return dbCmd.ConvertToAsync(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), filter, filterParams), token); + } + + internal static Task> SelectFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFilter, params object[] filterParams) + { + return dbCmd.ConvertToListAsync( + dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sqlFilter, filterParams), token); + } + + internal static Task> SelectFmtAsync(this IDbCommand dbCmd, CancellationToken token, Type fromTableType, string sqlFilter, params object[] filterParams) + { + var sql = OrmLiteReadCommandExtensionsLegacy.ToSelectFmt(dbCmd.GetDialectProvider(), fromTableType, sqlFilter, filterParams); + return dbCmd.ConvertToListAsync(sql, token); + } + + internal static Task ScalarFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) + { + return dbCmd.ScalarAsync(sql.SqlFmt(sqlParams), token); + } + + internal static Task> ColumnFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) + { + return dbCmd.ColumnAsync(sql.SqlFmt(sqlParams), token); + } + + internal static Task> ColumnDistinctFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) + { + return dbCmd.ColumnDistinctAsync(sql.SqlFmt(sqlParams), token); + } + + internal static Task>> LookupFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sql, params object[] sqlParams) + { + return dbCmd.LookupAsync(sql.SqlFmt(sqlParams), token); + } + + internal static Task> DictionaryFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFormat, params object[] sqlParams) + { + return dbCmd.DictionaryAsync(sqlFormat.SqlFmt(sqlParams), token); + } + + internal static Task ExistsFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFilter, params object[] filterParams) + { + var fromTableType = typeof(T); + return dbCmd.ScalarAsync(dbCmd.GetDialectProvider().ToSelectStatement(fromTableType, sqlFilter, filterParams), token) + .Then(x => x != null); + } + + internal static Task DeleteFmtAsync(this IDbCommand dbCmd, CancellationToken token, string sqlFilter, params object[] filterParams) + { + return DeleteFmtAsync(dbCmd, token, typeof(T), sqlFilter, filterParams); + } + + internal static Task DeleteFmtAsync(this IDbCommand dbCmd, CancellationToken token, Type tableType, string sqlFilter, params object[] filterParams) + { + var dialectProvider = dbCmd.GetDialectProvider(); + return dbCmd.ExecuteSqlAsync(dialectProvider.ToDeleteStatement(tableType, sqlFilter, filterParams), token); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteReadCommandExtensionsLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadCommandExtensionsLegacy.cs new file mode 100644 index 000000000..93734f129 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadCommandExtensionsLegacy.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Data; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + internal static class OrmLiteReadCommandExtensionsLegacy + { + internal static List SelectFmt(this IDbCommand dbCmd, string sqlFilter, params object[] filterParams) + { + return dbCmd.ConvertToList( + dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sqlFilter, filterParams)); + } + + internal static List SelectFmt(this IDbCommand dbCmd, Type fromTableType, string sqlFilter, params object[] filterParams) + { + var sql = ToSelectFmt(dbCmd.GetDialectProvider(), fromTableType, sqlFilter, filterParams); + + return dbCmd.ConvertToList(sql); + } + + internal static string ToSelectFmt(IOrmLiteDialectProvider dialectProvider, Type fromTableType, string sqlFilter, object[] filterParams) + { + var sql = StringBuilderCache.Allocate(); + var modelDef = ModelDefinition.Definition; + sql.AppendFormat("SELECT {0} FROM {1}", dialectProvider.GetColumnNames(modelDef), + dialectProvider.GetQuotedTableName(fromTableType.GetModelDefinition())); + if (!string.IsNullOrEmpty(sqlFilter)) + { + sqlFilter = sqlFilter.SqlFmt(filterParams); + sql.Append(" WHERE "); + sql.Append(sqlFilter); + } + return StringBuilderCache.ReturnAndFree(sql); + } + + internal static IEnumerable SelectLazyFmt(this IDbCommand dbCmd, string filter, params object[] filterParams) + { + var dialectProvider = dbCmd.GetDialectProvider(); + dbCmd.CommandText = dialectProvider.ToSelectStatement(typeof(T), filter, filterParams); + + if (OrmLiteConfig.ResultsFilter != null) + { + foreach (var item in OrmLiteConfig.ResultsFilter.GetList(dbCmd)) + { + yield return item; + } + yield break; + } + + using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) + { + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider); + var values = new object[reader.FieldCount]; + while (reader.Read()) + { + var row = OrmLiteUtils.CreateInstance(); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); + yield return row; + } + } + } + + internal static T SingleFmt(this IDbCommand dbCmd, string filter, params object[] filterParams) + { + return dbCmd.ConvertTo(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), filter, filterParams)); + } + + internal static T ScalarFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) + { + return dbCmd.Scalar(sql.SqlFmt(sqlParams)); + } + + internal static List ColumnFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) + { + return dbCmd.Column(sql.SqlFmt(sqlParams)); + } + + internal static HashSet ColumnDistinctFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) + { + return dbCmd.ColumnDistinct(sql.SqlFmt(sqlParams)); + } + + internal static Dictionary> LookupFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) + { + return dbCmd.Lookup(sql.SqlFmt(sqlParams)); + } + + internal static Dictionary DictionaryFmt(this IDbCommand dbCmd, string sqlFormat, params object[] sqlParams) + { + return dbCmd.Dictionary(sqlFormat.SqlFmt(sqlParams)); + } + + internal static bool ExistsFmt(this IDbCommand dbCmd, string sqlFilter, params object[] filterParams) + { + var fromTableType = typeof(T); + var result = dbCmd.Scalar(dbCmd.GetDialectProvider().ToSelectStatement(fromTableType, sqlFilter, filterParams)); + return result != null; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteReadExpressionsApiAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadExpressionsApiAsyncLegacy.cs new file mode 100644 index 000000000..cde04bdca --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadExpressionsApiAsyncLegacy.cs @@ -0,0 +1,82 @@ +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. +// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt + +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + public static class OrmLiteReadExpressionsApiAsyncLegacy + { + /// + /// Returns results from using an SqlExpression lambda. E.g: + /// db.Select<Person>(q => q.Where(x => x.Age > 40)) + /// + [Obsolete("Use db.SelectAsync(db.From())")] + public static Task> SelectAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.SelectAsync(expression, token)); + } + + /// + /// Project results from a number of joined tables into a different model + /// + [Obsolete("Use db.SelectAsync(db.From())")] + public static Task> SelectAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.SelectAsync(expression, token)); + } + + /// + /// Returns a single result from using an SqlExpression lambda. E.g: + /// db.Single<Person>(q => q.Where(x => x.Age == 42)) + /// + [Obsolete("Use db.SingleAsync(db.From())")] + public static Task SingleAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.SingleAsync(expression, token)); + } + + /// + /// Returns the first result using a SqlFormat query. E.g: + /// db.SingleFmt<Person>("Age = {0}", 42) + /// + [Obsolete("Use db.SingleAsync(\"Age = @age\", new { age = 42 })")] + public static Task SingleFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SingleFmtAsync(token, sqlFormat, filterParams)); + } + [Obsolete("Use db.SingleAsync(\"Age = @age\", new { age = 42 })")] + public static Task SingleFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.SingleFmtAsync(default(CancellationToken), sqlFormat, filterParams)); + } + + /// + /// Returns the count of rows that match the SqlExpression lambda, E.g: + /// db.Count<Person>(q => q.Where(x => x.Age < 50)) + /// + [Obsolete("Use db.CountAsync(db.From())")] + public static Task CountAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token)); + } + + /// + /// Returns results with references from using an SqlExpression lambda. E.g: + /// db.LoadSelectAsync<Person>(q => q.Where(x => x.Age > 40)) + /// + [Obsolete("Use db.LoadSelectAsync(db.From())")] + public static Task> LoadSelectAsync(this IDbConnection dbConn, Func, SqlExpression> expression, string[] include = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression, include, token)); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteReadExpressionsApiLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadExpressionsApiLegacy.cs new file mode 100644 index 000000000..52308eaa8 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteReadExpressionsApiLegacy.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + public static class OrmLiteReadExpressionsApiLegacy + { + /// + /// Create a new SqlExpression builder allowing typed LINQ-like queries. + /// + [Obsolete("Use From")] + public static SqlExpression SqlExpression(this IDbConnection dbConn) + { + return dbConn.GetExecFilter().SqlExpression(dbConn); + } + + /// + /// Returns results from using an SqlExpression lambda. E.g: + /// db.Select<Person>(q => q.Where(x => x.Age > 40)) + /// + [Obsolete("Use db.Select(db.From())")] + public static List Select(this IDbConnection dbConn, Func, SqlExpression> expression) + { + return dbConn.Exec(dbCmd => dbCmd.Select(expression)); + } + + /// + /// Project results from a number of joined tables into a different model + /// + [Obsolete("Use db.Select(db.From())")] + public static List Select(this IDbConnection dbConn, SqlExpression expression) + { + return dbConn.Exec(dbCmd => dbCmd.Select(expression)); + } + + /// + /// Project results from a number of joined tables into a different model + /// + [Obsolete("Use db.Select(db.From())")] + public static List Select(this IDbConnection dbConn, Func, SqlExpression> expression) + { + return dbConn.Exec(dbCmd => dbCmd.Select(expression)); + } + + /// + /// Returns a single result from using an SqlExpression lambda. E.g: + /// db.Single<Person>(q => q.Where(x => x.Age == 42)) + /// + [Obsolete("Use db.Single(db.From())")] + public static T Single(this IDbConnection dbConn, Func, SqlExpression> expression) + { + return dbConn.Exec(dbCmd => dbCmd.Single(expression)); + } + + /// + /// Returns the count of rows that match the SqlExpression lambda, E.g: + /// db.Count<Person>(q => q.Where(x => x.Age < 50)) + /// + [Obsolete("Use db.Count(db.From())")] + public static long Count(this IDbConnection dbConn, Func, SqlExpression> expression) + { + return dbConn.Exec(dbCmd => dbCmd.Count(expression)); + } + + /// + /// Returns results with references from using an SqlExpression lambda. E.g: + /// db.LoadSelect<Person>(q => q.Where(x => x.Age > 40)) + /// + [Obsolete("Use db.LoadSelect(db.From())")] + public static List LoadSelect(this IDbConnection dbConn, Func, SqlExpression> expression, IEnumerable include = null) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include)); + } + + /// + /// Returns results with references from using an SqlExpression lambda. E.g: + /// db.LoadSelect<Person>(q => q.Where(x => x.Age > 40), include: x => new { x.PrimaryAddress }) + /// + [Obsolete("Use db.LoadSelect(db.From())")] + public static List LoadSelect(this IDbConnection dbConn, Func, SqlExpression> expression, Func include) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include(typeof(T).CreateInstance()).GetType().AllAnonFields())); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteApiAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteApiAsyncLegacy.cs new file mode 100644 index 000000000..559b7f2ac --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteApiAsyncLegacy.cs @@ -0,0 +1,51 @@ +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. +// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using ServiceStack.Data; + +namespace ServiceStack.OrmLite.Legacy +{ + public static class OrmLiteWriteApiAsyncLegacy + { + /// + /// Delete rows using a SqlFormat filter. E.g: + /// + /// number of rows deleted + [Obsolete(Messages.LegacyApi)] + public static Task DeleteFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFilter, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(token, sqlFilter, filterParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task DeleteFmtAsync(this IDbConnection dbConn, string sqlFilter, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(default(CancellationToken), sqlFilter, filterParams)); + } + + /// + /// Delete rows from the runtime table type using a SqlFormat filter. E.g: + /// + /// db.DeleteFmt(typeof(Person), "Age = {0}", 27) + /// number of rows deleted + [Obsolete(Messages.LegacyApi)] + public static Task DeleteFmtAsync(this IDbConnection dbConn, CancellationToken token, Type tableType, string sqlFilter, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(token, tableType, sqlFilter, filterParams)); + } + [Obsolete(Messages.LegacyApi)] + public static Task DeleteFmtAsync(this IDbConnection dbConn, Type tableType, string sqlFilter, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(default(CancellationToken), tableType, sqlFilter, filterParams)); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteCommandExtensionsAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteCommandExtensionsAsyncLegacy.cs new file mode 100644 index 000000000..09d335728 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteCommandExtensionsAsyncLegacy.cs @@ -0,0 +1,23 @@ +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. +// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using ServiceStack.Data; +using ServiceStack.Logging; + +namespace ServiceStack.OrmLite.Legacy +{ + internal static class OrmLiteWriteCommandExtensionsAsyncLegacy + { + + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteCommandExtensionsLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteCommandExtensionsLegacy.cs new file mode 100644 index 000000000..279d06206 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteCommandExtensionsLegacy.cs @@ -0,0 +1,31 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + public static class OrmLiteWriteCommandExtensionsLegacy + { + /// + /// Delete rows using a SqlFormat filter. E.g: + /// db.Delete<Person>("Age > {0}", 42) + /// + /// number of rows deleted + [Obsolete(Messages.LegacyApi)] + public static int DeleteFmt(this IDbConnection dbConn, string sqlFilter, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(sqlFilter, filterParams)); + } + + /// + /// Delete rows from the runtime table type using a SqlFormat filter. E.g: + /// + /// db.DeleteFmt(typeof(Person), "Age = {0}", 27) + /// number of rows deleted + [Obsolete(Messages.LegacyApi)] + public static int DeleteFmt(this IDbConnection dbConn, Type tableType, string sqlFilter, params object[] filterParams) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(tableType, sqlFilter, filterParams)); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteExpressionsApiAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteExpressionsApiAsyncLegacy.cs new file mode 100644 index 000000000..dec2c542e --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteExpressionsApiAsyncLegacy.cs @@ -0,0 +1,118 @@ +#if ASYNC +using System; +using System.Data; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + public static class OrmLiteWriteExpressionsApiAsyncLegacy + { + /// + /// Insert only fields in POCO specified by the SqlExpression lambda. E.g: + /// db.InsertOnly(new Person { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })) + /// + [Obsolete("Use db.InsertOnlyAsync(obj, db.From())")] + public static Task InsertOnlyAsync(this IDbConnection dbConn, T obj, Func, SqlExpression> onlyFields, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.InsertOnlyAsync(obj, onlyFields, token)); + } + + /// + /// Using an SqlExpression to only Insert the fields specified, e.g: + /// + /// db.InsertOnly(new Person { FirstName = "Amy" }, q => q.Insert(p => new { p.FirstName })); + /// INSERT INTO "Person" ("FirstName") VALUES ('Amy'); + /// + public static Task InsertOnlyAsync(this IDbConnection dbConn, T obj, SqlExpression onlyFields, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.InsertOnlyAsync(obj, onlyFields, token)); + } + + /// + /// Use an SqlExpression to select which fields to update and construct the where expression, E.g: + /// + /// db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') + /// + /// What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: + /// + /// db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); + /// UPDATE "Person" SET "FirstName" = 'JJ' + /// + [Obsolete("Use db.UpdateOnlyAsync(model, db.From())")] + public static Task UpdateOnlyAsync(this IDbConnection dbConn, T model, Func, SqlExpression> onlyFields, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(model, onlyFields, token)); + } + + /// + /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g: + /// + /// db.Update<Person>(set:"FirstName = {0}".Params("JJ"), where:"LastName = {0}".Params("Hendrix")); + /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// + [Obsolete(Messages.LegacyApi)] + public static Task UpdateFmtAsync(this IDbConnection dbConn, string set = null, string where = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateFmtAsync(set, where, token)); + } + + /// + /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g. + /// + /// db.Update(table:"Person", set: "FirstName = {0}".Params("JJ"), where: "LastName = {0}".Params("Hendrix")); + /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// + [Obsolete(Messages.LegacyApi)] + public static Task UpdateFmtAsync(this IDbConnection dbConn, string table = null, string set = null, string where = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateFmtAsync(table, set, where, token)); + } + + /// + /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// + /// db.Delete<Person>(where:"Age = {0}".Params(27)); + /// DELETE FROM "Person" WHERE Age = 27 + /// + [Obsolete(Messages.LegacyApi)] + public static Task DeleteFmtAsync(this IDbConnection dbConn, string where, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(where, token)); + } + [Obsolete(Messages.LegacyApi)] + public static Task DeleteFmtAsync(this IDbConnection dbConn, string where = null) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(where, default(CancellationToken))); + } + + /// + /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// + /// db.Delete(table:"Person", where: "Age = {0}".Params(27)); + /// DELETE FROM "Person" WHERE Age = 27 + /// + [Obsolete(Messages.LegacyApi)] + public static Task DeleteFmtAsync(this IDbConnection dbConn, string table = null, string where = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(table, where, token)); + } + + /// + /// Delete the rows that matches the where expression, e.g: + /// + /// db.Delete<Person>(ev => ev.Where(p => p.Age == 27)); + /// DELETE FROM "Person" WHERE ("Age" = 27) + /// + [Obsolete("Use db.DeleteAsync(db.From())")] + public static Task DeleteAsync(this IDbConnection dbConn, Func, SqlExpression> where, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(where, token)); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteExpressionsApiLegacy.cs b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteExpressionsApiLegacy.cs new file mode 100644 index 000000000..a61facb41 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/OrmLiteWriteExpressionsApiLegacy.cs @@ -0,0 +1,107 @@ +using System; +using System.Data; + +namespace ServiceStack.OrmLite.Legacy +{ + public static class OrmLiteWriteExpressionsApiLegacy + { + /// + /// Insert only fields in POCO specified by the SqlExpression lambda. E.g: + /// db.InsertOnly(new Person { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })) + /// + [Obsolete("Use db.InsertOnly(obj, db.From())")] + public static void InsertOnly(this IDbConnection dbConn, T obj, Func, SqlExpression> onlyFields) + { + dbConn.Exec(dbCmd => dbCmd.InsertOnly(obj, onlyFields)); + } + + /// + /// Use an SqlExpression to select which fields to update and construct the where expression, E.g: + /// + /// db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') + /// + /// What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: + /// + /// db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); + /// UPDATE "Person" SET "FirstName" = 'JJ' + /// + [Obsolete("Use db.UpdateOnly(model, db.From())")] + public static int UpdateOnly(this IDbConnection dbConn, T model, Func, SqlExpression> onlyFields) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(model, onlyFields)); + } + + /// + /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g: + /// + /// db.Update<Person>(set:"FirstName = {0}".Params("JJ"), where:"LastName = {0}".Params("Hendrix")); + /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// + [Obsolete(Messages.LegacyApi)] + public static int UpdateFmt(this IDbConnection dbConn, string set = null, string where = null) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateFmt(set, where)); + } + + /// + /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g. + /// + /// db.Update(table:"Person", set: "FirstName = {0}".Params("JJ"), where: "LastName = {0}".Params("Hendrix")); + /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// + [Obsolete(Messages.LegacyApi)] + public static int UpdateFmt(this IDbConnection dbConn, string table = null, string set = null, string where = null) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateFmt(table, set, where)); + } + + /// + /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// + /// db.Delete<Person>(where:"Age = {0}".Params(27)); + /// DELETE FROM "Person" WHERE Age = 27 + /// + [Obsolete(Messages.LegacyApi)] + public static int DeleteFmt(this IDbConnection dbConn, string where = null) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(where)); + } + + /// + /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// + /// db.Delete(table:"Person", where: "Age = {0}".Params(27)); + /// DELETE FROM "Person" WHERE Age = 27 + /// + [Obsolete(Messages.LegacyApi)] + public static int DeleteFmt(this IDbConnection dbConn, string table = null, string where = null) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(table, where)); + } + + /// + /// Delete the rows that matches the where expression, e.g: + /// + /// db.Delete<Person>(ev => ev.Where(p => p.Age == 27)); + /// DELETE FROM "Person" WHERE ("Age" = 27) + /// + [Obsolete("Use db.Delete(db.From())")] + public static int Delete(this IDbConnection dbConn, Func, SqlExpression> where) + { + return dbConn.Exec(dbCmd => dbCmd.Delete(where)); + } + + /// + /// Using an SqlExpression to only Insert the fields specified, e.g: + /// + /// db.InsertOnly(new Person { FirstName = "Amy" }, q => q.Insert(p => new { p.FirstName })); + /// INSERT INTO "Person" ("FirstName") VALUES ('Amy'); + /// + [Obsolete("Use db.InsertOnly(() => new Person { ... })")] + public static void InsertOnly(this IDbConnection dbConn, T obj, SqlExpression onlyFields) + { + dbConn.Exec(dbCmd => dbCmd.InsertOnly(obj, onlyFields)); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/ReadExpressionCommandExtensionsAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/ReadExpressionCommandExtensionsAsyncLegacy.cs new file mode 100644 index 000000000..52b18b354 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/ReadExpressionCommandExtensionsAsyncLegacy.cs @@ -0,0 +1,57 @@ +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. +// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt + +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + internal static class ReadExpressionCommandExtensionsAsyncLegacy + { + [Obsolete("Use db.SelectAsync(db.From())")] + internal static Task> SelectAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + var sql = expression(q).SelectInto(QueryType.Select); + return dbCmd.ExprConvertToListAsync(sql, q.Params, q.OnlyFields, token); + } + + [Obsolete("Use db.SelectAsync(db.From())")] + internal static Task> SelectAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + string sql = expression(q).SelectInto(QueryType.Select); + return dbCmd.ExprConvertToListAsync(sql, q.Params, q.OnlyFields, token); + } + + [Obsolete("Use db.SingleAsync(db.From())")] + internal static Task SingleAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) + { + var expr = dbCmd.GetDialectProvider().SqlExpression(); + return dbCmd.SingleAsync(expression(expr), token); + } + + [Obsolete("Use db.CountAsync(db.From())")] + internal static Task CountAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, CancellationToken token) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + var sql = expression(q).ToCountStatement(); + return dbCmd.GetCountAsync(sql, q.Params, token); + } + + [Obsolete("Use db.LoadSelectAsync(db.From())")] + internal static Task> LoadSelectAsync(this IDbCommand dbCmd, Func, SqlExpression> expression, string[] include = null, CancellationToken token = default) + { + var expr = dbCmd.GetDialectProvider().SqlExpression(); + expr = expression(expr); + return dbCmd.LoadListWithReferences(expr, include, token); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/ReadExpressionCommandExtensionsLegacy.cs b/src/ServiceStack.OrmLite/Legacy/ReadExpressionCommandExtensionsLegacy.cs new file mode 100644 index 000000000..2d128bb45 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/ReadExpressionCommandExtensionsLegacy.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + internal static class ReadExpressionCommandExtensionsLegacy + { + [Obsolete("Use db.Select(db.From())")] + internal static List Select(this IDbCommand dbCmd, Func, SqlExpression> expression) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + string sql = expression(q).SelectInto(QueryType.Select); + + return dbCmd.ExprConvertToList(sql, q.Params, onlyFields: q.OnlyFields); + } + + [Obsolete("Use db.Select(db.From())")] + internal static List Select(this IDbCommand dbCmd, Func, SqlExpression> expression) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + string sql = expression(q).SelectInto(QueryType.Select); + + return dbCmd.ExprConvertToList(sql, q.Params, onlyFields: q.OnlyFields); + } + + internal static List Select(this IDbCommand dbCmd, SqlExpression q) + { + string sql = q.SelectInto(QueryType.Select); + return dbCmd.ExprConvertToList(sql, q.Params, onlyFields: q.OnlyFields); + } + + [Obsolete("Use db.Single(db.From())")] + internal static T Single(this IDbCommand dbCmd, Func, SqlExpression> expression) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + return dbCmd.Single(expression(q)); + } + + [Obsolete("Use db.Count(db.From())")] + internal static long Count(this IDbCommand dbCmd, Func, SqlExpression> expression) + { + var q = dbCmd.GetDialectProvider().SqlExpression(); + var sql = expression(q).ToCountStatement(); + return dbCmd.GetCount(sql, q.Params); + } + + [Obsolete("Use db.LoadSelect(db.From())")] + internal static List LoadSelect(this IDbCommand dbCmd, Func, SqlExpression> expression, IEnumerable include = null) + { + var expr = dbCmd.GetDialectProvider().SqlExpression(); + expr = expression(expr); + return dbCmd.LoadListWithReferences(expr, include); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/WriteExpressionCommandExtensionsAsyncLegacy.cs b/src/ServiceStack.OrmLite/Legacy/WriteExpressionCommandExtensionsAsyncLegacy.cs new file mode 100644 index 000000000..ecd61b2fd --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/WriteExpressionCommandExtensionsAsyncLegacy.cs @@ -0,0 +1,68 @@ +#if ASYNC +using System; +using System.Data; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + internal static class WriteExpressionCommandExtensionsAsyncLegacy + { + [Obsolete("Use db.InsertOnlyAsync(obj, db.From())")] + internal static Task InsertOnlyAsync(this IDbCommand dbCmd, T obj, Func, SqlExpression> onlyFields, CancellationToken token) + { + return dbCmd.InsertOnlyAsync(obj, onlyFields(dbCmd.GetDialectProvider().SqlExpression()), token); + } + + [Obsolete("Use db.UpdateOnlyAsync(model, db.From())")] + internal static Task UpdateOnlyAsync(this IDbCommand dbCmd, T model, Func, SqlExpression> onlyFields, CancellationToken token) + { + return dbCmd.UpdateOnlyFieldsAsync(model, onlyFields(dbCmd.GetDialectProvider().SqlExpression()), null, token); + } + + internal static Task UpdateFmtAsync(this IDbCommand dbCmd, string set, string where, CancellationToken token) + { + return dbCmd.UpdateFmtAsync(typeof(T).GetModelDefinition().ModelName, set, where, token); + } + + internal static Task UpdateFmtAsync(this IDbCommand dbCmd, string table, string set, string where, CancellationToken token) + { + var sql = WriteExpressionCommandExtensionsLegacy.UpdateFmtSql(dbCmd.GetDialectProvider(), table, set, where); + return dbCmd.ExecuteSqlAsync(sql, token); + } + + [Obsolete("Use db.DeleteAsync(db.From())")] + internal static Task DeleteAsync(this IDbCommand dbCmd, Func, SqlExpression> where, CancellationToken token) + { + return dbCmd.DeleteAsync(where(dbCmd.GetDialectProvider().SqlExpression()), null, token); + } + + internal static Task DeleteFmtAsync(this IDbCommand dbCmd, string where, CancellationToken token) + { + return dbCmd.DeleteFmtAsync(typeof(T).GetModelDefinition().ModelName, where, token); + } + + internal static Task DeleteFmtAsync(this IDbCommand dbCmd, string table, string where, CancellationToken token) + { + var sql = WriteExpressionCommandExtensionsLegacy.DeleteFmtSql(dbCmd.GetDialectProvider(), table, where); + return dbCmd.ExecuteSqlAsync(sql, token); + } + + internal static Task InsertOnlyAsync(this IDbCommand dbCmd, T obj, SqlExpression onlyFields, CancellationToken token) + { + if (OrmLiteConfig.InsertFilter != null) + OrmLiteConfig.InsertFilter(dbCmd, obj); + + var dialectProvider = dbCmd.GetDialectProvider(); + var sql = dialectProvider.ToInsertRowStatement(dbCmd, obj, onlyFields.InsertFields); + + dialectProvider.SetParameterValues(dbCmd, obj); + + return dbCmd.ExecuteSqlAsync(sql, token); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Legacy/WriteExpressionCommandExtensionsLegacy.cs b/src/ServiceStack.OrmLite/Legacy/WriteExpressionCommandExtensionsLegacy.cs new file mode 100644 index 000000000..50771df85 --- /dev/null +++ b/src/ServiceStack.OrmLite/Legacy/WriteExpressionCommandExtensionsLegacy.cs @@ -0,0 +1,108 @@ +using System; +using System.Data; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Legacy +{ + [Obsolete(Messages.LegacyApi)] + internal static class WriteExpressionCommandExtensionsLegacy + { + [Obsolete("Use db.InsertOnly(obj, db.From())")] + public static void InsertOnly(this IDbCommand dbCmd, T obj, Func, SqlExpression> onlyFields) + { + dbCmd.InsertOnly(obj, onlyFields(dbCmd.GetDialectProvider().SqlExpression())); + } + + [Obsolete("Use db.UpdateOnly(model, db.From())")] + public static int UpdateOnly(this IDbCommand dbCmd, T model, Func, SqlExpression> onlyFields) + { + return dbCmd.UpdateOnlyFields(model, onlyFields(dbCmd.GetDialectProvider().SqlExpression())); + } + + public static int UpdateFmt(this IDbCommand dbCmd, string set = null, string where = null) + { + return dbCmd.UpdateFmt(typeof(T).GetModelDefinition().ModelName, set, where); + } + + public static int UpdateFmt(this IDbCommand dbCmd, string table = null, string set = null, string where = null) + { + var sql = UpdateFmtSql(dbCmd.GetDialectProvider(), table, set, @where); + return dbCmd.ExecuteSql(sql); + } + + internal static string UpdateFmtSql(IOrmLiteDialectProvider dialectProvider, string table, string set, string @where) + { + if (table == null) + throw new ArgumentNullException("table"); + if (set == null) + throw new ArgumentNullException("set"); + + var sql = StringBuilderCache.Allocate(); + sql.Append("UPDATE "); + sql.Append(dialectProvider.GetQuotedTableName(table)); + sql.Append(" SET "); + sql.Append(set.SqlVerifyFragment()); + if (!string.IsNullOrEmpty(@where)) + { + sql.Append(" WHERE "); + sql.Append(@where.SqlVerifyFragment()); + } + return StringBuilderCache.ReturnAndFree(sql); + } + + internal static int DeleteFmt(this IDbCommand dbCmd, string sqlFilter, params object[] filterParams) + { + return DeleteFmt(dbCmd, typeof(T), sqlFilter, filterParams); + } + + internal static int DeleteFmt(this IDbCommand dbCmd, Type tableType, string sqlFilter, params object[] filterParams) + { + return dbCmd.ExecuteSql(dbCmd.GetDialectProvider().ToDeleteStatement(tableType, sqlFilter, filterParams)); + } + + public static int DeleteFmt(this IDbCommand dbCmd, string where = null) + { + return dbCmd.DeleteFmt(typeof(T).GetModelDefinition().ModelName, where); + } + + public static int DeleteFmt(this IDbCommand dbCmd, string table = null, string where = null) + { + var sql = DeleteFmtSql(dbCmd.GetDialectProvider(), table, @where); + return dbCmd.ExecuteSql(sql); + } + + internal static string DeleteFmtSql(IOrmLiteDialectProvider dialectProvider, string table, string @where) + { + if (table == null) + throw new ArgumentNullException("table"); + if (@where == null) + throw new ArgumentNullException("where"); + + var sql = StringBuilderCache.Allocate(); + sql.AppendFormat("DELETE FROM {0} WHERE {1}", + dialectProvider.GetQuotedTableName(table), + @where.SqlVerifyFragment()); + return StringBuilderCache.ReturnAndFree(sql); + } + + [Obsolete("Use db.Delete(db.From())")] + internal static int Delete(this IDbCommand dbCmd, Func, SqlExpression> where) + { + return dbCmd.Delete(where(dbCmd.GetDialectProvider().SqlExpression())); + } + + [Obsolete(Messages.LegacyApi)] + public static void InsertOnly(this IDbCommand dbCmd, T obj, SqlExpression onlyFields) + { + if (OrmLiteConfig.InsertFilter != null) + OrmLiteConfig.InsertFilter(dbCmd, obj); + + var dialectProvider = dbCmd.GetDialectProvider(); + var sql = dialectProvider.ToInsertRowStatement(dbCmd, obj, onlyFields.InsertFields); + + dialectProvider.SetParameterValues(dbCmd, obj); + + dbCmd.ExecuteSql(sql); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/ModelDefinition.cs b/src/ServiceStack.OrmLite/ModelDefinition.cs index 31a026c58..0bb676c68 100644 --- a/src/ServiceStack.OrmLite/ModelDefinition.cs +++ b/src/ServiceStack.OrmLite/ModelDefinition.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // @@ -14,6 +14,7 @@ using System.Linq; using ServiceStack.DataAnnotations; using System.Linq.Expressions; +using System.Runtime.CompilerServices; namespace ServiceStack.OrmLite { @@ -24,6 +25,7 @@ public ModelDefinition() this.FieldDefinitions = new List(); this.IgnoredFieldDefinitions = new List(); this.CompositeIndexes = new List(); + this.UniqueConstraints = new List(); } public const string RowVersionName = "RowVersion"; @@ -42,19 +44,15 @@ public ModelDefinition() public string PostDropTableSql { get; set; } - public bool IsInSchema { get { return this.Schema != null; } } + public bool IsInSchema => this.Schema != null; - public bool HasAutoIncrementId - { - get { return PrimaryKey != null && PrimaryKey.AutoIncrement; } - } + public bool HasAutoIncrementId => PrimaryKey != null && PrimaryKey.AutoIncrement; + + public bool HasSequenceAttribute => this.FieldDefinitions.Any(x => !x.Sequence.IsNullOrEmpty()); public FieldDefinition RowVersion { get; set; } - public string ModelName - { - get { return this.Alias ?? this.Name; } - } + public string ModelName => this.Alias ?? this.Name; public Type ModelType { get; set; } @@ -63,81 +61,203 @@ public FieldDefinition PrimaryKey get { return this.FieldDefinitions.First(x => x.IsPrimaryKey); } } - public List FieldDefinitions { get; set; } - - private FieldDefinition[] fieldDefinitionsArray; - public FieldDefinition[] FieldDefinitionsArray + public object GetPrimaryKey(object instance) { - get { return fieldDefinitionsArray; } + var pk = PrimaryKey; + return pk != null + ? pk.GetValue(instance) + : instance.GetId(); } + public List FieldDefinitions { get; set; } + + public FieldDefinition[] FieldDefinitionsArray { get; private set; } + + public FieldDefinition[] FieldDefinitionsWithAliases { get; private set; } + public List IgnoredFieldDefinitions { get; set; } - private FieldDefinition[] ignoredFieldDefinitionsArray; - public FieldDefinition[] IgnoredFieldDefinitionsArray + public FieldDefinition[] IgnoredFieldDefinitionsArray { get; private set; } + + public FieldDefinition[] AllFieldDefinitionsArray { get; private set; } + + private readonly object fieldDefLock = new object(); + private Dictionary fieldDefinitionMap; + private Func fieldNameSanitizer; + + public FieldDefinition[] AutoIdFields { get; private set; } + + public List GetAutoIdFieldDefinitions() { - get { return ignoredFieldDefinitionsArray; } + var to = new List(); + foreach (var fieldDef in FieldDefinitionsArray) + { + if (fieldDef.AutoId) + { + to.Add(fieldDef); + } + } + return to; } - private FieldDefinition[] allFieldDefinitionsArray; - public FieldDefinition[] AllFieldDefinitionsArray + public FieldDefinition[] GetOrderedFieldDefinitions(ICollection fieldNames, Func sanitizeFieldName=null) { - get { return allFieldDefinitionsArray; } + if (fieldNames == null) + throw new ArgumentNullException(nameof(fieldNames)); + + var fieldDefs = new FieldDefinition[fieldNames.Count]; + + var i = 0; + foreach (var fieldName in fieldNames) + { + var fieldDef = sanitizeFieldName != null + ? AssertFieldDefinition(fieldName, sanitizeFieldName) + : AssertFieldDefinition(fieldName); + fieldDefs[i++] = fieldDef; + } + + return fieldDefs; } - private readonly object fieldDefLock = new object(); - private Dictionary fieldDefinitionMap; - private Func fieldNameSanitizer; public Dictionary GetFieldDefinitionMap(Func sanitizeFieldName) { - if (fieldDefinitionMap == null || fieldNameSanitizer != sanitizeFieldName) + lock (fieldDefLock) { - lock (fieldDefLock) + if (fieldDefinitionMap != null && fieldNameSanitizer == sanitizeFieldName) + return fieldDefinitionMap; + + fieldDefinitionMap = new Dictionary(StringComparer.OrdinalIgnoreCase); + fieldNameSanitizer = sanitizeFieldName; + foreach (var fieldDef in FieldDefinitionsArray) { - if (fieldDefinitionMap == null || fieldNameSanitizer != sanitizeFieldName) - { - fieldDefinitionMap = new Dictionary(StringComparer.OrdinalIgnoreCase); - fieldNameSanitizer = sanitizeFieldName; - foreach (var fieldDef in FieldDefinitionsArray) - { - fieldDefinitionMap[sanitizeFieldName(fieldDef.FieldName)] = fieldDef; - } - } + fieldDefinitionMap[sanitizeFieldName(fieldDef.FieldName)] = fieldDef; } + return fieldDefinitionMap; } - return fieldDefinitionMap; } public List CompositeIndexes { get; set; } + public List UniqueConstraints { get; set; } + public FieldDefinition GetFieldDefinition(Expression> field) { - var fn = GetFieldName(field); - return FieldDefinitions.First(f => f.Name == fn); + return GetFieldDefinition(ExpressionUtils.GetMemberName(field)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void ThrowNoFieldException(string fieldName) => + throw new NotSupportedException($"'{fieldName}' is not a property of '{Name}'"); + + public FieldDefinition AssertFieldDefinition(string fieldName) + { + var fieldDef = GetFieldDefinition(fieldName); + if (fieldDef == null) + ThrowNoFieldException(fieldName); + + return fieldDef; + } + + public FieldDefinition GetFieldDefinition(string fieldName) + { + if (fieldName != null) + { + foreach (var f in FieldDefinitionsWithAliases) + { + if (f.Alias == fieldName) + return f; + } + foreach (var f in FieldDefinitionsArray) + { + if (f.Name == fieldName) + return f; + } + foreach (var f in FieldDefinitionsWithAliases) + { + if (string.Equals(f.Alias, fieldName, StringComparison.OrdinalIgnoreCase)) + return f; + } + foreach (var f in FieldDefinitionsArray) + { + if (string.Equals(f.Name, fieldName, StringComparison.OrdinalIgnoreCase)) + return f; + } + } + return null; } - string GetFieldName(Expression> field) + public FieldDefinition AssertFieldDefinition(string fieldName, Func sanitizeFieldName) { + var fieldDef = GetFieldDefinition(fieldName, sanitizeFieldName); + if (fieldDef == null) + ThrowNoFieldException(fieldName); - var lambda = (field as LambdaExpression); - if (lambda.Body.NodeType == ExpressionType.MemberAccess) + return fieldDef; + } + + public FieldDefinition GetFieldDefinition(string fieldName, Func sanitizeFieldName) + { + if (fieldName != null) { - var me = lambda.Body as MemberExpression; - return me.Member.Name; + foreach (var f in FieldDefinitionsWithAliases) + { + if (f.Alias == fieldName || sanitizeFieldName(f.Alias) == fieldName) + return f; + } + foreach (var f in FieldDefinitionsArray) + { + if (f.Name == fieldName || sanitizeFieldName(f.Name) == fieldName) + return f; + } + foreach (var f in FieldDefinitionsWithAliases) + { + if (string.Equals(f.Alias, fieldName, StringComparison.OrdinalIgnoreCase) || + string.Equals(sanitizeFieldName(f.Alias), fieldName, StringComparison.OrdinalIgnoreCase)) + return f; + } + foreach (var f in FieldDefinitionsArray) + { + if (string.Equals(f.Name, fieldName, StringComparison.OrdinalIgnoreCase) || + string.Equals(sanitizeFieldName(f.Name), fieldName, StringComparison.OrdinalIgnoreCase)) + return f; + } } - - var operand = (lambda.Body as UnaryExpression).Operand; - return (operand as MemberExpression).Member.Name; + return null; + } + + public string GetQuotedName(string fieldName, IOrmLiteDialectProvider dialectProvider) => + GetFieldDefinition(fieldName)?.GetQuotedName(dialectProvider); + + public FieldDefinition GetFieldDefinition(Func predicate) + { + foreach (var f in FieldDefinitionsWithAliases) + { + if (predicate(f.Alias)) + return f; + } + foreach (var f in FieldDefinitionsArray) + { + if (predicate(f.Name)) + return f; + } + + return null; } public void AfterInit() { - fieldDefinitionsArray = FieldDefinitions.ToArray(); - ignoredFieldDefinitionsArray = IgnoredFieldDefinitions.ToArray(); + FieldDefinitionsArray = FieldDefinitions.ToArray(); + FieldDefinitionsWithAliases = FieldDefinitions.Where(x => x.Alias != null).ToArray(); + + IgnoredFieldDefinitionsArray = IgnoredFieldDefinitions.ToArray(); var allItems = new List(FieldDefinitions); allItems.AddRange(IgnoredFieldDefinitions); - allFieldDefinitionsArray = allItems.ToArray(); + AllFieldDefinitionsArray = allItems.ToArray(); + + AutoIdFields = GetAutoIdFieldDefinitions().ToArray(); + + OrmLiteConfig.OnModelDefinitionInit?.Invoke(this); } public bool IsRefField(FieldDefinition fieldDef) @@ -151,22 +271,20 @@ private bool IsRefField(string name) return (Alias != null && Alias + "Id" == name) || Name + "Id" == name; } + + public override string ToString() + { + return Name; + } } public static class ModelDefinition { private static ModelDefinition definition; - public static ModelDefinition Definition - { - get { return definition ?? (definition = typeof(T).GetModelDefinition()); } - } + public static ModelDefinition Definition => definition ??= typeof(T).GetModelDefinition(); private static string primaryKeyName; - public static string PrimaryKeyName - { - get { return primaryKeyName ?? (primaryKeyName = Definition.PrimaryKey.FieldName); } - } - + public static string PrimaryKeyName => primaryKeyName ??= Definition.PrimaryKey.FieldName; } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/NamingStrategy.cs b/src/ServiceStack.OrmLite/NamingStrategy.cs new file mode 100644 index 000000000..1cff3cdb4 --- /dev/null +++ b/src/ServiceStack.OrmLite/NamingStrategy.cs @@ -0,0 +1,73 @@ +using System.Collections.Generic; + +namespace ServiceStack.OrmLite +{ + public class OrmLiteDefaultNamingStrategy : OrmLiteNamingStrategyBase {} + public class AliasNamingStrategy : OrmLiteNamingStrategyBase + { + public Dictionary TableAliases = new(); + public Dictionary ColumnAliases = new(); + public INamingStrategy UseNamingStrategy { get; set; } + + public override string GetTableName(string name) + { + string alias; + return UseNamingStrategy != null + ? UseNamingStrategy.GetTableName(TableAliases.TryGetValue(name, out alias) ? alias : name) + : base.GetTableName(TableAliases.TryGetValue(name, out alias) ? alias : name); + } + + public override string GetColumnName(string name) + { + string alias; + return UseNamingStrategy != null + ? UseNamingStrategy.GetColumnName(ColumnAliases.TryGetValue(name, out alias) ? alias : name) + : base.GetColumnName(ColumnAliases.TryGetValue(name, out alias) ? alias : name); + } + } + + public class LowercaseUnderscoreNamingStrategy : OrmLiteNamingStrategyBase + { + public override string GetTableName(string name) + { + return name.ToLowercaseUnderscore(); + } + + public override string GetColumnName(string name) + { + return name.ToLowercaseUnderscore(); + } + } + + public class UpperCaseNamingStrategy : OrmLiteNamingStrategyBase + { + public override string GetTableName(string name) + { + return name.ToUpper(); + } + + public override string GetColumnName(string name) + { + return name.ToUpper(); + } + } + + public class PrefixNamingStrategy : OrmLiteNamingStrategyBase + { + public string TablePrefix { get; set; } + + public string ColumnPrefix { get; set; } + + public override string GetTableName(string name) + { + return TablePrefix + name; + } + + public override string GetColumnName(string name) + { + return ColumnPrefix + name; + } + + } + +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteCommand.cs b/src/ServiceStack.OrmLite/OrmLiteCommand.cs index 90b0994f0..4d67621f1 100644 --- a/src/ServiceStack.OrmLite/OrmLiteCommand.cs +++ b/src/ServiceStack.OrmLite/OrmLiteCommand.cs @@ -1,17 +1,13 @@ using System.Data; +using ServiceStack.Data; namespace ServiceStack.OrmLite { - public interface IHasDbCommand + public class OrmLiteCommand : IDbCommand, IHasDbCommand, IHasDialectProvider { - IDbCommand DbCommand { get; } - } - - public class OrmLiteCommand : IDbCommand, IHasDbCommand - { - private OrmLiteConnection dbConn; - private IDbCommand dbCmd; - public IOrmLiteDialectProvider DialectProvider; + private readonly OrmLiteConnection dbConn; + private readonly IDbCommand dbCmd; + public IOrmLiteDialectProvider DialectProvider { get; set; } public bool IsDisposed { get; private set; } public OrmLiteCommand(OrmLiteConnection dbConn, IDbCommand dbCmd) @@ -64,42 +60,37 @@ public object ExecuteScalar() public IDbConnection Connection { - get { return dbCmd.Connection; } - set { dbCmd.Connection = value; } + get => dbCmd.Connection; + set => dbCmd.Connection = value; } public IDbTransaction Transaction { - get { return dbCmd.Transaction; } - set { dbCmd.Transaction = value; } + get => dbCmd.Transaction; + set => dbCmd.Transaction = value; } public string CommandText { - get { return dbCmd.CommandText; } - set { dbCmd.CommandText = value; } + get => dbCmd.CommandText; + set => dbCmd.CommandText = value; } public int CommandTimeout { - get { return dbCmd.CommandTimeout; } - set { dbCmd.CommandTimeout = value; } + get => dbCmd.CommandTimeout; + set => dbCmd.CommandTimeout = value; } public CommandType CommandType { - get { return dbCmd.CommandType; } - set { dbCmd.CommandType = value; } - } - public IDataParameterCollection Parameters - { - get { return dbCmd.Parameters; } + get => dbCmd.CommandType; + set => dbCmd.CommandType = value; } + public IDataParameterCollection Parameters => dbCmd.Parameters; + public UpdateRowSource UpdatedRowSource { - get { return dbCmd.UpdatedRowSource; } - set { dbCmd.UpdatedRowSource = value; } + get => dbCmd.UpdatedRowSource; + set => dbCmd.UpdatedRowSource = value; } - public IDbCommand DbCommand - { - get { return dbCmd; } - } + public IDbCommand DbCommand => dbCmd; } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteConfig.cs b/src/ServiceStack.OrmLite/OrmLiteConfig.cs index bb1337f9b..225bf1616 100644 --- a/src/ServiceStack.OrmLite/OrmLiteConfig.cs +++ b/src/ServiceStack.OrmLite/OrmLiteConfig.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Data; +using ServiceStack.Logging; namespace ServiceStack.OrmLite { @@ -19,21 +20,13 @@ public static class OrmLiteConfig { public const string IdField = "Id"; - private const int defaultCommandTimeout = 30; + private const int DefaultCommandTimeout = 30; private static int? commandTimeout; public static int CommandTimeout { - get - { - if (commandTimeout != null) - return commandTimeout.Value; - return defaultCommandTimeout; - } - set - { - commandTimeout = value; - } + get => commandTimeout ?? DefaultCommandTimeout; + set => commandTimeout = value; } private static IOrmLiteDialectProvider dialectProvider; @@ -43,59 +36,57 @@ public static IOrmLiteDialectProvider DialectProvider { if (dialectProvider == null) { - throw new ArgumentNullException("DialectProvider", + throw new ArgumentNullException(nameof(DialectProvider), "You must set the singleton 'OrmLiteConfig.DialectProvider' to use the OrmLiteWriteExtensions"); } return dialectProvider; } - set - { - dialectProvider = value; - } + set => dialectProvider = value; } - public static IOrmLiteDialectProvider GetDialectProvider(this IDbCommand dbCmd) - { - var ormLiteCmd = dbCmd as OrmLiteCommand; - return ormLiteCmd != null - ? ormLiteCmd.DialectProvider + public static IOrmLiteDialectProvider GetDialectProvider(this IDbCommand dbCmd) => + dbCmd is IHasDialectProvider hasDialectProvider + ? hasDialectProvider.DialectProvider : DialectProvider; - } - public static IOrmLiteDialectProvider GetDialectProvider(this IDbConnection db) - { - var ormLiteConn = db as OrmLiteConnection; - return ormLiteConn != null - ? ormLiteConn.DialectProvider + public static IOrmLiteDialectProvider Dialect(this IDbCommand dbCmd) => + dbCmd is IHasDialectProvider hasDialectProvider + ? hasDialectProvider.DialectProvider + : DialectProvider; + + public static IOrmLiteDialectProvider GetDialectProvider(this IDbConnection db) => + db is IHasDialectProvider hasDialectProvider + ? hasDialectProvider.DialectProvider + : DialectProvider; + + public static IOrmLiteDialectProvider Dialect(this IDbConnection db) => + db is IHasDialectProvider hasDialectProvider + ? hasDialectProvider.DialectProvider : DialectProvider; - } public static IOrmLiteExecFilter GetExecFilter(this IOrmLiteDialectProvider dialectProvider) { return dialectProvider != null - ? dialectProvider.ExecFilter ?? ExecFilter - : ExecFilter; + ? dialectProvider.ExecFilter ?? ExecFilter + : ExecFilter; } public static IOrmLiteExecFilter GetExecFilter(this IDbCommand dbCmd) { - var ormLiteCmd = dbCmd as OrmLiteCommand; - var dialectProvider = ormLiteCmd != null - ? ormLiteCmd.DialectProvider + var dialect = dbCmd is IHasDialectProvider hasDialectProvider + ? hasDialectProvider.DialectProvider : DialectProvider; - return dialectProvider.GetExecFilter(); + return dialect.GetExecFilter(); } public static IOrmLiteExecFilter GetExecFilter(this IDbConnection db) { - var ormLiteConn = db as OrmLiteConnection; - var dialectProvider = ormLiteConn != null - ? ormLiteConn.DialectProvider + var dialect = db is IHasDialectProvider hasDialectProvider + ? hasDialectProvider.DialectProvider : DialectProvider; - return dialectProvider.GetExecFilter(); + return dialect.GetExecFilter(); } public static void SetLastCommandText(this IDbConnection db, string sql) { - var ormLiteConn = db as OrmLiteConnection; - if (ormLiteConn != null) + if (db is OrmLiteConnection ormLiteConn) { ormLiteConn.LastCommandText = sql; } @@ -105,9 +96,8 @@ public static void SetLastCommandText(this IDbConnection db, string sql) public static void SetCommandTimeout(this IDbConnection db, int? commandTimeout) { - var ormLiteConn = db as OrmLiteConnection; - if (ormLiteConn == null) - throw new NotImplementedException(RequiresOrmLiteConnection.Fmt("CommandTimeout")); + if (!(db is OrmLiteConnection ormLiteConn)) + throw new NotImplementedException(string.Format(RequiresOrmLiteConnection,"CommandTimeout")); ormLiteConn.CommandTimeout = commandTimeout; } @@ -149,19 +139,35 @@ public static IDbConnection ToDbConnection(this string dbConnectionStringOrFileP return dbConn; } + public static void ResetLogFactory(ILogFactory logFactory=null) + { + logFactory ??= LogManager.LogFactory; + LogManager.LogFactory = logFactory; + OrmLiteResultsFilterExtensions.Log = logFactory.GetLogger(typeof(OrmLiteResultsFilterExtensions)); + OrmLiteWriteCommandExtensions.Log = logFactory.GetLogger(typeof(OrmLiteWriteCommandExtensions)); + OrmLiteReadCommandExtensions.Log = logFactory.GetLogger(typeof(OrmLiteReadCommandExtensions)); + OrmLiteResultsFilterExtensions.Log = logFactory.GetLogger(typeof(OrmLiteResultsFilterExtensions)); + OrmLiteUtils.Log = logFactory.GetLogger(typeof(OrmLiteUtils)); + OrmLiteWriteCommandExtensionsAsync.Log = logFactory.GetLogger(typeof(OrmLiteWriteCommandExtensionsAsync)); + OrmLiteReadCommandExtensionsAsync.Log = logFactory.GetLogger(typeof(OrmLiteReadCommandExtensionsAsync)); + OrmLiteResultsFilterExtensionsAsync.Log = logFactory.GetLogger(typeof(OrmLiteResultsFilterExtensionsAsync)); + OrmLiteConverter.Log = logFactory.GetLogger(typeof(OrmLiteConverter)); + } + public static bool DisableColumnGuessFallback { get; set; } - public static bool StripUpperInLike { get; set; } + public static bool StripUpperInLike { get; set; } +#if NETCORE + = true; +#endif public static IOrmLiteResultsFilter ResultsFilter { get { var state = OrmLiteContext.OrmLiteState; - return state != null - ? state.ResultsFilter - : null; + return state?.ResultsFilter; } - set { OrmLiteContext.GetOrCreateState().ResultsFilter = value; } + set => OrmLiteContext.GetOrCreateState().ResultsFilter = value; } private static IOrmLiteExecFilter execFilter; @@ -176,12 +182,43 @@ public static IOrmLiteExecFilter ExecFilter ? dialectProvider.ExecFilter ?? execFilter : execFilter; } - set { execFilter = value; } + set => execFilter = value; } + public static Action BeforeExecFilter { get; set; } + public static Action AfterExecFilter { get; set; } + public static Action InsertFilter { get; set; } public static Action UpdateFilter { get; set; } + public static Action SqlExpressionSelectFilter { get; set; } + public static Func LoadReferenceSelectFilter { get; set; } + public static Func StringFilter { get; set; } + + public static Func OnDbNullFilter { get; set; } + + public static Action PopulatedObjectFilter { get; set; } + + public static Action ExceptionFilter { get; set; } + + public static bool ThrowOnError { get; set; } + + public static Func SanitizeFieldNameForParamNameFn = fieldName => + (fieldName ?? "").Replace(" ", ""); + + public static bool IsCaseInsensitive { get; set; } + + public static bool DeoptimizeReader { get; set; } + + public static bool SkipForeignKeys { get; set; } + + public static bool IncludeTablePrefixes { get; set; } + + public static Action SqlExpressionInitFilter { get; set; } + + public static Func ParamNameFilter { get; set; } + + public static Action OnModelDefinitionInit { get; set; } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteConfigExtensions.cs b/src/ServiceStack.OrmLite/OrmLiteConfigExtensions.cs index 0b8b731d2..b91dfe11b 100644 --- a/src/ServiceStack.OrmLite/OrmLiteConfigExtensions.cs +++ b/src/ServiceStack.OrmLite/OrmLiteConfigExtensions.cs @@ -4,17 +4,20 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Reflection; using System.Threading; using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; +using ServiceStack.Text; namespace ServiceStack.OrmLite { @@ -22,12 +25,6 @@ internal static class OrmLiteConfigExtensions { private static Dictionary typeModelDefinitionMap = new Dictionary(); - private static bool IsNullableType(Type theType) - { - return (theType.IsGenericType - && theType.GetGenericTypeDefinition() == typeof(Nullable<>)); - } - internal static bool CheckForIdField(IEnumerable objProperties) { // Not using Linq.Where() and manually iterating through objProperties just to avoid dependencies on System.Xml?? @@ -45,47 +42,63 @@ internal static void ClearCache() } internal static ModelDefinition GetModelDefinition(this Type modelType) - { - ModelDefinition modelDef; - - if (typeModelDefinitionMap.TryGetValue(modelType, out modelDef)) + { + if (typeModelDefinitionMap.TryGetValue(modelType, out var modelDef)) return modelDef; - if (modelType.IsValueType() || modelType == typeof(string)) + if (modelType.IsValueType || modelType == typeof(string)) return null; var modelAliasAttr = modelType.FirstAttribute(); var schemaAttr = modelType.FirstAttribute(); - var preCreate = modelType.FirstAttribute(); - var postCreate = modelType.FirstAttribute(); - var preDrop = modelType.FirstAttribute(); - var postDrop = modelType.FirstAttribute(); + var preCreates = modelType.AllAttributes(); + var postCreates = modelType.AllAttributes(); + var preDrops = modelType.AllAttributes(); + var postDrops = modelType.AllAttributes(); + + string JoinSql(List statements) + { + if (statements.Count == 0) + return null; + var sb = StringBuilderCache.Allocate(); + foreach (var sql in statements) + { + if (sb.Length > 0) + sb.AppendLine(";"); + sb.Append(sql); + } + var to = StringBuilderCache.ReturnAndFree(sb); + return to; + } modelDef = new ModelDefinition { ModelType = modelType, Name = modelType.Name, - Alias = modelAliasAttr != null ? modelAliasAttr.Name : null, - Schema = schemaAttr != null ? schemaAttr.Name : null, - PreCreateTableSql = preCreate != null ? preCreate.Sql : null, - PostCreateTableSql = postCreate != null ? postCreate.Sql : null, - PreDropTableSql = preDrop != null ? preDrop.Sql : null, - PostDropTableSql = postDrop != null ? postDrop.Sql : null, + Alias = modelAliasAttr?.Name, + Schema = schemaAttr?.Name, + PreCreateTableSql = JoinSql(preCreates.Map(x => x.Sql)), + PostCreateTableSql = JoinSql(postCreates.Map(x => x.Sql)), + PreDropTableSql = JoinSql(preDrops.Map(x => x.Sql)), + PostDropTableSql = JoinSql(postDrops.Map(x => x.Sql)), }; modelDef.CompositeIndexes.AddRange( - modelType.GetCustomAttributes(typeof(CompositeIndexAttribute), true).ToList() - .ConvertAll(x => (CompositeIndexAttribute)x)); + modelType.AllAttributes().ToList()); + + modelDef.UniqueConstraints.AddRange( + modelType.AllAttributes().ToList()); var objProperties = modelType.GetProperties( BindingFlags.Public | BindingFlags.Instance).ToList(); - var hasPkAttr = objProperties.Any(p => p.HasAttribute()); + var hasPkAttr = objProperties.Any(p => p.HasAttributeCached()); var hasIdField = CheckForIdField(objProperties); var i = 0; + var propertyInfoIdx = 0; foreach (var propertyInfo in objProperties) { if (propertyInfo.GetIndexParameters().Length > 0) @@ -93,37 +106,57 @@ internal static ModelDefinition GetModelDefinition(this Type modelType) var sequenceAttr = propertyInfo.FirstAttribute(); var computeAttr = propertyInfo.FirstAttribute(); + var computedAttr = propertyInfo.FirstAttribute(); + var persistedAttr = propertyInfo.FirstAttribute(); + var customSelectAttr = propertyInfo.FirstAttribute(); var decimalAttribute = propertyInfo.FirstAttribute(); var belongToAttribute = propertyInfo.FirstAttribute(); - var isFirst = i++ == 0; - - var isPrimaryKey = (!hasPkAttr && (propertyInfo.Name == OrmLiteConfig.IdField || (!hasIdField && isFirst))) - || propertyInfo.HasAttributeNamed(typeof(PrimaryKeyAttribute).Name); + var referenceAttr = propertyInfo.FirstAttribute(); var isRowVersion = propertyInfo.Name == ModelDefinition.RowVersionName - && propertyInfo.PropertyType == typeof(ulong); + && (propertyInfo.PropertyType == typeof(ulong) || propertyInfo.PropertyType == typeof(byte[])); - var isNullableType = IsNullableType(propertyInfo.PropertyType); + var isNullableType = propertyInfo.PropertyType.IsNullableType(); var isNullable = (!propertyInfo.PropertyType.IsValueType - && !propertyInfo.HasAttributeNamed(typeof(RequiredAttribute).Name)) + && !propertyInfo.HasAttributeNamed(nameof(RequiredAttribute))) || isNullableType; var propertyType = isNullableType ? Nullable.GetUnderlyingType(propertyInfo.PropertyType) : propertyInfo.PropertyType; + Type treatAsType = null; - if (propertyType.IsEnumFlags()) - { - treatAsType = Enum.GetUnderlyingType(propertyType); - } - if (propertyType == typeof(TimeSpan)) + if (propertyType.IsEnum) { - treatAsType = typeof(long); + var enumKind = Converters.EnumConverter.GetEnumKind(propertyType); + if (enumKind == EnumKind.Int) + treatAsType = Enum.GetUnderlyingType(propertyType); + else if (enumKind == EnumKind.Char) + treatAsType = typeof(char); } + var isReference = referenceAttr != null && propertyType.IsClass; + var isIgnored = propertyInfo.HasAttributeCached() || isReference; + + var isFirst = !isIgnored && i++ == 0; + + var isAutoId = propertyInfo.HasAttributeCached(); + + var isPrimaryKey = (!hasPkAttr && (propertyInfo.Name == OrmLiteConfig.IdField || (!hasIdField && isFirst))) + || propertyInfo.HasAttributeNamed(nameof(PrimaryKeyAttribute)) + || isAutoId; + + var isAutoIncrement = isPrimaryKey && propertyInfo.HasAttributeCached(); + + if (isAutoIncrement && propertyInfo.PropertyType == typeof(Guid)) + throw new NotSupportedException($"[AutoIncrement] is only valid for integer properties for {modelType.Name}.{propertyInfo.Name} Guid property use [AutoId] instead"); + + if (isAutoId && (propertyInfo.PropertyType == typeof(int) || propertyInfo.PropertyType == typeof(long))) + throw new NotSupportedException($"[AutoId] is only valid for Guid properties for {modelType.Name}.{propertyInfo.Name} integer property use [AutoIncrement] instead"); + var aliasAttr = propertyInfo.FirstAttribute(); var indexAttr = propertyInfo.FirstAttribute(); @@ -135,51 +168,58 @@ internal static ModelDefinition GetModelDefinition(this Type modelType) var defaultValueAttr = propertyInfo.FirstAttribute(); var referencesAttr = propertyInfo.FirstAttribute(); - var referenceAttr = propertyInfo.FirstAttribute(); - var foreignKeyAttr = propertyInfo.FirstAttribute(); + var fkAttr = propertyInfo.FirstAttribute(); var customFieldAttr = propertyInfo.FirstAttribute(); + var chkConstraintAttr = propertyInfo.FirstAttribute(); + + var order = propertyInfoIdx++; + if (customFieldAttr != null) order = customFieldAttr.Order; var fieldDefinition = new FieldDefinition { Name = propertyInfo.Name, - Alias = aliasAttr != null ? aliasAttr.Name : null, + Alias = aliasAttr?.Name, FieldType = propertyType, + FieldTypeDefaultValue = isNullable ? null : propertyType.GetDefaultValue(), TreatAsType = treatAsType, PropertyInfo = propertyInfo, IsNullable = isNullable, IsPrimaryKey = isPrimaryKey, - AutoIncrement = - isPrimaryKey && - propertyInfo.HasAttributeNamed(typeof(AutoIncrementAttribute).Name), - IsIndexed = isIndex, - IsUnique = isUnique, - IsClustered = indexAttr != null && indexAttr.Clustered, - IsNonClustered = indexAttr != null && indexAttr.NonClustered, + AutoIncrement = isPrimaryKey && isAutoIncrement, + AutoId = isAutoId, + IsIndexed = !isPrimaryKey && isIndex, + IsUniqueIndex = isUnique, + IsClustered = indexAttr?.Clustered == true, + IsNonClustered = indexAttr?.NonClustered == true, + IndexName = indexAttr?.Name, IsRowVersion = isRowVersion, - FieldLength = stringLengthAttr != null - ? stringLengthAttr.MaximumLength - : (int?)null, - DefaultValue = defaultValueAttr != null ? defaultValueAttr.DefaultValue : null, - ForeignKey = foreignKeyAttr == null + IgnoreOnInsert = propertyInfo.HasAttributeCached(), + IgnoreOnUpdate = propertyInfo.HasAttributeCached(), + ReturnOnInsert = propertyInfo.HasAttributeCached(), + FieldLength = stringLengthAttr?.MaximumLength, + DefaultValue = defaultValueAttr?.DefaultValue, + CheckConstraint = chkConstraintAttr?.Constraint, + IsUniqueConstraint = propertyInfo.HasAttributeCached(), + ForeignKey = fkAttr == null ? referencesAttr != null ? new ForeignKeyConstraint(referencesAttr.Type) : null - : new ForeignKeyConstraint(foreignKeyAttr.Type, - foreignKeyAttr.OnDelete, - foreignKeyAttr.OnUpdate, - foreignKeyAttr.ForeignKeyName), - IsReference = referenceAttr != null && propertyType.IsClass, - GetValueFn = propertyInfo.GetPropertyGetterFn(), - SetValueFn = propertyInfo.GetPropertySetterFn(), - Sequence = sequenceAttr != null ? sequenceAttr.Name : string.Empty, - IsComputed = computeAttr != null, + : new ForeignKeyConstraint(fkAttr.Type, fkAttr.OnDelete, fkAttr.OnUpdate, fkAttr.ForeignKeyName), + IsReference = isReference, + GetValueFn = propertyInfo.CreateGetter(), + SetValueFn = propertyInfo.CreateSetter(), + Sequence = sequenceAttr?.Name, + IsComputed = computeAttr != null || computedAttr != null || customSelectAttr != null, + IsPersisted = persistedAttr != null, ComputeExpression = computeAttr != null ? computeAttr.Expression : string.Empty, - Scale = decimalAttribute != null ? decimalAttribute.Scale : (int?)null, - BelongToModelName = belongToAttribute != null ? belongToAttribute.BelongToTableType.GetModelDefinition().ModelName : null, - CustomFieldDefinition = customFieldAttr != null ? customFieldAttr.Sql : null, + CustomSelect = customSelectAttr?.Sql, + CustomInsert = propertyInfo.FirstAttribute()?.Sql, + CustomUpdate = propertyInfo.FirstAttribute()?.Sql, + Scale = decimalAttribute?.Scale, + BelongToModelName = belongToAttribute?.BelongToTableType.GetModelDefinition().ModelName, + CustomFieldDefinition = customFieldAttr?.Sql, IsRefType = propertyType.IsRefType(), + Order = order }; - - var isIgnored = propertyInfo.HasAttributeNamed(typeof(IgnoreAttribute).Name) - || fieldDefinition.IsReference; + if (isIgnored) modelDef.IgnoredFieldDefinitions.Add(fieldDefinition); else @@ -195,8 +235,7 @@ internal static ModelDefinition GetModelDefinition(this Type modelType) do { snapshot = typeModelDefinitionMap; - newCache = new Dictionary(typeModelDefinitionMap); - newCache[modelType] = modelDef; + newCache = new Dictionary(typeModelDefinitionMap) { [modelType] = modelDef }; } while (!ReferenceEquals( Interlocked.CompareExchange(ref typeModelDefinitionMap, newCache, snapshot), snapshot)); diff --git a/src/ServiceStack.OrmLite/OrmLiteConflictResolutions.cs b/src/ServiceStack.OrmLite/OrmLiteConflictResolutions.cs new file mode 100644 index 000000000..246887ea0 --- /dev/null +++ b/src/ServiceStack.OrmLite/OrmLiteConflictResolutions.cs @@ -0,0 +1,26 @@ +using System; +using System.Data; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite +{ + public class ConflictResolution + { + public const string Ignore = "IGNORE"; + } + + public static class OrmLiteConflictResolutions + { + public static void OnConflictIgnore(this IDbCommand dbCmd) => dbCmd.OnConflict(ConflictResolution.Ignore); + + public static void OnConflict(this IDbCommand dbCmd, string conflictResolution) + { + var pos = dbCmd.CommandText?.IndexOf(' ') ?? -1; + if (pos == -1) + throw new NotSupportedException("Cannot specify ON CONFLICT resolution on Invalid SQL starting with: " + dbCmd.CommandText.SubstringWithEllipsis(0, 50)); + + var sqlConflict = dbCmd.GetDialectProvider().SqlConflict(dbCmd.CommandText, conflictResolution); + dbCmd.CommandText = sqlConflict; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteConnection.cs b/src/ServiceStack.OrmLite/OrmLiteConnection.cs index 9817a9216..f4852e93f 100644 --- a/src/ServiceStack.OrmLite/OrmLiteConnection.cs +++ b/src/ServiceStack.OrmLite/OrmLiteConnection.cs @@ -1,6 +1,9 @@ using System.Data; using System.Data.Common; +using System.Threading; +using System.Threading.Tasks; using ServiceStack.Data; +using ServiceStack.Text; namespace ServiceStack.OrmLite { @@ -8,10 +11,11 @@ namespace ServiceStack.OrmLite /// Wrapper IDbConnection class to allow for connection sharing, mocking, etc. /// public class OrmLiteConnection - : IDbConnection, IHasDbConnection, IHasDbTransaction + : IDbConnection, IHasDbConnection, IHasDbTransaction, ISetDbTransaction, IHasDialectProvider { public readonly OrmLiteConnectionFactory Factory; public IDbTransaction Transaction { get; set; } + public IDbTransaction DbTransaction => Transaction; private IDbConnection dbConnection; public IOrmLiteDialectProvider DialectProvider { get; set; } @@ -24,21 +28,11 @@ public OrmLiteConnection(OrmLiteConnectionFactory factory) this.DialectProvider = factory.DialectProvider; } - public IDbConnection DbConnection - { - get - { - if (dbConnection == null) - { - dbConnection = ConnectionString.ToDbConnection(Factory.DialectProvider); - } - return dbConnection; - } - } + public IDbConnection DbConnection => dbConnection ??= ConnectionString.ToDbConnection(Factory.DialectProvider); public void Dispose() { - if (Factory.OnDispose != null) Factory.OnDispose(this); + Factory.OnDispose?.Invoke(this); if (!Factory.AutoDisposeConnection) return; DbConnection.Dispose(); @@ -92,31 +86,40 @@ public void Open() //so the internal connection is wrapped for example by miniprofiler if (Factory.ConnectionFilter != null) dbConnection = Factory.ConnectionFilter(dbConnection); + + DialectProvider.OnOpenConnection?.Invoke(dbConnection); } } - private string connectionString; - public string ConnectionString + public async Task OpenAsync(CancellationToken token = default) { - get { return connectionString ?? Factory.ConnectionString; } - set { connectionString = value; } - } + if (DbConnection.State == ConnectionState.Broken) + DbConnection.Close(); - public int ConnectionTimeout - { - get { return DbConnection.ConnectionTimeout; } - } + if (DbConnection.State == ConnectionState.Closed) + { + await DialectProvider.OpenAsync(DbConnection, token).ConfigAwait(); + //so the internal connection is wrapped for example by miniprofiler + if (Factory.ConnectionFilter != null) + dbConnection = Factory.ConnectionFilter(dbConnection); - public string Database - { - get { return DbConnection.Database; } + DialectProvider.OnOpenConnection?.Invoke(dbConnection); + } } - public ConnectionState State + private string connectionString; + public string ConnectionString { - get { return DbConnection.State; } + get => connectionString ?? Factory.ConnectionString; + set => connectionString = value; } + public int ConnectionTimeout => DbConnection.ConnectionTimeout; + + public string Database => DbConnection.Database; + + public ConnectionState State => DbConnection.State; + public bool AutoDisposeConnection { get; set; } public static explicit operator DbConnection(OrmLiteConnection dbConn) @@ -125,8 +128,17 @@ public static explicit operator DbConnection(OrmLiteConnection dbConn) } } - internal interface IHasDbTransaction + internal interface ISetDbTransaction { IDbTransaction Transaction { get; set; } } + + public static class OrmLiteConnectionUtils + { + public static bool InTransaction(this IDbConnection db) => + db is IHasDbTransaction setDb && setDb.DbTransaction != null; + + public static IDbTransaction GetTransaction(this IDbConnection db) => + db is IHasDbTransaction setDb ? setDb.DbTransaction : null; + } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteConnectionFactory.cs b/src/ServiceStack.OrmLite/OrmLiteConnectionFactory.cs index 7932a113a..058233e63 100644 --- a/src/ServiceStack.OrmLite/OrmLiteConnectionFactory.cs +++ b/src/ServiceStack.OrmLite/OrmLiteConnectionFactory.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; using System.Data; +using System.Threading; +using System.Threading.Tasks; using ServiceStack.Data; +using ServiceStack.Text; namespace ServiceStack.OrmLite { @@ -9,7 +12,7 @@ namespace ServiceStack.OrmLite /// Allow for mocking and unit testing by providing non-disposing /// connection factory with injectable IDbCommand and IDbTransaction proxies /// - public class OrmLiteConnectionFactory : IDbConnectionFactory + public class OrmLiteConnectionFactory : IDbConnectionFactoryExtended { public OrmLiteConnectionFactory() : this(null, null, true) { } @@ -22,6 +25,8 @@ public OrmLiteConnectionFactory(string connectionString, IOrmLiteDialectProvider public OrmLiteConnectionFactory(string connectionString, IOrmLiteDialectProvider dialectProvider, bool setGlobalDialectProvider) { + if (connectionString == "DataSource=:memory:") + connectionString = ":memory:"; ConnectionString = connectionString; AutoDisposeConnection = connectionString != ":memory:"; this.DialectProvider = dialectProvider ?? OrmLiteConfig.DialectProvider; @@ -32,6 +37,8 @@ public OrmLiteConnectionFactory(string connectionString, IOrmLiteDialectProvider } this.ConnectionFilter = x => x; + + JsConfig.InitStatics(); } public IOrmLiteDialectProvider DialectProvider { get; set; } @@ -55,16 +62,32 @@ public OrmLiteConnectionFactory(string connectionString, IOrmLiteDialectProvider public Action OnDispose { get; set; } private OrmLiteConnection ormLiteConnection; - private OrmLiteConnection OrmLiteConnection + private OrmLiteConnection OrmLiteConnection => ormLiteConnection ??= new OrmLiteConnection(this); + + public virtual IDbConnection CreateDbConnection() { - get - { - if (ormLiteConnection == null) - { - ormLiteConnection = new OrmLiteConnection(this); - } - return ormLiteConnection; - } + if (this.ConnectionString == null) + throw new ArgumentNullException("ConnectionString", "ConnectionString must be set"); + + var connection = AutoDisposeConnection + ? new OrmLiteConnection(this) + : OrmLiteConnection; + + return connection; + } + + public static IDbConnection CreateDbConnection(string namedConnection) + { + if (namedConnection == null) + throw new ArgumentNullException(nameof(namedConnection)); + + if (!NamedConnections.TryGetValue(namedConnection, out var factory)) + throw new KeyNotFoundException("No factory registered is named " + namedConnection); + + IDbConnection connection = factory.AutoDisposeConnection + ? new OrmLiteConnection(factory) + : factory.OrmLiteConnection; + return connection; } public virtual IDbConnection OpenDbConnection() @@ -75,24 +98,39 @@ public virtual IDbConnection OpenDbConnection() return connection; } - public virtual IDbConnection CreateDbConnection() + public virtual async Task OpenDbConnectionAsync(CancellationToken token = default) { - if (this.ConnectionString == null) - throw new ArgumentNullException("ConnectionString", "ConnectionString must be set"); + var connection = CreateDbConnection(); + if (connection is OrmLiteConnection ormliteConn) + { + await ormliteConn.OpenAsync(token).ConfigAwait(); + return connection; + } - var connection = AutoDisposeConnection - ? new OrmLiteConnection(this) - : OrmLiteConnection; + await DialectProvider.OpenAsync(connection, token).ConfigAwait(); + return connection; + } + + public virtual async Task OpenDbConnectionAsync(string namedConnection, CancellationToken token = default) + { + var connection = CreateDbConnection(namedConnection); + if (connection is OrmLiteConnection ormliteConn) + { + await ormliteConn.OpenAsync(token).ConfigAwait(); + return connection; + } + await DialectProvider.OpenAsync(connection, token).ConfigAwait(); return connection; } public virtual IDbConnection OpenDbConnectionString(string connectionString) { if (connectionString == null) - throw new ArgumentNullException("connectionString"); + throw new ArgumentNullException(nameof(connectionString)); - var connection = new OrmLiteConnection(this) { + var connection = new OrmLiteConnection(this) + { ConnectionString = connectionString }; @@ -101,15 +139,54 @@ public virtual IDbConnection OpenDbConnectionString(string connectionString) return connection; } - public virtual IDbConnection OpenDbConnection(string connectionKey) + public virtual async Task OpenDbConnectionStringAsync(string connectionString, CancellationToken token = default) { - OrmLiteConnectionFactory factory; - if (!NamedConnections.TryGetValue(connectionKey, out factory)) - throw new KeyNotFoundException("No factory registered is named " + connectionKey); + if (connectionString == null) + throw new ArgumentNullException(nameof(connectionString)); - IDbConnection connection = factory.AutoDisposeConnection - ? new OrmLiteConnection(factory) - : factory.OrmLiteConnection; + var connection = new OrmLiteConnection(this) + { + ConnectionString = connectionString + }; + + await connection.OpenAsync(token).ConfigAwait(); + + return connection; + } + + public virtual IDbConnection OpenDbConnectionString(string connectionString, string providerName) + { + if (connectionString == null) + throw new ArgumentNullException(nameof(connectionString)); + if (providerName == null) + throw new ArgumentNullException(nameof(providerName)); + + if (!DialectProviders.TryGetValue(providerName, out var dialectProvider)) + throw new ArgumentException($"{providerName} is not a registered DialectProvider"); + + var dbFactory = new OrmLiteConnectionFactory(connectionString, dialectProvider, setGlobalDialectProvider:false); + + return dbFactory.OpenDbConnection(); + } + + public virtual async Task OpenDbConnectionStringAsync(string connectionString, string providerName, CancellationToken token = default) + { + if (connectionString == null) + throw new ArgumentNullException(nameof(connectionString)); + if (providerName == null) + throw new ArgumentNullException(nameof(providerName)); + + if (!DialectProviders.TryGetValue(providerName, out var dialectProvider)) + throw new ArgumentException($"{providerName} is not a registered DialectProvider"); + + var dbFactory = new OrmLiteConnectionFactory(connectionString, dialectProvider, setGlobalDialectProvider:false); + + return await dbFactory.OpenDbConnectionAsync(token).ConfigAwait(); + } + + public virtual IDbConnection OpenDbConnection(string namedConnection) + { + var connection = CreateDbConnection(namedConnection); //moved setting up the ConnectionFilter to OrmLiteConnection.Open //connection = factory.ConnectionFilter(connection); @@ -118,37 +195,58 @@ public virtual IDbConnection OpenDbConnection(string connectionKey) return connection; } - private static Dictionary namedConnections; - public static Dictionary NamedConnections + private static Dictionary dialectProviders; + public static Dictionary DialectProviders => dialectProviders ??= new Dictionary(); + + public virtual void RegisterDialectProvider(string providerName, IOrmLiteDialectProvider dialectProvider) { - get - { - return namedConnections = namedConnections - ?? (namedConnections = new Dictionary()); - } + DialectProviders[providerName] = dialectProvider; } - public virtual void RegisterConnection(string connectionKey, string connectionString, IOrmLiteDialectProvider dialectProvider) + private static Dictionary namedConnections; + public static Dictionary NamedConnections => namedConnections ??= new Dictionary(); + + public virtual void RegisterConnection(string namedConnection, string connectionString, IOrmLiteDialectProvider dialectProvider) { - RegisterConnection(connectionKey, new OrmLiteConnectionFactory(connectionString, dialectProvider, setGlobalDialectProvider: false)); + RegisterConnection(namedConnection, new OrmLiteConnectionFactory(connectionString, dialectProvider, setGlobalDialectProvider: false)); } - public virtual void RegisterConnection(string connectionKey, OrmLiteConnectionFactory connectionFactory) + public virtual void RegisterConnection(string namedConnection, OrmLiteConnectionFactory connectionFactory) { - NamedConnections[connectionKey] = connectionFactory; + NamedConnections[namedConnection] = connectionFactory; } } public static class OrmLiteConnectionFactoryExtensions { /// - /// Alias for OpenDbConnection + /// Alias for /// public static IDbConnection Open(this IDbConnectionFactory connectionFactory) { return connectionFactory.OpenDbConnection(); } + /// + /// Alias for OpenDbConnectionAsync + /// + public static Task OpenDbConnectionAsync(this IDbConnectionFactory connectionFactory, CancellationToken token = default) + { + return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionAsync(token); + } + public static Task OpenAsync(this IDbConnectionFactory connectionFactory, CancellationToken token = default) + { + return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionAsync(token); + } + + /// + /// Alias for OpenDbConnectionAsync + /// + public static Task OpenAsync(this IDbConnectionFactory connectionFactory, string namedConnection, CancellationToken token = default) + { + return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionAsync(namedConnection, token); + } + /// /// Alias for OpenDbConnection /// @@ -157,38 +255,131 @@ public static IDbConnection Open(this IDbConnectionFactory connectionFactory, st return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnection(namedConnection); } + /// + /// Alias for OpenDbConnection + /// public static IDbConnection OpenDbConnection(this IDbConnectionFactory connectionFactory, string namedConnection) { return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnection(namedConnection); } + public static Task OpenDbConnectionAsync(this IDbConnectionFactory connectionFactory, string namedConnection, CancellationToken token = default) + { + return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionAsync(namedConnection, token); + } + + /// + /// Alias for OpenDbConnection + /// public static IDbConnection OpenDbConnectionString(this IDbConnectionFactory connectionFactory, string connectionString) { return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionString(connectionString); } + public static IDbConnection OpenDbConnectionString(this IDbConnectionFactory connectionFactory, string connectionString, string providerName) + { + return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionString(connectionString, providerName); + } + + public static Task OpenDbConnectionStringAsync(this IDbConnectionFactory connectionFactory, string connectionString, CancellationToken token = default) + { + return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionStringAsync(connectionString, token); + } + + public static Task OpenDbConnectionStringAsync(this IDbConnectionFactory connectionFactory, string connectionString, string providerName, CancellationToken token = default) + { + return ((OrmLiteConnectionFactory)connectionFactory).OpenDbConnectionStringAsync(connectionString, providerName, token); + } + + + public static IOrmLiteDialectProvider GetDialectProvider(this IDbConnectionFactory connectionFactory, ConnectionInfo dbInfo) + { + return dbInfo != null + ? GetDialectProvider(connectionFactory, providerName:dbInfo.ProviderName, namedConnection:dbInfo.NamedConnection) + : ((OrmLiteConnectionFactory) connectionFactory).DialectProvider; + } + + public static IOrmLiteDialectProvider GetDialectProvider(this IDbConnectionFactory connectionFactory, + string providerName = null, string namedConnection = null) + { + var dbFactory = (OrmLiteConnectionFactory) connectionFactory; + + if (!string.IsNullOrEmpty(providerName)) + return OrmLiteConnectionFactory.DialectProviders.TryGetValue(providerName, out var provider) + ? provider + : throw new NotSupportedException($"Dialect provider is not registered '{provider}'"); + + if (!string.IsNullOrEmpty(namedConnection)) + return OrmLiteConnectionFactory.NamedConnections.TryGetValue(namedConnection, out var namedFactory) + ? namedFactory.DialectProvider + : throw new NotSupportedException($"Named connection is not registered '{namedConnection}'"); + + return dbFactory.DialectProvider; + } + public static IDbConnection ToDbConnection(this IDbConnection db) { - var hasDb = db as IHasDbConnection; - return hasDb != null - ? hasDb.DbConnection + return db is IHasDbConnection hasDb + ? hasDb.DbConnection.ToDbConnection() : db; } public static IDbCommand ToDbCommand(this IDbCommand dbCmd) { - var hasDbCmd = dbCmd as IHasDbCommand; - return hasDbCmd != null - ? hasDbCmd.DbCommand + return dbCmd is IHasDbCommand hasDbCmd + ? hasDbCmd.DbCommand.ToDbCommand() : dbCmd; } public static IDbTransaction ToDbTransaction(this IDbTransaction dbTrans) { - var hasDbTrans = dbTrans as IHasDbTransaction; - return hasDbTrans != null - ? hasDbTrans.Transaction + return dbTrans is IHasDbTransaction hasDbTrans + ? hasDbTrans.DbTransaction : dbTrans; } + + public static void RegisterConnection(this IDbConnectionFactory dbFactory, string namedConnection, string connectionString, IOrmLiteDialectProvider dialectProvider) + { + ((OrmLiteConnectionFactory)dbFactory).RegisterConnection(namedConnection, connectionString, dialectProvider); + } + + public static void RegisterConnection(this IDbConnectionFactory dbFactory, string namedConnection, OrmLiteConnectionFactory connectionFactory) + { + ((OrmLiteConnectionFactory)dbFactory).RegisterConnection(namedConnection, connectionFactory); + } + + public static IDbConnection OpenDbConnection(this IDbConnectionFactory dbFactory, ConnectionInfo connInfo) + { + if (dbFactory is IDbConnectionFactoryExtended dbFactoryExt && connInfo != null) + { + if (connInfo.ConnectionString != null) + { + return connInfo.ProviderName != null + ? dbFactoryExt.OpenDbConnectionString(connInfo.ConnectionString, connInfo.ProviderName) + : dbFactoryExt.OpenDbConnectionString(connInfo.ConnectionString); + } + + if (connInfo.NamedConnection != null) + return dbFactoryExt.OpenDbConnection(connInfo.NamedConnection); + } + return dbFactory.Open(); + } + + public static async Task OpenDbConnectionAsync(this IDbConnectionFactory dbFactory, ConnectionInfo connInfo) + { + if (dbFactory is IDbConnectionFactoryExtended dbFactoryExt && connInfo != null) + { + if (connInfo.ConnectionString != null) + { + return connInfo.ProviderName != null + ? await dbFactoryExt.OpenDbConnectionStringAsync(connInfo.ConnectionString, connInfo.ProviderName).ConfigAwait() + : await dbFactoryExt.OpenDbConnectionStringAsync(connInfo.ConnectionString).ConfigAwait(); + } + + if (connInfo.NamedConnection != null) + return await dbFactoryExt.OpenDbConnectionAsync(connInfo.NamedConnection).ConfigAwait(); + } + return await dbFactory.OpenAsync().ConfigAwait(); + } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteContext.cs b/src/ServiceStack.OrmLite/OrmLiteContext.cs index c3b50880c..3309cf708 100644 --- a/src/ServiceStack.OrmLite/OrmLiteContext.cs +++ b/src/ServiceStack.OrmLite/OrmLiteContext.cs @@ -3,7 +3,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; +#if !NETCORE using System.Runtime.Remoting.Messaging; +#endif using System.Threading; namespace ServiceStack.OrmLite @@ -21,25 +23,29 @@ public class OrmLiteContext [ThreadStatic] public static IDictionary ContextItems; +#if NETCORE + AsyncLocal localContextItems = new(); +#endif + /// /// Gets a list of items for this context. /// public virtual IDictionary Items { - get - { - return GetItems() ?? (CreateItems()); - } - set - { - CreateItems(value); - } + get => GetItems() ?? (CreateItems()); + set => CreateItems(value); } private const string _key = "__OrmLite.Items"; private IDictionary GetItems() { +#if NETCORE + if (UseThreadStatic) + return ContextItems; + + return localContextItems.Value; +#else try { if (UseThreadStatic) @@ -52,29 +58,57 @@ private IDictionary GetItems() //Fixed in Mono master: https://github.com/mono/mono/pull/817 return CallContext.GetData(_key) as IDictionary; } +#endif } private IDictionary CreateItems(IDictionary items = null) { +#if NETCORE + if (UseThreadStatic) + { + ContextItems = items ??= new Dictionary(); + } + else + { + localContextItems.Value = items ??= new ConcurrentDictionary(); + } +#else try { if (UseThreadStatic) { - ContextItems = items ?? (items = new Dictionary()); + ContextItems = items ??= new Dictionary(); } else { - CallContext.LogicalSetData(_key, items ?? (items = new ConcurrentDictionary())); + CallContext.LogicalSetData(_key, items ??= new ConcurrentDictionary()); } } catch (NotImplementedException) { //Fixed in Mono master: https://github.com/mono/mono/pull/817 - CallContext.SetData(_key, items ?? (items = new ConcurrentDictionary())); + CallContext.SetData(_key, items ??= new ConcurrentDictionary()); } +#endif return items; } + public void ClearItems() + { + if (UseThreadStatic) + { + ContextItems = new Dictionary(); + } + else + { +#if NETCORE + localContextItems.Value = new ConcurrentDictionary(); +#else + CallContext.FreeNamedDataSlot(_key); +#endif + } + } + public T GetOrCreate(Func createFn) { if (Items.Contains(typeof(T).Name)) @@ -104,7 +138,7 @@ public static OrmLiteState CreateNewState() public static OrmLiteState GetOrCreateState() { - return (OrmLiteState as OrmLiteState) + return OrmLiteState ?? CreateNewState(); } @@ -114,13 +148,10 @@ public static OrmLiteState OrmLiteState { if (Instance.Items.Contains("OrmLiteState")) return Instance.Items["OrmLiteState"] as OrmLiteState; - else - return null; - } - set - { - SetItem("OrmLiteState", value); + + return null; } + set => SetItem("OrmLiteState", value); } //Only used when using OrmLite API's against a native IDbConnection (i.e. not from DbFactory) @@ -129,11 +160,9 @@ internal static IDbTransaction TSTransaction get { var state = OrmLiteState; - return state != null - ? state.TSTransaction - : null; + return state?.TSTransaction; } - set { GetOrCreateState().TSTransaction = value; } + set => GetOrCreateState().TSTransaction = value; } } @@ -152,7 +181,7 @@ public OrmLiteState() public override string ToString() { - return "State Id: {0}".Fmt(Id); + return $"State Id: {Id}"; } } } diff --git a/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs b/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs index c0973b653..3d7685d56 100644 --- a/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs +++ b/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs @@ -1,1553 +1,1853 @@ -// -// ServiceStack.OrmLite: Light-weight POCO ORM for .NET and Mono -// -// Authors: -// Demis Bellot (demis.bellot@gmail.com) -// -// Copyright 2013 Service Stack LLC. All Rights Reserved. -// -// Licensed under the same terms of ServiceStack. -// - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Data; -using System.Globalization; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using ServiceStack.DataAnnotations; -using ServiceStack.Logging; -using ServiceStack.Text; -using System.Linq.Expressions; - -namespace ServiceStack.OrmLite -{ - public abstract class OrmLiteDialectProviderBase - : IOrmLiteDialectProvider - where TDialect : IOrmLiteDialectProvider - { - protected static readonly ILog Log = LogManager.GetLogger(typeof(IOrmLiteDialectProvider)); - - protected OrmLiteDialectProviderBase() - { - UpdateStringColumnDefinitions(); - StringSerializer = new JsvStringSerializer(); - } - - #region ADO.NET supported types - /* ADO.NET UNDERSTOOD DATA TYPES: - COUNTER DbType.Int64 - AUTOINCREMENT DbType.Int64 - IDENTITY DbType.Int64 - LONG DbType.Int64 - TINYINT DbType.Byte - INTEGER DbType.Int64 - INT DbType.Int32 - VARCHAR DbType.String - NVARCHAR DbType.String - CHAR DbType.String - NCHAR DbType.String - TEXT DbType.String - NTEXT DbType.String - STRING DbType.String - DOUBLE DbType.Double - FLOAT DbType.Double - REAL DbType.Single - BIT DbType.Boolean - YESNO DbType.Boolean - LOGICAL DbType.Boolean - BOOL DbType.Boolean - NUMERIC DbType.Decimal - DECIMAL DbType.Decimal - MONEY DbType.Decimal - CURRENCY DbType.Decimal - TIME DbType.DateTime - DATE DbType.DateTime - TIMESTAMP DbType.DateTime - DATETIME DbType.DateTime - BLOB DbType.Binary - BINARY DbType.Binary - VARBINARY DbType.Binary - IMAGE DbType.Binary - GENERAL DbType.Binary - OLEOBJECT DbType.Binary - GUID DbType.Guid - UNIQUEIDENTIFIER DbType.Guid - MEMO DbType.String - NOTE DbType.String - LONGTEXT DbType.String - LONGCHAR DbType.String - SMALLINT DbType.Int16 - BIGINT DbType.Int64 - LONGVARCHAR DbType.String - SMALLDATE DbType.DateTime - SMALLDATETIME DbType.DateTime - */ - #endregion - - public IOrmLiteExecFilter ExecFilter { get; set; } - - public string StringLengthNonUnicodeColumnDefinitionFormat = "VARCHAR({0})"; - public string StringLengthUnicodeColumnDefinitionFormat = "NVARCHAR({0})"; - - //Set by Constructor and UpdateStringColumnDefinitions() - public string StringColumnDefinition; - public string StringLengthColumnDefinitionFormat; - - private string maxStringColumnDefinition; - public string MaxStringColumnDefinition - { - get { return maxStringColumnDefinition ?? StringColumnDefinition; } - set { maxStringColumnDefinition = value; } - } - - public string AutoIncrementDefinition = "AUTOINCREMENT"; //SqlServer express limit - public string IntColumnDefinition = "INTEGER"; - public string LongColumnDefinition = "BIGINT"; - public string GuidColumnDefinition = "GUID"; - public string BoolColumnDefinition = "BOOL"; - public string RealColumnDefinition = "DOUBLE"; - public string DecimalColumnDefinition = "DECIMAL"; - public string BlobColumnDefinition = "BLOB"; - public string DateTimeColumnDefinition = "DATETIME"; - public string TimeColumnDefinition = "BIGINT"; - public string DateTimeOffsetColumnDefinition = "DATETIMEOFFSET"; - - private int defaultDecimalPrecision = 18; - private int defaultDecimalScale = 12; - - public int DefaultDecimalPrecision - { - get { return defaultDecimalPrecision; } - set { defaultDecimalPrecision = value; } - } - - public int DefaultDecimalScale - { - get { return defaultDecimalScale; } - set { defaultDecimalScale = value; } - } - - private int defaultStringLength = 8000; //SqlServer express limit - public int DefaultStringLength - { - get - { - return defaultStringLength; - } - set - { - defaultStringLength = value; - UpdateStringColumnDefinitions(); - } - } - - private string paramString = "@"; - public string ParamString - { - get { return paramString; } - set { paramString = value; } - } - - protected bool useUnicode; - public virtual bool UseUnicode - { - get - { - return useUnicode; - } - set - { - useUnicode = value; - UpdateStringColumnDefinitions(); - } - } - - private INamingStrategy namingStrategy = new OrmLiteNamingStrategyBase(); - public INamingStrategy NamingStrategy - { - get - { - return namingStrategy; - } - set - { - namingStrategy = value; - } - } - - public IStringSerializer StringSerializer { get; set; } - - public virtual void UpdateStringColumnDefinitions() - { - this.StringLengthColumnDefinitionFormat = useUnicode - ? StringLengthUnicodeColumnDefinitionFormat - : StringLengthNonUnicodeColumnDefinitionFormat; - - this.StringColumnDefinition = string.Format( - this.StringLengthColumnDefinitionFormat, DefaultStringLength); - } - - protected DbTypes DbTypeMap = new DbTypes(); - protected void InitColumnTypeMap() - { - DbTypeMap.Set(DbType.String, StringColumnDefinition); - DbTypeMap.Set(DbType.StringFixedLength, StringColumnDefinition); - DbTypeMap.Set(DbType.StringFixedLength, StringColumnDefinition); - DbTypeMap.Set(DbType.String, StringColumnDefinition); - DbTypeMap.Set(DbType.Boolean, BoolColumnDefinition); - DbTypeMap.Set(DbType.Boolean, BoolColumnDefinition); - DbTypeMap.Set(DbType.Guid, GuidColumnDefinition); - DbTypeMap.Set(DbType.Guid, GuidColumnDefinition); - DbTypeMap.Set(DbType.DateTime, DateTimeColumnDefinition); - DbTypeMap.Set(DbType.DateTime, DateTimeColumnDefinition); - - DbTypeMap.Set(DbType.Int64, TimeColumnDefinition); //using ticks - DbTypeMap.Set(DbType.Int64, TimeColumnDefinition); - DbTypeMap.Set(DbType.DateTimeOffset, DateTimeOffsetColumnDefinition); - DbTypeMap.Set(DbType.DateTimeOffset, DateTimeOffsetColumnDefinition); - - DbTypeMap.Set(DbType.Byte, IntColumnDefinition); - DbTypeMap.Set(DbType.Byte, IntColumnDefinition); - DbTypeMap.Set(DbType.SByte, IntColumnDefinition); - DbTypeMap.Set(DbType.SByte, IntColumnDefinition); - DbTypeMap.Set(DbType.Int16, IntColumnDefinition); - DbTypeMap.Set(DbType.Int16, IntColumnDefinition); - DbTypeMap.Set(DbType.UInt16, IntColumnDefinition); - DbTypeMap.Set(DbType.UInt16, IntColumnDefinition); - DbTypeMap.Set(DbType.Int32, IntColumnDefinition); - DbTypeMap.Set(DbType.Int32, IntColumnDefinition); - DbTypeMap.Set(DbType.UInt32, IntColumnDefinition); - DbTypeMap.Set(DbType.UInt32, IntColumnDefinition); - - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); - DbTypeMap.Set(DbType.Int64, LongColumnDefinition); - DbTypeMap.Set(DbType.UInt64, LongColumnDefinition); - DbTypeMap.Set(DbType.UInt64, LongColumnDefinition); - - DbTypeMap.Set(DbType.Single, RealColumnDefinition); - DbTypeMap.Set(DbType.Single, RealColumnDefinition); - DbTypeMap.Set(DbType.Double, RealColumnDefinition); - DbTypeMap.Set(DbType.Double, RealColumnDefinition); - - DbTypeMap.Set(DbType.Decimal, DecimalColumnDefinition); - DbTypeMap.Set(DbType.Decimal, DecimalColumnDefinition); - - DbTypeMap.Set(DbType.Binary, BlobColumnDefinition); - - DbTypeMap.Set(DbType.String, StringColumnDefinition); - - OnAfterInitColumnTypeMap(); - } - - public virtual void OnAfterInitColumnTypeMap() - { - } - - public string DefaultValueFormat = " DEFAULT ({0})"; - - public virtual bool ShouldQuoteValue(Type fieldType) - { - string fieldDefinition; - if (!DbTypeMap.ColumnTypeMap.TryGetValue(fieldType, out fieldDefinition)) - { - fieldDefinition = this.GetUndefinedColumnDefinition(fieldType, null); - } - - return fieldDefinition != IntColumnDefinition - && fieldDefinition != LongColumnDefinition - && fieldDefinition != RealColumnDefinition - && fieldDefinition != DecimalColumnDefinition - && fieldDefinition != BoolColumnDefinition; - } - - /// - /// Populates row fields during re-hydration of results. - /// - public virtual void SetDbValue(FieldDefinition fieldDef, IDataReader reader, int colIndex, object instance) - { - if (OrmLiteUtils.HandledDbNullValue(fieldDef, reader, colIndex, instance)) return; - - var convertedValue = ConvertDbValue(reader.GetValue(colIndex), fieldDef.FieldType); - try - { - fieldDef.SetValueFn(instance, convertedValue); - } - catch (NullReferenceException ignore) { } - } - - - public abstract IDbConnection CreateConnection(string filePath, Dictionary options); - - public virtual string GetQuotedValue(string paramValue) - { - return "'" + paramValue.Replace("'", "''") + "'"; - } - - public virtual string GetTableName(ModelDefinition modelDef) - { - return GetTableName(modelDef.ModelName, modelDef.Schema); - } - - public virtual string GetTableName(string table, string schema = null) - { - return schema != null - ? string.Format("{0}.{1}", - NamingStrategy.GetSchemaName(schema), - NamingStrategy.GetTableName(table)) - : NamingStrategy.GetTableName(table); - } - - public virtual string GetQuotedTableName(ModelDefinition modelDef) - { - return GetQuotedTableName(modelDef.ModelName, modelDef.Schema); - } - - public virtual string GetQuotedTableName(string tableName, string schema = null) - { - if (schema == null) - return GetQuotedName(NamingStrategy.GetTableName(tableName)); - - var escapedSchema = NamingStrategy.GetSchemaName(schema) - .Replace(".", "\".\""); - - return GetQuotedName(escapedSchema) - + "." - + GetQuotedName(NamingStrategy.GetTableName(tableName)); - } - - public virtual string GetQuotedColumnName(string columnName) - { - return GetQuotedName(namingStrategy.GetColumnName(columnName)); - } - - public virtual string GetQuotedName(string name) - { - return string.Format("\"{0}\"", name); - } - - public virtual string SanitizeFieldNameForParamName(string fieldName) - { - return (fieldName ?? "").Replace(" ", ""); - } - - protected virtual string GetUndefinedColumnDefinition(Type fieldType, int? fieldLength) - { - return fieldLength.HasValue - ? string.Format(StringLengthColumnDefinitionFormat, fieldLength.GetValueOrDefault(DefaultStringLength)) - : MaxStringColumnDefinition; - } - - public virtual string GetColumnDefinition(string fieldName, Type fieldType, - bool isPrimaryKey, bool autoIncrement, bool isNullable, bool isRowVersion, - int? fieldLength, int? scale, string defaultValue, string customFieldDefinition) - { - string fieldDefinition; - - if (customFieldDefinition != null) - { - fieldDefinition = customFieldDefinition; - } - else if (fieldType == typeof(string)) - { - fieldDefinition = fieldLength == StringLengthAttribute.MaxText - ? MaxStringColumnDefinition - : string.Format(StringLengthColumnDefinitionFormat, fieldLength.GetValueOrDefault(DefaultStringLength)); - } - else - { - if (!DbTypeMap.ColumnTypeMap.TryGetValue(fieldType, out fieldDefinition)) - { - fieldDefinition = this.GetUndefinedColumnDefinition(fieldType, fieldLength); - } - } - - var sql = new StringBuilder(); - sql.AppendFormat("{0} {1}", GetQuotedColumnName(fieldName), fieldDefinition); - - if (isPrimaryKey) - { - sql.Append(" PRIMARY KEY"); - if (autoIncrement) - { - sql.Append(" ").Append(AutoIncrementDefinition); - } - } - else - { - if (isNullable) - { - sql.Append(" NULL"); - } - else - { - sql.Append(" NOT NULL"); - } - } - - if (!string.IsNullOrEmpty(defaultValue)) - { - sql.AppendFormat(DefaultValueFormat, defaultValue); - } - - return sql.ToString(); - } - - public virtual string SelectIdentitySql { get; set; } - - public virtual long GetLastInsertId(IDbCommand dbCmd) - { - if (SelectIdentitySql == null) - throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider."); - - dbCmd.CommandText = SelectIdentitySql; - return dbCmd.ExecLongScalar(); - } - - public virtual long InsertAndGetLastInsertId(IDbCommand dbCmd) - { - if (SelectIdentitySql == null) - throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider."); - - dbCmd.CommandText += "; " + SelectIdentitySql; - - return dbCmd.ExecLongScalar(); - } - - // Fmt - public virtual string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams) - { - const string SelectStatement = "SELECT"; - var isFullSelectStatement = - !string.IsNullOrEmpty(sqlFilter) - && sqlFilter.TrimStart().StartsWith(SelectStatement, StringComparison.OrdinalIgnoreCase); - - if (isFullSelectStatement) - return sqlFilter.SqlFmt(filterParams); - - var modelDef = tableType.GetModelDefinition(); - var sql = new StringBuilder(); - sql.AppendFormat("SELECT {0} FROM {1}", - GetColumnNames(modelDef), - GetQuotedTableName(modelDef)); - - if (!string.IsNullOrEmpty(sqlFilter)) - { - sqlFilter = sqlFilter.SqlFmt(filterParams); - if (!sqlFilter.StartsWith("ORDER ", StringComparison.OrdinalIgnoreCase) - && !sqlFilter.StartsWith("LIMIT ", StringComparison.OrdinalIgnoreCase)) - { - sql.Append(" WHERE "); - } - - sql.Append(sqlFilter); - } - - return sql.ToString(); - } - - public virtual string ToSelectStatement(ModelDefinition modelDef, - string selectExpression, - string bodyExpression, - string orderByExpression = null, - int? offset = null, - int? rows = null) - { - - var sb = new StringBuilder(selectExpression); - sb.Append(bodyExpression); - if (orderByExpression != null) - { - sb.Append(orderByExpression); - } - - if (offset != null || rows != null) - { - sb.Append("\nLIMIT "); - if (offset == null) - { - sb.Append(rows); - } - else - { - sb.Append(rows.GetValueOrDefault(int.MaxValue)).Append(" OFFSET ").Append(offset); - } - } - - return sb.ToString(); - } - - public virtual string GetRowVersionColumnName(FieldDefinition field) - { - return GetQuotedColumnName(field.FieldName); - } - - public virtual string GetColumnNames(ModelDefinition modelDef) - { - var sqlColumns = new StringBuilder(); - foreach (var field in modelDef.FieldDefinitions) - { - if (sqlColumns.Length > 0) - sqlColumns.Append(", "); - - sqlColumns.Append(field.GetQuotedName(this)); - } - - return sqlColumns.ToString(); - } - - /// Fmt - public virtual string ToInsertRowStatement(IDbCommand command, object objWithProperties, ICollection insertFields = null) - { - if (insertFields == null) - insertFields = new List(); - - var sbColumnNames = new StringBuilder(); - var sbColumnValues = new StringBuilder(); - var modelDef = objWithProperties.GetType().GetModelDefinition(); - - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.ShouldSkipInsert()) - continue; - - //insertFields contains Property "Name" of fields to insert ( that's how expressions work ) - if (insertFields.Count > 0 && !insertFields.Contains(fieldDef.Name)) - continue; - - if (sbColumnNames.Length > 0) sbColumnNames.Append(","); - if (sbColumnValues.Length > 0) sbColumnValues.Append(","); - - try - { - sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); - sbColumnValues.Append(fieldDef.GetQuotedValue(objWithProperties, this)); - } - catch (Exception ex) - { - Log.Error("ERROR in ToInsertRowStatement(): " + ex.Message, ex); - throw; - } - } - - var sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", - GetQuotedTableName(modelDef), sbColumnNames, sbColumnValues); - - return sql; - } - - public virtual void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null) - { - var sbColumnNames = new StringBuilder(); - var sbColumnValues = new StringBuilder(); - var modelDef = typeof(T).GetModelDefinition(); - - cmd.Parameters.Clear(); - cmd.CommandTimeout = OrmLiteConfig.CommandTimeout; - - foreach (var fieldDef in modelDef.FieldDefinitionsArray) - { - if (fieldDef.ShouldSkipInsert()) - continue; - - //insertFields contains Property "Name" of fields to insert ( that's how expressions work ) - if (insertFields != null && !insertFields.Contains(fieldDef.Name)) - continue; - - if (sbColumnNames.Length > 0) - sbColumnNames.Append(","); - if (sbColumnValues.Length > 0) - sbColumnValues.Append(","); - - try - { - sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); - sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); - - AddParameter(cmd, fieldDef); - } - catch (Exception ex) - { - Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex); - throw; - } - } - - cmd.CommandText = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", - GetQuotedTableName(modelDef), sbColumnNames, sbColumnValues); - } - - public virtual bool PrepareParameterizedUpdateStatement(IDbCommand cmd, ICollection updateFields = null) - { - var sqlFilter = new StringBuilder(); - var sql = new StringBuilder(); - var modelDef = typeof(T).GetModelDefinition(); - var hadRowVesion = false; - var updateAllFields = updateFields == null || updateFields.Count == 0; - - cmd.Parameters.Clear(); - cmd.CommandTimeout = OrmLiteConfig.CommandTimeout; - - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.ShouldSkipUpdate()) - continue; - - try - { - if ((fieldDef.IsPrimaryKey || fieldDef.IsRowVersion) && updateAllFields) - { - if (sqlFilter.Length > 0) - sqlFilter.Append(" AND "); - - AppendFieldCondition(sqlFilter, fieldDef, cmd); - - if (fieldDef.IsRowVersion) - hadRowVesion = true; - - continue; - } - - if (!updateAllFields && !updateFields.Contains(fieldDef.Name)) - continue; - - if (sql.Length > 0) - sql.Append(", "); - - AppendFieldCondition(sql, fieldDef, cmd); - } - catch (Exception ex) - { - Log.Error("ERROR in PrepareParameterizedUpdateStatement(): " + ex.Message, ex); - } - } - - if (sql.Length > 0) - { - cmd.CommandText = string.Format("UPDATE {0} SET {1} {2}", - GetQuotedTableName(modelDef), sql, (sqlFilter.Length > 0 ? "WHERE " + sqlFilter : "")); - } - - return hadRowVesion; - } - - public virtual void AppendFieldCondition(StringBuilder sqlFilter, FieldDefinition fieldDef, IDbCommand cmd) - { - sqlFilter - .Append(GetQuotedColumnName(fieldDef.FieldName)) - .Append("=") - .Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); - - AddParameter(cmd, fieldDef); - } - - public virtual void AppendFieldConditionFmt(StringBuilder sqlFilter, FieldDefinition fieldDef, object objWithProperties) - { - sqlFilter.AppendFormat("{0}={1}", - GetQuotedColumnName(fieldDef.FieldName), - fieldDef.GetQuotedValue(objWithProperties, this)); - } - - public virtual bool PrepareParameterizedDeleteStatement(IDbCommand cmd, IDictionary deleteFields) - { - if (deleteFields == null || deleteFields.Count == 0) - throw new ArgumentException("DELETE's must have at least 1 criteria"); - - var sqlFilter = new StringBuilder(); - var modelDef = typeof(T).GetModelDefinition(); - var hadRowVesion = false; - - cmd.Parameters.Clear(); - cmd.CommandTimeout = OrmLiteConfig.CommandTimeout; - - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.ShouldSkipDelete()) - continue; - - object fieldValue; - - if (!deleteFields.TryGetValue(fieldDef.Name, out fieldValue)) - continue; - - if (fieldDef.IsRowVersion) - hadRowVesion = true; - - try - { - if (sqlFilter.Length > 0) - sqlFilter.Append(" AND "); - - if (fieldValue != null) - { - AppendFieldCondition(sqlFilter, fieldDef, cmd); - } - else - { - sqlFilter - .Append(GetQuotedColumnName(fieldDef.FieldName)) - .Append(" IS NULL"); - } - } - catch (Exception ex) - { - Log.Error("ERROR in PrepareParameterizedDeleteStatement(): " + ex.Message, ex); - } - } - - cmd.CommandText = string.Format("DELETE FROM {0} WHERE {1}", - GetQuotedTableName(modelDef), sqlFilter); - - return hadRowVesion; - } - - public virtual void PrepareStoredProcedureStatement(IDbCommand cmd, T obj) - { - cmd.CommandText = ToExecuteProcedureStatement(obj); - cmd.CommandType = CommandType.StoredProcedure; - } - - protected void AddParameter(IDbCommand cmd, FieldDefinition fieldDef) - { - var p = cmd.CreateParameter(); - SetParameter(fieldDef, p); - cmd.Parameters.Add(p); - } - - public virtual void SetParameter(FieldDefinition fieldDef, IDbDataParameter p) - { - p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)); - - DbType dbType; - var sqlDbType = DbTypeMap.ColumnDbTypeMap.TryGetValue(fieldDef.ColumnType, out dbType) - ? dbType - : DbType.String; - - p.DbType = sqlDbType; - } - - public virtual void SetParameterValues(IDbCommand dbCmd, object obj) - { - var modelDef = GetModel(typeof(T)); - var fieldMap = GetFieldDefinitionMap(modelDef); - - foreach (IDataParameter p in dbCmd.Parameters) - { - FieldDefinition fieldDef; - var fieldName = this.ToFieldName(p.ParameterName); - fieldMap.TryGetValue(fieldName, out fieldDef); - - if (fieldDef == null) - throw new ArgumentException("Field Definition '{0}' was not found".Fmt(fieldName)); - - SetParameterValue(fieldDef, p, obj); - } - } - - public Dictionary GetFieldDefinitionMap(ModelDefinition modelDef) - { - return modelDef.GetFieldDefinitionMap(SanitizeFieldNameForParamName); - } - - public virtual void SetParameterValue(FieldDefinition fieldDef, IDataParameter p, object obj) - { - var value = GetValueOrDbNull(fieldDef, obj); - p.Value = value; - } - - protected virtual object GetValue(FieldDefinition fieldDef, object obj) - { - var value = obj is T - ? fieldDef.GetValue(obj) - : GetAnonValue(fieldDef, obj); - - return GetFieldValue(fieldDef, value); - } - - public object GetFieldValue(FieldDefinition fieldDef, object value) - { - if (value != null) - { - if (fieldDef.IsRefType) - { - //Let ADO.NET providers handle byte[] - if (fieldDef.FieldType == typeof (byte[])) - { - return value; - } - return StringSerializer.SerializeToString(value); - } - if (fieldDef.FieldType.IsEnum) - { - var enumValue = StringSerializer.SerializeToString(value); - if (enumValue == null) - return null; - - enumValue = enumValue.Trim('"'); - long intEnum; - if (Int64.TryParse(enumValue, out intEnum)) - return intEnum; - - return enumValue; - } - if (fieldDef.FieldType == typeof (TimeSpan)) - { - var timespan = (TimeSpan) value; - return timespan.Ticks; - } - } - - return value; - } - - protected virtual object GetValueOrDbNull(FieldDefinition fieldDef, object obj) - { - var value = GetValue(fieldDef, obj); - return value ?? DBNull.Value; - } - - protected virtual object GetQuotedValueOrDbNull(FieldDefinition fieldDef, object obj) - { - var value = obj is T - ? fieldDef.GetValue(obj) - : GetAnonValue(fieldDef, obj); - - if (value == null) - return DBNull.Value; - - var unquotedVal = GetQuotedValue(value, fieldDef.FieldType) - .TrimStart('\'').TrimEnd('\''); ; - - if (string.IsNullOrEmpty(unquotedVal)) - return DBNull.Value; - - return unquotedVal; - } - - static readonly ConcurrentDictionary anonValueFnMap = - new ConcurrentDictionary(); - - protected virtual object GetAnonValue(FieldDefinition fieldDef, object obj) - { - var anonType = obj.GetType(); - var key = anonType.Name + "." + fieldDef.Name; - - var factoryFn = (Func)(_ => - anonType.GetProperty(fieldDef.Name).GetPropertyGetterFn()); - - var getterFn = anonValueFnMap.GetOrAdd(key, factoryFn); - - return getterFn(obj); - } - - public virtual string ToUpdateRowStatement(object objWithProperties, ICollection updateFields = null) - { - var sqlFilter = new StringBuilder(); - var sql = new StringBuilder(); - var modelDef = objWithProperties.GetType().GetModelDefinition(); - var updateAllFields = updateFields == null || updateFields.Count == 0; - - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.ShouldSkipUpdate()) - continue; - - try - { - if (fieldDef.IsPrimaryKey && updateAllFields) - { - if (sqlFilter.Length > 0) - sqlFilter.Append(" AND "); - - AppendFieldConditionFmt(sqlFilter, fieldDef, objWithProperties); - - continue; - } - - if (!updateAllFields && !updateFields.Contains(fieldDef.Name) || fieldDef.AutoIncrement) continue; - if (sql.Length > 0) - sql.Append(", "); - - AppendFieldConditionFmt(sql, fieldDef, objWithProperties); - } - catch (Exception ex) - { - Log.Error("ERROR in ToUpdateRowStatement(): " + ex.Message, ex); - } - } - - var updateSql = string.Format("UPDATE {0} SET {1}{2}", - GetQuotedTableName(modelDef), sql, (sqlFilter.Length > 0 ? " WHERE " + sqlFilter : "")); - - if (sql.Length == 0) - throw new Exception("No valid update properties provided (e.g. p => p.FirstName): " + updateSql); - - return updateSql; - } - - public virtual string ToDeleteRowStatement(object objWithProperties) - { - var sqlFilter = new StringBuilder(); - var modelDef = objWithProperties.GetType().GetModelDefinition(); - - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (fieldDef.ShouldSkipDelete()) - continue; - - try - { - if (fieldDef.IsPrimaryKey) - { - if (sqlFilter.Length > 0) - sqlFilter.Append(" AND "); - - AppendFieldConditionFmt(sqlFilter, fieldDef, objWithProperties); - } - } - catch (Exception ex) - { - Log.Error("ERROR in ToDeleteRowStatement(): " + ex.Message, ex); - } - } - - var deleteSql = string.Format("DELETE FROM {0} WHERE {1}", - GetQuotedTableName(modelDef), sqlFilter); - - return deleteSql; - } - - public virtual string ToDeleteStatement(Type tableType, string sqlFilter, params object[] filterParams) - { - var sql = new StringBuilder(); - const string deleteStatement = "DELETE "; - - var isFullDeleteStatement = - !string.IsNullOrEmpty(sqlFilter) - && sqlFilter.Length > deleteStatement.Length - && sqlFilter.Substring(0, deleteStatement.Length).ToUpper().Equals(deleteStatement); - - if (isFullDeleteStatement) - return sqlFilter.SqlFmt(filterParams); - - var modelDef = tableType.GetModelDefinition(); - sql.AppendFormat("DELETE FROM {0}", GetQuotedTableName(modelDef)); - if (!string.IsNullOrEmpty(sqlFilter)) - { - sqlFilter = sqlFilter.SqlFmt(filterParams); - sql.Append(" WHERE "); - sql.Append(sqlFilter); - } - - return sql.ToString(); - } - - public virtual string ToCreateTableStatement(Type tableType) - { - var sbColumns = new StringBuilder(); - var sbConstraints = new StringBuilder(); - - var modelDef = tableType.GetModelDefinition(); - foreach (var fieldDef in modelDef.FieldDefinitions) - { - var columnDefinition = GetColumnDefinition( - fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - - if (columnDefinition == null) - continue; - - if (sbColumns.Length != 0) - sbColumns.Append(", \n "); - - sbColumns.Append(columnDefinition); - - if (fieldDef.ForeignKey == null) continue; - - var refModelDef = fieldDef.ForeignKey.ReferenceType.GetModelDefinition(); - sbConstraints.AppendFormat( - ", \n\n CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2} ({3})", - GetQuotedName(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef)), - GetQuotedColumnName(fieldDef.FieldName), - GetQuotedTableName(refModelDef), - GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)); - - sbConstraints.Append(GetForeignKeyOnDeleteClause(fieldDef.ForeignKey)); - sbConstraints.Append(GetForeignKeyOnUpdateClause(fieldDef.ForeignKey)); - } - var sql = new StringBuilder(string.Format( - "CREATE TABLE {0} \n(\n {1}{2} \n); \n", GetQuotedTableName(modelDef), sbColumns, sbConstraints)); - - return sql.ToString(); - } - - public virtual string ToPostCreateTableStatement(ModelDefinition modelDef) - { - return null; - } - - public virtual string ToPostDropTableStatement(ModelDefinition modelDef) - { - return null; - } - - public virtual string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignKey) - { - return !string.IsNullOrEmpty(foreignKey.OnDelete) ? " ON DELETE " + foreignKey.OnDelete : ""; - } - - public virtual string GetForeignKeyOnUpdateClause(ForeignKeyConstraint foreignKey) - { - return !string.IsNullOrEmpty(foreignKey.OnUpdate) ? " ON UPDATE " + foreignKey.OnUpdate : ""; - } - - public virtual List ToCreateIndexStatements(Type tableType) - { - var sqlIndexes = new List(); - - var modelDef = tableType.GetModelDefinition(); - foreach (var fieldDef in modelDef.FieldDefinitions) - { - if (!fieldDef.IsIndexed) continue; - - var indexName = GetIndexName(fieldDef.IsUnique, modelDef.ModelName.SafeVarName(), fieldDef.FieldName); - - sqlIndexes.Add( - ToCreateIndexStatement(fieldDef.IsUnique, indexName, modelDef, fieldDef.FieldName, isCombined: false, fieldDef: fieldDef)); - } - - foreach (var compositeIndex in modelDef.CompositeIndexes) - { - var indexName = GetCompositeIndexName(compositeIndex, modelDef); - var indexNames = string.Join(" ASC, ", - compositeIndex.FieldNames.ConvertAll(GetQuotedName).ToArray()); - - sqlIndexes.Add( - ToCreateIndexStatement(compositeIndex.Unique, indexName, modelDef, indexNames, true)); - } - - return sqlIndexes; - } - - public virtual DbType GetColumnDbType(Type valueType) - { - if (valueType.IsEnum) - return DbTypeMap.ColumnDbTypeMap[typeof(string)]; - - return DbTypeMap.ColumnDbTypeMap[valueType]; - } - - public virtual string GetColumnTypeDefinition(Type fieldType) - { - string fieldDefinition; - DbTypeMap.ColumnTypeMap.TryGetValue(fieldType, out fieldDefinition); - return fieldDefinition ?? GetUndefinedColumnDefinition(fieldType, null); - } - - public virtual bool DoesTableExist(IDbConnection db, string tableName, string schema = null) - { - return db.Exec(dbCmd => DoesTableExist(dbCmd, tableName, schema)); - } - - public virtual bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) - { - return false; - } - - public virtual bool DoesSequenceExist(IDbCommand dbCmd, string sequenceName) - { - return true; - } - - protected virtual string GetIndexName(bool isUnique, string modelName, string fieldName) - { - return string.Format("{0}idx_{1}_{2}", isUnique ? "u" : "", modelName, fieldName).ToLower(); - } - - protected virtual string GetCompositeIndexName(CompositeIndexAttribute compositeIndex, ModelDefinition modelDef) - { - return compositeIndex.Name ?? GetIndexName(compositeIndex.Unique, modelDef.ModelName.SafeVarName(), - string.Join("_", compositeIndex.FieldNames.ToArray())); - } - - protected virtual string GetCompositeIndexNameWithSchema(CompositeIndexAttribute compositeIndex, ModelDefinition modelDef) - { - return compositeIndex.Name ?? GetIndexName(compositeIndex.Unique, - (modelDef.IsInSchema ? - modelDef.Schema + "_" + GetQuotedTableName(modelDef) : - GetQuotedTableName(modelDef)).SafeVarName(), - string.Join("_", compositeIndex.FieldNames.ToArray())); - } - - protected virtual string ToCreateIndexStatement(bool isUnique, string indexName, ModelDefinition modelDef, string fieldName, - bool isCombined = false, FieldDefinition fieldDef = null) - { - return string.Format("CREATE {0}{1}{2} INDEX {3} ON {4} ({5} ASC); \n", - isUnique ? "UNIQUE" : "", - fieldDef != null && fieldDef.IsClustered ? " CLUSTERED" : "", - fieldDef != null && fieldDef.IsNonClustered ? " NONCLUSTERED" : "", - indexName, - GetQuotedTableName(modelDef), - (isCombined) ? fieldName : GetQuotedColumnName(fieldName)); - } - - public virtual List ToCreateSequenceStatements(Type tableType) - { - return new List(); - } - - public virtual string ToCreateSequenceStatement(Type tableType, string sequenceName) - { - return ""; - } - - public virtual List SequenceList(Type tableType) - { - return new List(); - } - - // TODO : make abstract ?? - public virtual string ToExistStatement(Type fromTableType, - object objWithProperties, - string sqlFilter, - params object[] filterParams) - { - throw new NotImplementedException(); - } - - // TODO : make abstract ?? - public virtual string ToSelectFromProcedureStatement( - object fromObjWithProperties, - Type outputModelType, - string sqlFilter, - params object[] filterParams) - { - throw new NotImplementedException(); - } - - // TODO : make abstract ?? - public virtual string ToExecuteProcedureStatement(object objWithProperties) - { - return null; - } - - protected static ModelDefinition GetModel(Type modelType) - { - return modelType.GetModelDefinition(); - } - - public virtual SqlExpression SqlExpression() - { - throw new NotImplementedException(); - } - - public IDbCommand CreateParameterizedDeleteStatement(IDbConnection connection, object objWithProperties) - { - throw new NotImplementedException(); - } - - public virtual string GetDropForeignKeyConstraints(ModelDefinition modelDef) - { - return null; - } - - public virtual string ToAddColumnStatement(Type modelType, FieldDefinition fieldDef) - { - - var column = GetColumnDefinition(fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - return string.Format("ALTER TABLE {0} ADD COLUMN {1};", - GetQuotedTableName(modelType.GetModelDefinition().ModelName), - column); - } - - - public virtual string ToAlterColumnStatement(Type modelType, FieldDefinition fieldDef) - { - var column = GetColumnDefinition(fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - return string.Format("ALTER TABLE {0} MODIFY COLUMN {1};", - GetQuotedTableName(modelType.GetModelDefinition().ModelName), - column); - } - - public virtual string ToChangeColumnNameStatement(Type modelType, - FieldDefinition fieldDef, - string oldColumnName) - { - var column = GetColumnDefinition(fieldDef.FieldName, - fieldDef.ColumnType, - fieldDef.IsPrimaryKey, - fieldDef.AutoIncrement, - fieldDef.IsNullable, - fieldDef.IsRowVersion, - fieldDef.FieldLength, - fieldDef.Scale, - fieldDef.DefaultValue, - fieldDef.CustomFieldDefinition); - return string.Format("ALTER TABLE {0} CHANGE COLUMN {1} {2};", - GetQuotedTableName(modelType.GetModelDefinition().ModelName), - GetQuotedColumnName(oldColumnName), - column); - } - - public virtual string ToAddForeignKeyStatement(Expression> field, - Expression> foreignField, - OnFkOption onUpdate, - OnFkOption onDelete, - string foreignKeyName = null) - { - var sourceMD = ModelDefinition.Definition; - var fieldName = sourceMD.GetFieldDefinition(field).FieldName; - - var referenceMD = ModelDefinition.Definition; - var referenceFieldName = referenceMD.GetFieldDefinition(foreignField).FieldName; - - string name = GetQuotedName(foreignKeyName.IsNullOrEmpty() ? - "fk_" + sourceMD.ModelName + "_" + fieldName + "_" + referenceFieldName : - foreignKeyName); - - return string.Format("ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}){5}{6};", - GetQuotedTableName(sourceMD.ModelName), - name, - GetQuotedColumnName(fieldName), - GetQuotedTableName(referenceMD.ModelName), - GetQuotedColumnName(referenceFieldName), - GetForeignKeyOnDeleteClause(new ForeignKeyConstraint(typeof(T), onDelete: FkOptionToString(onDelete))), - GetForeignKeyOnUpdateClause(new ForeignKeyConstraint(typeof(T), onUpdate: FkOptionToString(onUpdate)))); - } - - public virtual string ToCreateIndexStatement(Expression> field, - string indexName = null, bool unique = false) - { - - var sourceMD = ModelDefinition.Definition; - var fieldName = sourceMD.GetFieldDefinition(field).FieldName; - - string name = GetQuotedName(indexName.IsNullOrEmpty() ? - (unique ? "uidx" : "idx") + "_" + sourceMD.ModelName + "_" + fieldName : - indexName); - - string command = string.Format("CREATE{0}INDEX {1} ON {2}({3});", - unique ? " UNIQUE " : " ", - name, - GetQuotedTableName(sourceMD.ModelName), - GetQuotedColumnName(fieldName)); - return command; - } - - - protected virtual string FkOptionToString(OnFkOption option) - { - switch (option) - { - case OnFkOption.Cascade: return "CASCADE"; - case OnFkOption.NoAction: return "NO ACTION"; - case OnFkOption.SetNull: return "SET NULL"; - case OnFkOption.SetDefault: return "SET DEFAULT"; - case OnFkOption.Restrict: - default: return "RESTRICT"; - } - } - - public virtual object ConvertDbValue(object value, Type type) - { - if (value == null || value is DBNull) return null; - - var strValue = value as string; - if (strValue != null && OrmLiteConfig.StringFilter != null) - { - value = OrmLiteConfig.StringFilter(strValue); - } - - if (value.GetType() == type) - { - return value; - } - - if (type == typeof(DateTimeOffset)) - { - if (strValue != null) - { - var moment = DateTimeOffset.Parse(strValue, null, DateTimeStyles.RoundtripKind); - return moment; - } - if (value is DateTime) - { - return new DateTimeOffset((DateTime)value); - } - } - - if (!type.IsEnum) - { - var typeCode = type.GetUnderlyingTypeCode(); - switch (typeCode) - { - case TypeCode.Int16: - return value is short ? value : Convert.ToInt16(value); - case TypeCode.UInt16: - return value is ushort ? value : Convert.ToUInt16(value); - case TypeCode.Int32: - return value is int ? value : Convert.ToInt32(value); - case TypeCode.UInt32: - return value is uint ? value : Convert.ToUInt32(value); - case TypeCode.Int64: - return value is long ? value : Convert.ToInt64(value); - case TypeCode.UInt64: - if (value is ulong) - return value; - var byteValue = value as byte[]; - if (byteValue != null) - return OrmLiteUtils.ConvertToULong(byteValue); - return Convert.ToUInt64(value); - case TypeCode.Single: - return value is float ? value : Convert.ToSingle(value); - case TypeCode.Double: - return value is double ? value : Convert.ToDouble(value); - case TypeCode.Decimal: - return value is decimal ? value : Convert.ToDecimal(value); - } - - if (type == typeof(TimeSpan)) - { - var ticks = (long)value; - return TimeSpan.FromTicks(ticks); - } - } - - try - { - var convertedValue = StringSerializer.DeserializeFromString(value.ToString(), type); - return convertedValue; - } - catch (Exception) - { - Log.ErrorFormat("Error ConvertDbValue trying to convert {0} into {1}", value, type.Name); - throw; - } - } - - public virtual string GetQuotedValue(object value, Type fieldType) - { - if (value == null) return "NULL"; - - if (fieldType.IsRefType()) - { - return GetQuotedValue(StringSerializer.SerializeToString(value)); - } - - if (fieldType.IsEnum) - { - var isEnumFlags = fieldType.IsEnumFlags(); - long enumValue; - if (!isEnumFlags && Int64.TryParse(value.ToString(), out enumValue)) - { - value = Enum.ToObject(fieldType, enumValue).ToString(); - } - - var enumString = StringSerializer.SerializeToString(value); - - return !isEnumFlags - ? GetQuotedValue(enumString.Trim('"')) - : enumString; - } - - var typeCode = fieldType.GetTypeCode(); - switch (typeCode) - { - case TypeCode.Single: - return ((float)value).ToString(CultureInfo.InvariantCulture); - case TypeCode.Double: - return ((double)value).ToString(CultureInfo.InvariantCulture); - case TypeCode.Decimal: - return ((decimal)value).ToString(CultureInfo.InvariantCulture); - - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - if (fieldType.IsNumericType()) - { - if (value is TimeSpan) - return ((TimeSpan)value).Ticks.ToString(CultureInfo.InvariantCulture); - return Convert.ChangeType(value, fieldType).ToString(); - } - break; - } - - if (fieldType == typeof(TimeSpan)) - return ((TimeSpan)value).Ticks.ToString(CultureInfo.InvariantCulture); - - return ShouldQuoteValue(fieldType) - ? GetQuotedValue(value.ToString()) - : value.ToString(); - } - - public virtual string EscapeWildcards(string value) - { - if (value == null) - return null; - - return value - .Replace("^", @"^^") - .Replace(@"\", @"^\") - .Replace("_", @"^_") - .Replace("%", @"^%"); - } - - public virtual string GetLoadChildrenSubSelect(ModelDefinition modelDef, SqlExpression expr) - { - expr.Select(this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey)); - - var subSql = expr.ToSelectStatement(); - - return subSql; - } - - public virtual string ToRowCountStatement(string innerSql) - { - return "SELECT COUNT(*) FROM ({0}) AS COUNT".Fmt(innerSql); - } - - //Async API's, should be overrided by Dialect Providers to use .ConfigureAwait(false) - //Default impl below uses TaskAwaiter shim in async.cs - - public virtual Task OpenAsync(IDbConnection db, CancellationToken token = default(CancellationToken)) - { - db.Open(); - return TaskResult.Finished; - } - - public virtual Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken)) - { - return cmd.ExecuteReader().InTask(); - } - - public virtual Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken)) - { - return cmd.ExecuteNonQuery().InTask(); - } - - public virtual Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken)) - { - return cmd.ExecuteScalar().InTask(); - } - - public virtual Task ReadAsync(IDataReader reader, CancellationToken token = default(CancellationToken)) - { - return reader.Read().InTask(); - } - -#if NET45 - public virtual async Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = default(CancellationToken)) - { - try - { - var to = new List(); - while (await ReadAsync(reader, token)) - { - var row = fn(); - to.Add(row); - } - return to; - } - finally - { - reader.Dispose(); - } - } - - public virtual async Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = default(CancellationToken)) - { - try - { - while (await ReadAsync(reader, token)) - { - fn(); - } - return source; - } - finally - { - reader.Dispose(); - } - } - - public virtual async Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = default(CancellationToken)) - { - try - { - if (await ReadAsync(reader, token)) - return fn(); - - return default(T); - } - finally - { - reader.Dispose(); - } - } - - public virtual Task InsertAndGetLastInsertIdAsync(IDbCommand dbCmd, CancellationToken token) - { - if (SelectIdentitySql == null) - return new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider.") - .InTask(); - - dbCmd.CommandText += "; " + SelectIdentitySql; - - return dbCmd.ExecLongScalarAsync(null, token); - } -#else - public Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = new CancellationToken()) - { - throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); - } - - public Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = new CancellationToken()) - { - throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); - } - - public Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = new CancellationToken()) - { - throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); - } - - public Task InsertAndGetLastInsertIdAsync(IDbCommand dbCmd, CancellationToken token) - { - throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); - } -#endif - } -} +// +// ServiceStack.OrmLite: Light-weight POCO ORM for .NET and Mono +// +// Authors: +// Demis Bellot (demis.bellot@gmail.com) +// +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. +// +// Licensed under the same terms of ServiceStack. +// + +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using ServiceStack.DataAnnotations; +using ServiceStack.Logging; +using ServiceStack.OrmLite.Converters; +using ServiceStack.Text; +using ServiceStack.Script; + +namespace ServiceStack.OrmLite +{ + public abstract class OrmLiteDialectProviderBase + : IOrmLiteDialectProvider + where TDialect : IOrmLiteDialectProvider + { + protected static readonly ILog Log = LogManager.GetLogger(typeof(IOrmLiteDialectProvider)); + + protected OrmLiteDialectProviderBase() + { + Variables = new Dictionary(); + StringSerializer = new JsvStringSerializer(); + } + + #region ADO.NET supported types + /* ADO.NET UNDERSTOOD DATA TYPES: + COUNTER DbType.Int64 + AUTOINCREMENT DbType.Int64 + IDENTITY DbType.Int64 + LONG DbType.Int64 + TINYINT DbType.Byte + INTEGER DbType.Int64 + INT DbType.Int32 + VARCHAR DbType.String + NVARCHAR DbType.String + CHAR DbType.String + NCHAR DbType.String + TEXT DbType.String + NTEXT DbType.String + STRING DbType.String + DOUBLE DbType.Double + FLOAT DbType.Double + REAL DbType.Single + BIT DbType.Boolean + YESNO DbType.Boolean + LOGICAL DbType.Boolean + BOOL DbType.Boolean + NUMERIC DbType.Decimal + DECIMAL DbType.Decimal + MONEY DbType.Decimal + CURRENCY DbType.Decimal + TIME DbType.DateTime + DATE DbType.DateTime + TIMESTAMP DbType.DateTime + DATETIME DbType.DateTime + BLOB DbType.Binary + BINARY DbType.Binary + VARBINARY DbType.Binary + IMAGE DbType.Binary + GENERAL DbType.Binary + OLEOBJECT DbType.Binary + GUID DbType.Guid + UNIQUEIDENTIFIER DbType.Guid + MEMO DbType.String + NOTE DbType.String + LONGTEXT DbType.String + LONGCHAR DbType.String + SMALLINT DbType.Int16 + BIGINT DbType.Int64 + LONGVARCHAR DbType.String + SMALLDATE DbType.DateTime + SMALLDATETIME DbType.DateTime + */ + #endregion + + protected void InitColumnTypeMap() + { + EnumConverter = new EnumConverter(); + RowVersionConverter = new RowVersionConverter(); + ReferenceTypeConverter = new ReferenceTypeConverter(); + ValueTypeConverter = new ValueTypeConverter(); + + RegisterConverter(new StringConverter()); + RegisterConverter(new CharConverter()); + RegisterConverter(new CharArrayConverter()); + RegisterConverter(new ByteArrayConverter()); + + RegisterConverter(new ByteConverter()); + RegisterConverter(new SByteConverter()); + RegisterConverter(new Int16Converter()); + RegisterConverter(new UInt16Converter()); + RegisterConverter(new Int32Converter()); + RegisterConverter(new UInt32Converter()); + RegisterConverter(new Int64Converter()); + RegisterConverter(new UInt64Converter()); + + RegisterConverter(new UInt64Converter()); + + RegisterConverter(new FloatConverter()); + RegisterConverter(new DoubleConverter()); + RegisterConverter(new DecimalConverter()); + + RegisterConverter(new GuidConverter()); + RegisterConverter(new TimeSpanAsIntConverter()); + RegisterConverter(new DateTimeConverter()); + RegisterConverter(new DateTimeOffsetConverter()); + +#if NET6_0 + RegisterConverter(new DateOnlyConverter()); + RegisterConverter(new TimeOnlyConverter()); +#endif + } + + public string GetColumnTypeDefinition(Type columnType, int? fieldLength, int? scale) + { + var converter = GetConverter(columnType); + if (converter != null) + { + if (converter is IHasColumnDefinitionPrecision customPrecisionConverter) + return customPrecisionConverter.GetColumnDefinition(fieldLength, scale); + + if (converter is IHasColumnDefinitionLength customLengthConverter) + return customLengthConverter.GetColumnDefinition(fieldLength); + + if (string.IsNullOrEmpty(converter.ColumnDefinition)) + throw new ArgumentException($"{converter.GetType().Name} requires a ColumnDefinition"); + + return converter.ColumnDefinition; + } + + var stringConverter = columnType.IsRefType() + ? ReferenceTypeConverter + : columnType.IsEnum + ? EnumConverter + : (IHasColumnDefinitionLength)ValueTypeConverter; + + return stringConverter.GetColumnDefinition(fieldLength); + } + + public virtual void InitDbParam(IDbDataParameter dbParam, Type columnType) + { + var converter = GetConverterBestMatch(columnType); + converter.InitDbParam(dbParam, columnType); + } + + public abstract IDbDataParameter CreateParam(); + + public Dictionary Variables { get; set; } + + public IOrmLiteExecFilter ExecFilter { get; set; } + + public Dictionary Converters = new(); + + public string AutoIncrementDefinition = "AUTOINCREMENT"; //SqlServer express limit + + public DecimalConverter DecimalConverter => (DecimalConverter)Converters[typeof(decimal)]; + + public StringConverter StringConverter => (StringConverter)Converters[typeof(string)]; + + public Action OnOpenConnection { get; set; } + + public string ParamString { get; set; } = "@"; + + public INamingStrategy NamingStrategy { get; set; } = new OrmLiteDefaultNamingStrategy(); + + public IStringSerializer StringSerializer { get; set; } + + private Func paramNameFilter; + public Func ParamNameFilter + { + get => paramNameFilter ?? OrmLiteConfig.ParamNameFilter; + set => paramNameFilter = value; + } + + public string DefaultValueFormat = " DEFAULT ({0})"; + + private EnumConverter enumConverter; + public EnumConverter EnumConverter + { + get => enumConverter; + set + { + value.DialectProvider = this; + enumConverter = value; + } + } + + private RowVersionConverter rowVersionConverter; + public RowVersionConverter RowVersionConverter + { + get => rowVersionConverter; + set + { + value.DialectProvider = this; + rowVersionConverter = value; + } + } + + private ReferenceTypeConverter referenceTypeConverter; + public ReferenceTypeConverter ReferenceTypeConverter + { + get => referenceTypeConverter; + set + { + value.DialectProvider = this; + referenceTypeConverter = value; + } + } + + private ValueTypeConverter valueTypeConverter; + public ValueTypeConverter ValueTypeConverter + { + get => valueTypeConverter; + set + { + value.DialectProvider = this; + valueTypeConverter = value; + } + } + + public void RemoveConverter() + { + if (Converters.TryRemove(typeof(T), out var converter)) + converter.DialectProvider = null; + } + + public void RegisterConverter(IOrmLiteConverter converter) + { + if (converter == null) + throw new ArgumentNullException(nameof(converter)); + + converter.DialectProvider = this; + Converters[typeof(T)] = converter; + } + + public IOrmLiteConverter GetConverter(Type type) + { + type = Nullable.GetUnderlyingType(type) ?? type; + return Converters.TryGetValue(type, out IOrmLiteConverter converter) + ? converter + : null; + } + + public virtual bool ShouldQuoteValue(Type fieldType) + { + var converter = GetConverter(fieldType); + return converter == null || converter is NativeValueOrmLiteConverter; + } + + public virtual object FromDbRowVersion(Type fieldType, object value) + { + return RowVersionConverter.FromDbValue(fieldType, value); + } + + public IOrmLiteConverter GetConverterBestMatch(Type type) + { + if (type == typeof(RowVersionConverter)) + return RowVersionConverter; + + var converter = GetConverter(type); + if (converter != null) + return converter; + + if (type.IsEnum) + return EnumConverter; + + return type.IsRefType() + ? (IOrmLiteConverter)ReferenceTypeConverter + : ValueTypeConverter; + } + + public virtual IOrmLiteConverter GetConverterBestMatch(FieldDefinition fieldDef) + { + var fieldType = Nullable.GetUnderlyingType(fieldDef.FieldType) ?? fieldDef.FieldType; + + if (fieldDef.IsRowVersion) + return RowVersionConverter; + + if (Converters.TryGetValue(fieldType, out var converter)) + return converter; + + if (fieldType.IsEnum) + return EnumConverter; + + return fieldType.IsRefType() + ? (IOrmLiteConverter)ReferenceTypeConverter + : ValueTypeConverter; + } + + public virtual object ToDbValue(object value, Type type) + { + if (value == null || value is DBNull) + return null; + + var converter = GetConverterBestMatch(type); + try + { + return converter.ToDbValue(type, value); + } + catch (Exception ex) + { + Log.Error($"Error in {converter.GetType().Name}.ToDbValue() value '{value.GetType().Name}' and Type '{type.Name}'", ex); + throw; + } + } + + public virtual object FromDbValue(object value, Type type) + { + if (value == null || value is DBNull) + return null; + + var converter = GetConverterBestMatch(type); + try + { + return converter.FromDbValue(type, value); + } + catch (Exception ex) + { + Log.Error($"Error in {converter.GetType().Name}.FromDbValue() value '{value.GetType().Name}' and Type '{type.Name}'", ex); + throw; + } + } + + public object GetValue(IDataReader reader, int columnIndex, Type type) + { + if (Converters.TryGetValue(type, out var converter)) + return converter.GetValue(reader, columnIndex, null); + + return reader.GetValue(columnIndex); + } + + public virtual int GetValues(IDataReader reader, object[] values) + { + return reader.GetValues(values); + } + + public abstract IDbConnection CreateConnection(string filePath, Dictionary options); + + public virtual string GetQuotedValue(string paramValue) + { + return "'" + paramValue.Replace("'", "''") + "'"; + } + + public virtual string GetSchemaName(string schema) + { + return NamingStrategy.GetSchemaName(schema); + } + + public virtual string GetTableName(ModelDefinition modelDef) => + GetTableName(modelDef.ModelName, modelDef.Schema, useStrategy:true); + + public virtual string GetTableName(ModelDefinition modelDef, bool useStrategy) => + GetTableName(modelDef.ModelName, modelDef.Schema, useStrategy); + + public virtual string GetTableName(string table, string schema = null) => + GetTableName(table, schema, useStrategy: true); + + public virtual string GetTableName(string table, string schema, bool useStrategy) + { + if (useStrategy) + { + return schema != null + ? $"{QuoteIfRequired(NamingStrategy.GetSchemaName(schema))}.{QuoteIfRequired(NamingStrategy.GetTableName(table))}" + : QuoteIfRequired(NamingStrategy.GetTableName(table)); + } + + return schema != null + ? $"{QuoteIfRequired(schema)}.{QuoteIfRequired(table)}" + : QuoteIfRequired(table); + } + + public virtual string GetQuotedTableName(ModelDefinition modelDef) + { + return GetQuotedTableName(modelDef.ModelName, modelDef.Schema); + } + + public virtual string GetQuotedTableName(string tableName, string schema = null) + { + if (schema == null) + return GetQuotedName(NamingStrategy.GetTableName(tableName)); + + var escapedSchema = NamingStrategy.GetSchemaName(schema) + .Replace(".", "\".\""); + + return $"{GetQuotedName(escapedSchema)}.{GetQuotedName(NamingStrategy.GetTableName(tableName))}"; + } + + public virtual string GetQuotedTableName(string tableName, string schema, bool useStrategy) => + GetQuotedName(GetTableName(tableName, schema, useStrategy)); + + public virtual string GetQuotedColumnName(string columnName) + { + return GetQuotedName(NamingStrategy.GetColumnName(columnName)); + } + + public virtual bool ShouldQuote(string name) => !string.IsNullOrEmpty(name) && + (name.IndexOf(' ') >= 0 || name.IndexOf('.') >= 0); + + public virtual string QuoteIfRequired(string name) + { + return ShouldQuote(name) + ? GetQuotedName(name) + : name; + } + + public virtual string GetQuotedName(string name) => name == null ? null : name.FirstCharEquals('"') + ? name : '"' + name + '"'; + + public virtual string GetQuotedName(string name, string schema) + { + return schema != null + ? $"{GetQuotedName(schema)}.{GetQuotedName(name)}" + : GetQuotedName(name); + } + + public virtual string SanitizeFieldNameForParamName(string fieldName) + { + return OrmLiteConfig.SanitizeFieldNameForParamNameFn(fieldName); + } + + public virtual string GetColumnDefinition(FieldDefinition fieldDef) + { + var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) ?? + GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale); + + var sql = StringBuilderCache.Allocate(); + sql.Append($"{GetQuotedColumnName(fieldDef.FieldName)} {fieldDefinition}"); + + if (fieldDef.IsPrimaryKey) + { + sql.Append(" PRIMARY KEY"); + if (fieldDef.AutoIncrement) + { + sql.Append(" ").Append(AutoIncrementDefinition); + } + } + else + { + sql.Append(fieldDef.IsNullable ? " NULL" : " NOT NULL"); + } + + if (fieldDef.IsUniqueConstraint) + { + sql.Append(" UNIQUE"); + } + + var defaultValue = GetDefaultValue(fieldDef); + if (!string.IsNullOrEmpty(defaultValue)) + { + sql.AppendFormat(DefaultValueFormat, defaultValue); + } + + return StringBuilderCache.ReturnAndFree(sql); + } + + public virtual string SelectIdentitySql { get; set; } + + public virtual long GetLastInsertId(IDbCommand dbCmd) + { + if (SelectIdentitySql == null) + throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider."); + + dbCmd.CommandText = SelectIdentitySql; + return dbCmd.ExecLongScalar(); + } + + public virtual string GetLastInsertIdSqlSuffix() + { + if (SelectIdentitySql == null) + throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider."); + + return "; " + SelectIdentitySql; + } + + public virtual bool IsFullSelectStatement(string sql) => !string.IsNullOrEmpty(sql) + && sql.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase); + + // Fmt + public virtual string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams) + { + if (IsFullSelectStatement(sqlFilter)) + return sqlFilter.SqlFmt(this, filterParams); + + var modelDef = tableType.GetModelDefinition(); + var sql = StringBuilderCache.Allocate(); + sql.Append($"SELECT {GetColumnNames(modelDef)} FROM {GetQuotedTableName(modelDef)}"); + + if (string.IsNullOrEmpty(sqlFilter)) + return StringBuilderCache.ReturnAndFree(sql); + + sqlFilter = sqlFilter.SqlFmt(this, filterParams); + if (!sqlFilter.StartsWith("ORDER ", StringComparison.OrdinalIgnoreCase) + && !sqlFilter.StartsWith("LIMIT ", StringComparison.OrdinalIgnoreCase)) + { + sql.Append(" WHERE "); + } + + sql.Append(sqlFilter); + + return StringBuilderCache.ReturnAndFree(sql); + } + + protected virtual void ApplyTags(StringBuilder sqlBuilder, ISet tags) + { + if (tags != null && tags.Count > 0) + { + foreach (var tag in tags) + { + sqlBuilder.AppendLine(GenerateComment(tag)); + } + sqlBuilder.Append("\n"); + } + } + + public virtual string ToSelectStatement( + QueryType queryType, + ModelDefinition modelDef, + string selectExpression, + string bodyExpression, + string orderByExpression = null, + int? offset = null, + int? rows = null, + ISet tags = null) + { + var sb = StringBuilderCache.Allocate(); + + ApplyTags(sb, tags); + + sb.Append(selectExpression); + sb.Append(bodyExpression); + if (!string.IsNullOrEmpty(orderByExpression)) + { + sb.Append(orderByExpression); + } + + if ((queryType == QueryType.Select || (rows == 1 && offset is null or 0)) && (offset != null || rows != null)) + { + sb.Append("\n"); + sb.Append(SqlLimit(offset, rows)); + } + + return StringBuilderCache.ReturnAndFree(sb); + } + + public virtual string GenerateComment(in string text) + { + return $"-- {text}"; + } + + public virtual SelectItem GetRowVersionSelectColumn(FieldDefinition field, string tablePrefix = null) + { + return new SelectItemColumn(this, field.FieldName, null, tablePrefix); + } + + public virtual string GetRowVersionColumn(FieldDefinition field, string tablePrefix = null) + { + return GetRowVersionSelectColumn(field, tablePrefix).ToString(); + } + + public virtual string GetColumnNames(ModelDefinition modelDef) + { + return GetColumnNames(modelDef, null).ToSelectString(); + } + + public virtual SelectItem[] GetColumnNames(ModelDefinition modelDef, string tablePrefix) + { + var quotedPrefix = tablePrefix != null + ? GetQuotedTableName(tablePrefix, modelDef.Schema) + : ""; + + var sqlColumns = new SelectItem[modelDef.FieldDefinitions.Count]; + for (var i = 0; i < sqlColumns.Length; ++i) + { + var field = modelDef.FieldDefinitions[i]; + + if (field.CustomSelect != null) + { + sqlColumns[i] = new SelectItemExpression(this, field.CustomSelect, field.FieldName); + } + else if (field.IsRowVersion) + { + sqlColumns[i] = GetRowVersionSelectColumn(field, quotedPrefix); + } + else + { + sqlColumns[i] = new SelectItemColumn(this, field.FieldName, null, quotedPrefix); + } + } + + return sqlColumns; + } + + protected virtual bool ShouldSkipInsert(FieldDefinition fieldDef) => + fieldDef.ShouldSkipInsert(); + + public virtual string ColumnNameOnly(string columnExpr) + { + var nameOnly = columnExpr.LastRightPart('.'); + var ret = nameOnly.StripDbQuotes(); + return ret; + } + + public virtual FieldDefinition[] GetInsertFieldDefinitions(ModelDefinition modelDef, ICollection insertFields) + { + var insertColumns = insertFields?.Map(ColumnNameOnly); + return insertColumns != null + ? NamingStrategy.GetType() == typeof(OrmLiteDefaultNamingStrategy) + ? modelDef.GetOrderedFieldDefinitions(insertColumns) + : modelDef.GetOrderedFieldDefinitions(insertColumns, name => NamingStrategy.GetColumnName(name)) + : modelDef.FieldDefinitionsArray; + } + + public virtual string ToInsertRowStatement(IDbCommand cmd, object objWithProperties, ICollection insertFields = null) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var modelDef = objWithProperties.GetType().GetModelDefinition(); + + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) + { + if (ShouldSkipInsert(fieldDef) && !fieldDef.AutoId) + continue; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); + + AddParameter(cmd, fieldDef); + } + catch (Exception ex) + { + Log.Error("ERROR in ToInsertRowStatement(): " + ex.Message, ex); + throw; + } + } + + var sql = $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) " + + $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"; + + return sql; + } + + public virtual string ToInsertStatement(IDbCommand dbCmd, T item, ICollection insertFields = null) + { + dbCmd.Parameters.Clear(); + var dialectProvider = dbCmd.GetDialectProvider(); + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, insertFields); + + if (string.IsNullOrEmpty(dbCmd.CommandText)) + return null; + + dialectProvider.SetParameterValues(dbCmd, item); + + return MergeParamsIntoSql(dbCmd.CommandText, ToArray(dbCmd.Parameters)); + } + + protected virtual object GetInsertDefaultValue(FieldDefinition fieldDef) + { + if (!fieldDef.AutoId) + return null; + if (fieldDef.FieldType == typeof(Guid)) + return Guid.NewGuid(); + return null; + } + + public virtual void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null, + Func shouldInclude=null) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var modelDef = typeof(T).GetModelDefinition(); + + cmd.Parameters.Clear(); + + var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields); + foreach (var fieldDef in fieldDefs) + { + if (fieldDef.ShouldSkipInsert() && shouldInclude?.Invoke(fieldDef) != true) + continue; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName),fieldDef.CustomInsert)); + + var p = AddParameter(cmd, fieldDef); + + if (fieldDef.AutoId) + { + p.Value = GetInsertDefaultValue(fieldDef); + } + } + catch (Exception ex) + { + Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex); + throw; + } + } + + cmd.CommandText = $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) " + + $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"; + } + + public virtual void PrepareInsertRowStatement(IDbCommand dbCmd, Dictionary args) + { + var sbColumnNames = StringBuilderCache.Allocate(); + var sbColumnValues = StringBuilderCacheAlt.Allocate(); + var modelDef = typeof(T).GetModelDefinition(); + + dbCmd.Parameters.Clear(); + + foreach (var entry in args) + { + var fieldDef = modelDef.AssertFieldDefinition(entry.Key); + if (fieldDef.ShouldSkipInsert()) + continue; + + var value = entry.Value; + + if (sbColumnNames.Length > 0) + sbColumnNames.Append(","); + if (sbColumnValues.Length > 0) + sbColumnValues.Append(","); + + try + { + sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName)); + sbColumnValues.Append(this.GetInsertParam(dbCmd, value, fieldDef)); + } + catch (Exception ex) + { + Log.Error("ERROR in PrepareInsertRowStatement(): " + ex.Message, ex); + throw; + } + } + + dbCmd.CommandText = $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) " + + $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"; + } + + public virtual string ToUpdateStatement(IDbCommand dbCmd, T item, ICollection updateFields = null) + { + dbCmd.Parameters.Clear(); + var dialectProvider = dbCmd.GetDialectProvider(); + dialectProvider.PrepareParameterizedUpdateStatement(dbCmd); + + if (string.IsNullOrEmpty(dbCmd.CommandText)) + return null; + + dialectProvider.SetParameterValues(dbCmd, item); + + return MergeParamsIntoSql(dbCmd.CommandText, ToArray(dbCmd.Parameters)); + } + + IDbDataParameter[] ToArray(IDataParameterCollection dbParams) + { + var to = new IDbDataParameter[dbParams.Count]; + for (int i = 0; i < dbParams.Count; i++) + { + to[i] = (IDbDataParameter)dbParams[i]; + } + return to; + } + + public virtual string MergeParamsIntoSql(string sql, IEnumerable dbParams) + { + foreach (var dbParam in dbParams) + { + var quotedValue = dbParam.Value != null + ? GetQuotedValue(dbParam.Value, dbParam.Value.GetType()) + : "null"; + + var pattern = dbParam.ParameterName + @"(,|\s|\)|$)"; + var replacement = quotedValue.Replace("$", "$$") + "$1"; + sql = Regex.Replace(sql, pattern, replacement); + } + return sql; + } + + public virtual bool PrepareParameterizedUpdateStatement(IDbCommand cmd, ICollection updateFields = null) + { + var sql = StringBuilderCache.Allocate(); + var sqlFilter = StringBuilderCacheAlt.Allocate(); + var modelDef = typeof(T).GetModelDefinition(); + var hadRowVersion = false; + var updateAllFields = updateFields == null || updateFields.Count == 0; + + cmd.Parameters.Clear(); + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (fieldDef.ShouldSkipUpdate()) + continue; + + try + { + if ((fieldDef.IsPrimaryKey || fieldDef.IsRowVersion) && updateAllFields) + { + if (sqlFilter.Length > 0) + sqlFilter.Append(" AND "); + + AppendFieldCondition(sqlFilter, fieldDef, cmd); + + if (fieldDef.IsRowVersion) + hadRowVersion = true; + + continue; + } + + if (!updateAllFields && !updateFields.Contains(fieldDef.Name, StringComparer.OrdinalIgnoreCase)) + continue; + + if (sql.Length > 0) + sql.Append(", "); + + sql + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName), fieldDef.CustomUpdate)); + + AddParameter(cmd, fieldDef); + } + catch (Exception ex) + { + OrmLiteUtils.HandleException(ex, "ERROR in PrepareParameterizedUpdateStatement(): " + ex.Message); + } + } + + if (sql.Length > 0) + { + var strFilter = StringBuilderCacheAlt.ReturnAndFree(sqlFilter); + cmd.CommandText = $"UPDATE {GetQuotedTableName(modelDef)} " + + $"SET {StringBuilderCache.ReturnAndFree(sql)} {(strFilter.Length > 0 ? "WHERE " + strFilter : "")}"; + } + else + { + cmd.CommandText = ""; + } + + return hadRowVersion; + } + + public virtual void AppendNullFieldCondition(StringBuilder sqlFilter, FieldDefinition fieldDef) + { + sqlFilter + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append(" IS NULL"); + } + + public virtual void AppendFieldCondition(StringBuilder sqlFilter, FieldDefinition fieldDef, IDbCommand cmd) + { + sqlFilter + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName))); + + AddParameter(cmd, fieldDef); + } + + public virtual bool PrepareParameterizedDeleteStatement(IDbCommand cmd, IDictionary deleteFieldValues) + { + if (deleteFieldValues == null || deleteFieldValues.Count == 0) + throw new ArgumentException("DELETE's must have at least 1 criteria"); + + var sqlFilter = StringBuilderCache.Allocate(); + var modelDef = typeof(T).GetModelDefinition(); + var hadRowVersion = false; + + cmd.Parameters.Clear(); + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (fieldDef.ShouldSkipDelete()) + continue; + + if (!deleteFieldValues.TryGetValue(fieldDef.Name, out var fieldValue)) + continue; + + if (fieldDef.IsRowVersion) + hadRowVersion = true; + + try + { + if (sqlFilter.Length > 0) + sqlFilter.Append(" AND "); + + if (fieldValue != null) + { + AppendFieldCondition(sqlFilter, fieldDef, cmd); + } + else + { + AppendNullFieldCondition(sqlFilter, fieldDef); + } + } + catch (Exception ex) + { + OrmLiteUtils.HandleException(ex, "ERROR in PrepareParameterizedDeleteStatement(): " + ex.Message); + } + } + + cmd.CommandText = $"DELETE FROM {GetQuotedTableName(modelDef)} WHERE {StringBuilderCache.ReturnAndFree(sqlFilter)}"; + + return hadRowVersion; + } + + public virtual void PrepareStoredProcedureStatement(IDbCommand cmd, T obj) + { + cmd.CommandText = ToExecuteProcedureStatement(obj); + cmd.CommandType = CommandType.StoredProcedure; + } + + /// + /// Used for adding updated DB params in INSERT and UPDATE statements + /// + protected IDbDataParameter AddParameter(IDbCommand cmd, FieldDefinition fieldDef) + { + var p = cmd.CreateParameter(); + SetParameter(fieldDef, p); + InitUpdateParam(p); + cmd.Parameters.Add(p); + return p; + } + + public virtual void SetParameter(FieldDefinition fieldDef, IDbDataParameter p) + { + p.ParameterName = this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)); + InitDbParam(p, fieldDef.ColumnType); + } + + public virtual void EnableIdentityInsert(IDbCommand cmd) {} + public virtual Task EnableIdentityInsertAsync(IDbCommand cmd, CancellationToken token=default) => TypeConstants.EmptyTask; + + public virtual void DisableIdentityInsert(IDbCommand cmd) {} + public virtual Task DisableIdentityInsertAsync(IDbCommand cmd, CancellationToken token=default) => TypeConstants.EmptyTask; + + public virtual void EnableForeignKeysCheck(IDbCommand cmd) {} + public virtual Task EnableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token=default) => TypeConstants.EmptyTask; + + public virtual void DisableForeignKeysCheck(IDbCommand cmd) {} + public virtual Task DisableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token=default) => TypeConstants.EmptyTask; + + public virtual void SetParameterValues(IDbCommand dbCmd, object obj) + { + var modelDef = GetModel(typeof(T)); + var fieldMap = GetFieldDefinitionMap(modelDef); + + foreach (IDataParameter p in dbCmd.Parameters) + { + var fieldName = this.ToFieldName(p.ParameterName); + fieldMap.TryGetValue(fieldName, out var fieldDef); + + if (fieldDef == null) + { + if (ParamNameFilter != null) + { + fieldDef = modelDef.GetFieldDefinition(name => + string.Equals(ParamNameFilter(name), fieldName, StringComparison.OrdinalIgnoreCase)); + } + + if (fieldDef == null) + throw new ArgumentException($"Field Definition '{fieldName}' was not found"); + } + + if (fieldDef.AutoId && p.Value != null) + { + var existingId = fieldDef.GetValue(obj); + if (existingId is Guid existingGuid && existingGuid != default(Guid)) + { + p.Value = existingGuid; // Use existing value if not default + } + + fieldDef.SetValue(obj, p.Value); //Auto populate default values + continue; + } + + SetParameterValue(fieldDef, p, obj); + } + } + + public Dictionary GetFieldDefinitionMap(ModelDefinition modelDef) + { + return modelDef.GetFieldDefinitionMap(SanitizeFieldNameForParamName); + } + + public virtual void SetParameterValue(FieldDefinition fieldDef, IDataParameter p, object obj) + { + var value = GetValueOrDbNull(fieldDef, obj); + p.Value = value; + + SetParameterSize(fieldDef, p); + } + + protected virtual void SetParameterSize(FieldDefinition fieldDef, IDataParameter p) + { + if (p.Value is string s && p is IDbDataParameter dataParam && dataParam.Size > 0 && s.Length > dataParam.Size) + { + // db param Size set in StringConverter + dataParam.Size = s.Length; + } + } + + protected virtual object GetValue(FieldDefinition fieldDef, object obj) + { + return GetFieldValue(fieldDef, fieldDef.GetValue(obj)); + } + + public object GetFieldValue(FieldDefinition fieldDef, object value) + { + if (value == null) + return null; + + var converter = GetConverterBestMatch(fieldDef); + try + { + return converter.ToDbValue(fieldDef.FieldType, value); + } + catch (Exception ex) + { + Log.Error($"Error in {converter.GetType().Name}.ToDbValue() for field '{fieldDef.Name}' of Type '{fieldDef.FieldType}' with value '{value.GetType().Name}'", ex); + throw; + } + } + + public object GetFieldValue(Type fieldType, object value) + { + if (value == null) + return null; + + var converter = GetConverterBestMatch(fieldType); + try + { + return converter.ToDbValue(fieldType, value); + } + catch (Exception ex) + { + Log.Error($"Error in {converter.GetType().Name}.ToDbValue() for field of Type '{fieldType}' with value '{value.GetType().Name}'", ex); + throw; + } + } + + protected virtual object GetValueOrDbNull(FieldDefinition fieldDef, object obj) + { + var value = GetValue(fieldDef, obj); + if (value == null) + return DBNull.Value; + + return value; + } + + protected virtual object GetQuotedValueOrDbNull(FieldDefinition fieldDef, object obj) + { + var value = fieldDef.GetValue(obj); + + if (value == null) + return DBNull.Value; + + var unquotedVal = GetQuotedValue(value, fieldDef.FieldType) + .TrimStart('\'').TrimEnd('\''); ; + + if (string.IsNullOrEmpty(unquotedVal)) + return DBNull.Value; + + return unquotedVal; + } + + public virtual void PrepareUpdateRowStatement(IDbCommand dbCmd, object objWithProperties, ICollection updateFields = null) + { + var sql = StringBuilderCache.Allocate(); + var sqlFilter = StringBuilderCacheAlt.Allocate(); + var modelDef = objWithProperties.GetType().GetModelDefinition(); + var updateAllFields = updateFields == null || updateFields.Count == 0; + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (fieldDef.ShouldSkipUpdate()) + continue; + + try + { + if (fieldDef.IsPrimaryKey && updateAllFields) + { + if (sqlFilter.Length > 0) + sqlFilter.Append(" AND "); + + sqlFilter + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.AddQueryParam(dbCmd, fieldDef.GetValue(objWithProperties), fieldDef).ParameterName); + + continue; + } + + if (!updateAllFields && !updateFields.Contains(fieldDef.Name, StringComparer.OrdinalIgnoreCase) || fieldDef.AutoIncrement) + continue; + + if (sql.Length > 0) + sql.Append(", "); + + sql + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.GetUpdateParam(dbCmd, fieldDef.GetValue(objWithProperties), fieldDef)); + } + catch (Exception ex) + { + OrmLiteUtils.HandleException(ex, "ERROR in ToUpdateRowStatement(): " + ex.Message); + } + } + + var strFilter = StringBuilderCacheAlt.ReturnAndFree(sqlFilter); + dbCmd.CommandText = $"UPDATE {GetQuotedTableName(modelDef)} " + + $"SET {StringBuilderCache.ReturnAndFree(sql)}{(strFilter.Length > 0 ? " WHERE " + strFilter : "")}"; + + if (sql.Length == 0) + throw new Exception("No valid update properties provided (e.g. p => p.FirstName): " + dbCmd.CommandText); + } + + public virtual void PrepareUpdateRowStatement(IDbCommand dbCmd, Dictionary args, string sqlFilter) + { + var sql = StringBuilderCache.Allocate(); + var modelDef = typeof(T).GetModelDefinition(); + + foreach (var entry in args) + { + var fieldDef = modelDef.AssertFieldDefinition(entry.Key); + if (fieldDef.ShouldSkipUpdate() || fieldDef.IsPrimaryKey || fieldDef.AutoIncrement) + continue; + + var value = entry.Value; + + try + { + if (sql.Length > 0) + sql.Append(", "); + + sql + .Append(GetQuotedColumnName(fieldDef.FieldName)) + .Append("=") + .Append(this.GetUpdateParam(dbCmd, value, fieldDef)); + } + catch (Exception ex) + { + OrmLiteUtils.HandleException(ex, "ERROR in PrepareUpdateRowStatement(cmd,args): " + ex.Message); + } + } + + dbCmd.CommandText = $"UPDATE {GetQuotedTableName(modelDef)} " + + $"SET {StringBuilderCache.ReturnAndFree(sql)}{(string.IsNullOrEmpty(sqlFilter) ? "" : " ")}{sqlFilter}"; + + if (sql.Length == 0) + throw new Exception("No valid update properties provided (e.g. () => new Person { Age = 27 }): " + dbCmd.CommandText); + } + + public virtual void PrepareUpdateRowAddStatement(IDbCommand dbCmd, Dictionary args, string sqlFilter) + { + var sql = StringBuilderCache.Allocate(); + var modelDef = typeof(T).GetModelDefinition(); + + foreach (var entry in args) + { + var fieldDef = modelDef.AssertFieldDefinition(entry.Key); + if (fieldDef.ShouldSkipUpdate() || fieldDef.AutoIncrement || fieldDef.IsPrimaryKey || + fieldDef.IsRowVersion || fieldDef.Name == OrmLiteConfig.IdField) + continue; + + var value = entry.Value; + + try + { + if (sql.Length > 0) + sql.Append(", "); + + var quotedFieldName = GetQuotedColumnName(fieldDef.FieldName); + + if (fieldDef.FieldType.IsNumericType()) + { + sql + .Append(quotedFieldName) + .Append("=") + .Append(quotedFieldName) + .Append("+") + .Append(this.GetUpdateParam(dbCmd, value, fieldDef)); + } + else + { + sql + .Append(quotedFieldName) + .Append("=") + .Append(this.GetUpdateParam(dbCmd, value, fieldDef)); + } + } + catch (Exception ex) + { + OrmLiteUtils.HandleException(ex, "ERROR in PrepareUpdateRowAddStatement(): " + ex.Message); + } + } + + dbCmd.CommandText = $"UPDATE {GetQuotedTableName(modelDef)} " + + $"SET {StringBuilderCache.ReturnAndFree(sql)}{(string.IsNullOrEmpty(sqlFilter) ? "" : " ")}{sqlFilter}"; + + if (sql.Length == 0) + throw new Exception("No valid update properties provided (e.g. () => new Person { Age = 27 }): " + dbCmd.CommandText); + } + + public virtual string ToDeleteStatement(Type tableType, string sqlFilter, params object[] filterParams) + { + var sql = StringBuilderCache.Allocate(); + const string deleteStatement = "DELETE "; + + var isFullDeleteStatement = + !string.IsNullOrEmpty(sqlFilter) + && sqlFilter.Length > deleteStatement.Length + && sqlFilter.Substring(0, deleteStatement.Length).ToUpper().Equals(deleteStatement); + + if (isFullDeleteStatement) + return sqlFilter.SqlFmt(this, filterParams); + + var modelDef = tableType.GetModelDefinition(); + sql.Append($"DELETE FROM {GetQuotedTableName(modelDef)}"); + + if (string.IsNullOrEmpty(sqlFilter)) + return StringBuilderCache.ReturnAndFree(sql); + + sqlFilter = sqlFilter.SqlFmt(this, filterParams); + sql.Append(" WHERE "); + sql.Append(sqlFilter); + + return StringBuilderCache.ReturnAndFree(sql); + } + + public virtual bool HasInsertReturnValues(ModelDefinition modelDef) => + modelDef.FieldDefinitions.Any(x => x.ReturnOnInsert); + + public string GetDefaultValue(Type tableType, string fieldName) + { + var modelDef = tableType.GetModelDefinition(); + var fieldDef = modelDef.AssertFieldDefinition(fieldName); + return GetDefaultValue(fieldDef); + } + + public virtual string GetDefaultValue(FieldDefinition fieldDef) + { + var defaultValue = fieldDef.DefaultValue; + if (string.IsNullOrEmpty(defaultValue)) + { + return fieldDef.AutoId + ? GetAutoIdDefaultValue(fieldDef) + : null; + } + + return ResolveFragment(defaultValue); + } + + public virtual string ResolveFragment(string sql) + { + if (string.IsNullOrEmpty(sql)) + return null; + + if (!sql.StartsWith("{")) + return sql; + + return Variables.TryGetValue(sql, out var variable) + ? variable + : null; + } + + public virtual string GetAutoIdDefaultValue(FieldDefinition fieldDef) => null; + + public Func> CreateTableFieldsStrategy { get; set; } = GetFieldDefinitions; + + public static IEnumerable GetFieldDefinitions(ModelDefinition modelDef) => modelDef.FieldDefinitions.OrderBy(fd=>fd.Order); + + public abstract string ToCreateSchemaStatement(string schemaName); + + public abstract bool DoesSchemaExist(IDbCommand dbCmd, string schemaName); + + public virtual Task DoesSchemaExistAsync(IDbCommand dbCmd, string schema, CancellationToken token = default) + { + return DoesSchemaExist(dbCmd, schema).InTask(); + } + + public virtual string ToCreateTableStatement(Type tableType) + { + var sbColumns = StringBuilderCache.Allocate(); + var sbConstraints = StringBuilderCacheAlt.Allocate(); + + var modelDef = tableType.GetModelDefinition(); + foreach (var fieldDef in CreateTableFieldsStrategy(modelDef)) + { + if (fieldDef.CustomSelect != null || (fieldDef.IsComputed && !fieldDef.IsPersisted)) + continue; + + var columnDefinition = GetColumnDefinition(fieldDef); + + if (columnDefinition == null) + continue; + + if (sbColumns.Length != 0) + sbColumns.Append(", \n "); + + sbColumns.Append(columnDefinition); + + var sqlConstraint = GetCheckConstraint(modelDef, fieldDef); + if (sqlConstraint != null) + { + sbConstraints.Append(",\n" + sqlConstraint); + } + + if (fieldDef.ForeignKey == null || OrmLiteConfig.SkipForeignKeys) + continue; + + var refModelDef = fieldDef.ForeignKey.ReferenceType.GetModelDefinition(); + sbConstraints.Append( + $", \n\n CONSTRAINT {GetQuotedName(fieldDef.ForeignKey.GetForeignKeyName(modelDef, refModelDef, NamingStrategy, fieldDef))} " + + $"FOREIGN KEY ({GetQuotedColumnName(fieldDef.FieldName)}) " + + $"REFERENCES {GetQuotedTableName(refModelDef)} ({GetQuotedColumnName(refModelDef.PrimaryKey.FieldName)})"); + + sbConstraints.Append(GetForeignKeyOnDeleteClause(fieldDef.ForeignKey)); + sbConstraints.Append(GetForeignKeyOnUpdateClause(fieldDef.ForeignKey)); + } + + var uniqueConstraints = GetUniqueConstraints(modelDef); + if (uniqueConstraints != null) + { + sbConstraints.Append(",\n" + uniqueConstraints); + } + + var sql = $"CREATE TABLE {GetQuotedTableName(modelDef)} " + + $"\n(\n {StringBuilderCache.ReturnAndFree(sbColumns)}{StringBuilderCacheAlt.ReturnAndFree(sbConstraints)} \n); \n"; + + return sql; + } + + public virtual string GetUniqueConstraints(ModelDefinition modelDef) + { + var constraints = modelDef.UniqueConstraints.Map(x => + $"CONSTRAINT {GetUniqueConstraintName(x, GetTableName(modelDef).StripDbQuotes())} UNIQUE ({x.FieldNames.Map(f => modelDef.GetQuotedName(f,this)).Join(",")})" ); + + return constraints.Count > 0 + ? constraints.Join(",\n") + : null; + } + + protected virtual string GetUniqueConstraintName(UniqueConstraintAttribute constraint, string tableName) => + constraint.Name ?? $"UC_{tableName}_{constraint.FieldNames.Join("_")}"; + + public virtual string GetCheckConstraint(ModelDefinition modelDef, FieldDefinition fieldDef) + { + if (fieldDef.CheckConstraint == null) + return null; + + return $"CONSTRAINT CHK_{modelDef.Schema}_{modelDef.ModelName}_{fieldDef.FieldName} CHECK ({fieldDef.CheckConstraint})"; + } + + public virtual string ToPostCreateTableStatement(ModelDefinition modelDef) + { + return null; + } + + public virtual string ToPostDropTableStatement(ModelDefinition modelDef) + { + return null; + } + + public virtual string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignKey) + { + return !string.IsNullOrEmpty(foreignKey.OnDelete) ? " ON DELETE " + foreignKey.OnDelete : ""; + } + + public virtual string GetForeignKeyOnUpdateClause(ForeignKeyConstraint foreignKey) + { + return !string.IsNullOrEmpty(foreignKey.OnUpdate) ? " ON UPDATE " + foreignKey.OnUpdate : ""; + } + + public virtual List ToCreateIndexStatements(Type tableType) + { + var sqlIndexes = new List(); + + var modelDef = tableType.GetModelDefinition(); + foreach (var fieldDef in modelDef.FieldDefinitions) + { + if (!fieldDef.IsIndexed) continue; + + var indexName = fieldDef.IndexName + ?? GetIndexName(fieldDef.IsUniqueIndex, modelDef.ModelName.SafeVarName(), fieldDef.FieldName); + + sqlIndexes.Add( + ToCreateIndexStatement(fieldDef.IsUniqueIndex, indexName, modelDef, fieldDef.FieldName, isCombined: false, fieldDef: fieldDef)); + } + + foreach (var compositeIndex in modelDef.CompositeIndexes) + { + var indexName = GetCompositeIndexName(compositeIndex, modelDef); + + var sb = StringBuilderCache.Allocate(); + foreach (var fieldName in compositeIndex.FieldNames) + { + if (sb.Length > 0) + sb.Append(", "); + + var parts = fieldName.SplitOnLast(' '); + if (parts.Length == 2 && (parts[1].ToLower().StartsWith("desc") || parts[1].ToLower().StartsWith("asc"))) + { + sb.Append(GetQuotedColumnName(parts[0])) + .Append(' ') + .Append(parts[1]); + } + else + { + sb.Append(GetQuotedColumnName(fieldName)); + } + } + + sqlIndexes.Add( + ToCreateIndexStatement(compositeIndex.Unique, indexName, modelDef, + StringBuilderCache.ReturnAndFree(sb), + isCombined: true)); + } + + return sqlIndexes; + } + + public virtual bool DoesTableExist(IDbConnection db, string tableName, string schema = null) + { + return db.Exec(dbCmd => DoesTableExist(dbCmd, tableName, schema)); + } + + public virtual async Task DoesTableExistAsync(IDbConnection db, string tableName, string schema = null, CancellationToken token = default) + { + return await db.Exec(async dbCmd => await DoesTableExistAsync(dbCmd, tableName, schema, token)); + } + + public virtual bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null) + { + throw new NotImplementedException(); + } + + public virtual Task DoesTableExistAsync(IDbCommand dbCmd, string tableName, string schema = null, CancellationToken token = default) + { + return DoesTableExist(dbCmd, tableName, schema).InTask(); + } + + public virtual bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null) + { + throw new NotImplementedException(); + } + + public virtual Task DoesColumnExistAsync(IDbConnection db, string columnName, string tableName, string schema = null, CancellationToken token = default) + { + return DoesColumnExist(db, columnName, tableName, schema).InTask(); + } + + public virtual bool DoesSequenceExist(IDbCommand dbCmd, string sequenceName) + { + throw new NotImplementedException(); + } + + public virtual Task DoesSequenceExistAsync(IDbCommand dbCmd, string sequenceName, CancellationToken token = default) + { + return DoesSequenceExist(dbCmd, sequenceName).InTask(); + } + + protected virtual string GetIndexName(bool isUnique, string modelName, string fieldName) + { + return $"{(isUnique ? "u" : "")}idx_{modelName}_{fieldName}".ToLower(); + } + + protected virtual string GetCompositeIndexName(CompositeIndexAttribute compositeIndex, ModelDefinition modelDef) + { + return compositeIndex.Name ?? GetIndexName(compositeIndex.Unique, modelDef.ModelName.SafeVarName(), + string.Join("_", compositeIndex.FieldNames.Map(x => x.LeftPart(' ')).ToArray())); + } + + protected virtual string GetCompositeIndexNameWithSchema(CompositeIndexAttribute compositeIndex, ModelDefinition modelDef) + { + return compositeIndex.Name ?? GetIndexName(compositeIndex.Unique, + (modelDef.IsInSchema + ? modelDef.Schema + "_" + GetQuotedTableName(modelDef) + : GetQuotedTableName(modelDef)).SafeVarName(), + string.Join("_", compositeIndex.FieldNames.ToArray())); + } + + protected virtual string ToCreateIndexStatement(bool isUnique, string indexName, ModelDefinition modelDef, string fieldName, + bool isCombined = false, FieldDefinition fieldDef = null) + { + return $"CREATE {(isUnique ? "UNIQUE" : "")}" + + (fieldDef?.IsClustered == true ? " CLUSTERED" : "") + + (fieldDef?.IsNonClustered == true ? " NONCLUSTERED" : "") + + $" INDEX {indexName} ON {GetQuotedTableName(modelDef)} " + + $"({(isCombined ? fieldName : GetQuotedColumnName(fieldName))}); \n"; + } + + public virtual List ToCreateSequenceStatements(Type tableType) + { + return new List(); + } + + public virtual string ToCreateSequenceStatement(Type tableType, string sequenceName) + { + return ""; + } + + public virtual List SequenceList(Type tableType) => new List(); + + public virtual Task> SequenceListAsync(Type tableType, CancellationToken token = default) => new List().InTask(); + + // TODO : make abstract ?? + public virtual string ToExistStatement(Type fromTableType, + object objWithProperties, + string sqlFilter, + params object[] filterParams) + { + throw new NotImplementedException(); + } + + // TODO : make abstract ?? + public virtual string ToSelectFromProcedureStatement( + object fromObjWithProperties, + Type outputModelType, + string sqlFilter, + params object[] filterParams) + { + throw new NotImplementedException(); + } + + // TODO : make abstract ?? + public virtual string ToExecuteProcedureStatement(object objWithProperties) + { + return null; + } + + protected static ModelDefinition GetModel(Type modelType) + { + return modelType.GetModelDefinition(); + } + + public virtual SqlExpression SqlExpression() + { + throw new NotImplementedException(); + } + + public IDbCommand CreateParameterizedDeleteStatement(IDbConnection connection, object objWithProperties) + { + throw new NotImplementedException(); + } + + public virtual string GetDropForeignKeyConstraints(ModelDefinition modelDef) + { + return null; + } + + public virtual string ToAddColumnStatement(Type modelType, FieldDefinition fieldDef) + { + var column = GetColumnDefinition(fieldDef); + return $"ALTER TABLE {GetQuotedTableName(modelType.GetModelDefinition())} ADD COLUMN {column};"; + } + + public virtual string ToAlterColumnStatement(Type modelType, FieldDefinition fieldDef) + { + var column = GetColumnDefinition(fieldDef); + return $"ALTER TABLE {GetQuotedTableName(modelType.GetModelDefinition())} MODIFY COLUMN {column};"; + } + + public virtual string ToChangeColumnNameStatement(Type modelType, FieldDefinition fieldDef, string oldColumnName) + { + var column = GetColumnDefinition(fieldDef); + return $"ALTER TABLE {GetQuotedTableName(modelType.GetModelDefinition())} CHANGE COLUMN {GetQuotedColumnName(oldColumnName)} {column};"; + } + + public virtual string ToAddForeignKeyStatement(Expression> field, + Expression> foreignField, + OnFkOption onUpdate, + OnFkOption onDelete, + string foreignKeyName = null) + { + var sourceMD = ModelDefinition.Definition; + var fieldName = sourceMD.GetFieldDefinition(field).FieldName; + + var referenceMD = ModelDefinition.Definition; + var referenceFieldName = referenceMD.GetFieldDefinition(foreignField).FieldName; + + string name = GetQuotedName(foreignKeyName.IsNullOrEmpty() ? + "fk_" + sourceMD.ModelName + "_" + fieldName + "_" + referenceFieldName : + foreignKeyName); + + return $"ALTER TABLE {GetQuotedTableName(sourceMD)} " + + $"ADD CONSTRAINT {name} FOREIGN KEY ({GetQuotedColumnName(fieldName)}) " + + $"REFERENCES {GetQuotedTableName(referenceMD)} " + + $"({GetQuotedColumnName(referenceFieldName)})" + + $"{GetForeignKeyOnDeleteClause(new ForeignKeyConstraint(typeof(T), onDelete: FkOptionToString(onDelete)))}" + + $"{GetForeignKeyOnUpdateClause(new ForeignKeyConstraint(typeof(T), onUpdate: FkOptionToString(onUpdate)))};"; + } + + public virtual string ToCreateIndexStatement(Expression> field, string indexName = null, bool unique = false) + { + var sourceDef = ModelDefinition.Definition; + var fieldName = sourceDef.GetFieldDefinition(field).FieldName; + + string name = GetQuotedName(indexName.IsNullOrEmpty() ? + (unique ? "uidx" : "idx") + "_" + sourceDef.ModelName + "_" + fieldName : + indexName); + + string command = $"CREATE {(unique ? "UNIQUE" : "")} " + + $"INDEX {name} ON {GetQuotedTableName(sourceDef)}" + + $"({GetQuotedColumnName(fieldName)});"; + return command; + } + + + protected virtual string FkOptionToString(OnFkOption option) + { + switch (option) + { + case OnFkOption.Cascade: return "CASCADE"; + case OnFkOption.NoAction: return "NO ACTION"; + case OnFkOption.SetNull: return "SET NULL"; + case OnFkOption.SetDefault: return "SET DEFAULT"; + case OnFkOption.Restrict: + default: return "RESTRICT"; + } + } + + public virtual string GetQuotedValue(object value, Type fieldType) + { + if (value == null || value == DBNull.Value) + return "NULL"; + + var converter = value.GetType().IsEnum + ? EnumConverter + : GetConverterBestMatch(fieldType); + try + { + return converter.ToQuotedString(fieldType, value); + } + catch (Exception ex) + { + Log.Error($"Error in {converter.GetType().Name}.ToQuotedString() value '{converter.GetType().Name}' and Type '{value.GetType().Name}'", ex); + throw; + } + } + + public virtual object GetParamValue(object value, Type fieldType) + { + return ToDbValue(value, fieldType); + } + + public virtual void InitQueryParam(IDbDataParameter param) {} + public virtual void InitUpdateParam(IDbDataParameter param) {} + + public virtual string EscapeWildcards(string value) + { + return value?.Replace("^", @"^^") + .Replace(@"\", @"^\") + .Replace("_", @"^_") + .Replace("%", @"^%"); + } + + public virtual string GetLoadChildrenSubSelect(SqlExpression expr) + { + var modelDef = expr.ModelDef; + expr.UnsafeSelect(this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey)); + + var subSql = expr.ToSelectStatement(QueryType.Select); + + return subSql; + } + + public virtual string ToRowCountStatement(string innerSql) + { + return $"SELECT COUNT(*) FROM ({innerSql}) AS COUNT"; + } + + public virtual void DropColumn(IDbConnection db, Type modelType, string columnName) + { + var provider = db.GetDialectProvider(); + var command = ToDropColumnStatement(modelType, columnName, provider); + + db.ExecuteSql(command); + } + + protected virtual string ToDropColumnStatement(Type modelType, string columnName, IOrmLiteDialectProvider provider) + { + return $"ALTER TABLE {provider.GetQuotedTableName(modelType.GetModelDefinition())} " + + $"DROP COLUMN {provider.GetQuotedColumnName(columnName)};"; + } + + public virtual string ToTableNamesStatement(string schema) => throw new NotSupportedException(); + + public virtual string ToTableNamesWithRowCountsStatement(bool live, string schema) => null; //returning null Fallsback to slow UNION N+1 COUNT(*) op + + public virtual string SqlConflict(string sql, string conflictResolution) => sql; //NOOP + + public virtual string SqlConcat(IEnumerable args) => $"CONCAT({string.Join(", ", args)})"; + + public virtual string SqlCurrency(string fieldOrValue) => SqlCurrency(fieldOrValue, "$"); + + public virtual string SqlCurrency(string fieldOrValue, string currencySymbol) => SqlConcat(new List { currencySymbol, fieldOrValue }); + + public virtual string SqlBool(bool value) => value ? "true" : "false"; + + public virtual string SqlLimit(int? offset = null, int? rows = null) => rows == null && offset == null + ? "" + : offset == null + ? "LIMIT " + rows + : "LIMIT " + rows.GetValueOrDefault(int.MaxValue) + " OFFSET " + offset; + + public virtual string SqlCast(object fieldOrValue, string castAs) => $"CAST({fieldOrValue} AS {castAs})"; + + public virtual string SqlRandom => "RAND()"; + + //Async API's, should be overriden by Dialect Providers to use .ConfigureAwait(false) + //Default impl below uses TaskAwaiter shim in async.cs + + public virtual Task OpenAsync(IDbConnection db, CancellationToken token = default) + { + db.Open(); + return TaskResult.Finished; + } + + public virtual Task ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default) + { + return cmd.ExecuteReader().InTask(); + } + + public virtual Task ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default) + { + return cmd.ExecuteNonQuery().InTask(); + } + + public virtual Task ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default) + { + return cmd.ExecuteScalar().InTask(); + } + + public virtual Task ReadAsync(IDataReader reader, CancellationToken token = default) + { + return reader.Read().InTask(); + } + +#if ASYNC + public virtual async Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = default) + { + try + { + var to = new List(); + while (await ReadAsync(reader, token)) + { + var row = fn(); + to.Add(row); + } + return to; + } + finally + { + reader.Dispose(); + } + } + + public virtual async Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = default) + { + try + { + while (await ReadAsync(reader, token)) + { + fn(); + } + return source; + } + finally + { + reader.Dispose(); + } + } + + public virtual async Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = default) + { + try + { + if (await ReadAsync(reader, token)) + return fn(); + + return default(T); + } + finally + { + reader.Dispose(); + } + } + + public virtual Task InsertAndGetLastInsertIdAsync(IDbCommand dbCmd, CancellationToken token) + { + if (SelectIdentitySql == null) + return new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider.") + .InTask(); + + dbCmd.CommandText += "; " + SelectIdentitySql; + + return dbCmd.ExecLongScalarAsync(null, token); + } +#else + public Task> ReaderEach(IDataReader reader, Func fn, CancellationToken token = new CancellationToken()) + { + throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); + } + + public Task ReaderEach(IDataReader reader, Action fn, Return source, CancellationToken token = new CancellationToken()) + { + throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); + } + + public Task ReaderRead(IDataReader reader, Func fn, CancellationToken token = new CancellationToken()) + { + throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); + } + + public Task InsertAndGetLastInsertIdAsync(IDbCommand dbCmd, CancellationToken token) + { + throw new NotImplementedException(OrmLiteUtils.AsyncRequiresNet45Error); + } +#endif + } +} diff --git a/src/ServiceStack.OrmLite/OrmLiteDialectProviderExtensions.cs b/src/ServiceStack.OrmLite/OrmLiteDialectProviderExtensions.cs index 5a207087d..c8bd15201 100644 --- a/src/ServiceStack.OrmLite/OrmLiteDialectProviderExtensions.cs +++ b/src/ServiceStack.OrmLite/OrmLiteDialectProviderExtensions.cs @@ -1,13 +1,22 @@ using System; using System.Data; +using ServiceStack.OrmLite.Converters; namespace ServiceStack.OrmLite { public static class OrmLiteDialectProviderExtensions { + public static string GetParam(this IOrmLiteDialectProvider dialect, string name, string format) + { + var ret = dialect.ParamString + (dialect.ParamNameFilter?.Invoke(name) ?? name); + return format == null + ? ret + : string.Format(format, ret); + } + public static string GetParam(this IOrmLiteDialectProvider dialect, string name) { - return dialect.ParamString + name; + return dialect.ParamString + (dialect.ParamNameFilter?.Invoke(name) ?? name); } public static string GetParam(this IOrmLiteDialectProvider dialect, int indexNo = 0) @@ -44,12 +53,85 @@ public static string GetQuotedColumnName(this IOrmLiteDialectProvider dialect, dialect.GetQuotedColumnName(fieldDef.FieldName); } + public static string GetQuotedColumnName(this IOrmLiteDialectProvider dialect, + ModelDefinition tableDef, string tableAlias, FieldDefinition fieldDef) + { + if (tableAlias == null) + return dialect.GetQuotedColumnName(tableDef, fieldDef); + + return dialect.GetQuotedTableName(tableAlias) //aliases shouldn't have schemas + + "." + + dialect.GetQuotedColumnName(fieldDef.FieldName); + } + public static string GetQuotedColumnName(this IOrmLiteDialectProvider dialect, ModelDefinition tableDef, string fieldName) { return dialect.GetQuotedTableName(tableDef) + - "." + + "." + + dialect.GetQuotedColumnName(fieldName); + } + + public static string GetQuotedColumnName(this IOrmLiteDialectProvider dialect, + ModelDefinition tableDef, string tableAlias, string fieldName) + { + if (tableAlias == null) + return dialect.GetQuotedColumnName(tableDef, fieldName); + + return dialect.GetQuotedTableName(tableAlias) //aliases shouldn't have schemas + + "." + dialect.GetQuotedColumnName(fieldName); } + + public static object FromDbValue(this IOrmLiteDialectProvider dialect, + IDataReader reader, int columnIndex, Type type) + { + return dialect.FromDbValue(dialect.GetValue(reader, columnIndex, type), type); + } + + public static IOrmLiteConverter GetConverter(this IOrmLiteDialectProvider dialect) + { + return dialect.GetConverter(typeof(T)); + } + + public static bool HasConverter(this IOrmLiteDialectProvider dialect, Type type) + { + return dialect.GetConverter(type) != null; + } + + public static StringConverter GetStringConverter(this IOrmLiteDialectProvider dialect) + { + return (StringConverter)dialect.GetConverter(typeof(string)); + } + + public static DecimalConverter GetDecimalConverter(this IOrmLiteDialectProvider dialect) + { + return (DecimalConverter)dialect.GetConverter(typeof(decimal)); + } + + public static DateTimeConverter GetDateTimeConverter(this IOrmLiteDialectProvider dialect) + { + return (DateTimeConverter)dialect.GetConverter(typeof(DateTime)); + } + + public static bool IsMySqlConnector(this IOrmLiteDialectProvider dialect) => + dialect.GetType().Name == "MySqlConnectorDialectProvider"; + + public static void InitDbParam(this IOrmLiteDialectProvider dialect, IDbDataParameter dbParam, Type columnType) + { + var converter = dialect.GetConverterBestMatch(columnType); + converter.InitDbParam(dbParam, columnType); + } + + public static void InitDbParam(this IOrmLiteDialectProvider dialect, IDbDataParameter dbParam, Type columnType, object value) + { + var converter = dialect.GetConverterBestMatch(columnType); + converter.InitDbParam(dbParam, columnType); + dbParam.Value = converter.ToDbValue(columnType, value); + } + + public static string SqlSpread(this IOrmLiteDialectProvider dialect, params T[] values) => + OrmLiteUtils.SqlJoin(values, dialect); + } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteExecFilter.cs b/src/ServiceStack.OrmLite/OrmLiteExecFilter.cs index c4cf62ae8..97eba091b 100644 --- a/src/ServiceStack.OrmLite/OrmLiteExecFilter.cs +++ b/src/ServiceStack.OrmLite/OrmLiteExecFilter.cs @@ -48,6 +48,9 @@ public virtual IDbCommand CreateCommand(IDbConnection dbConn) public virtual void DisposeCommand(IDbCommand dbCmd, IDbConnection dbConn) { if (dbCmd == null) return; + + OrmLiteConfig.AfterExecFilter?.Invoke(dbCmd); + dbConn.SetLastCommandText(dbCmd.CommandText); dbCmd.Dispose(); @@ -61,13 +64,18 @@ public virtual T Exec(IDbConnection dbConn, Func filter) var ret = filter(dbCmd); return ret; } + catch (Exception ex) + { + OrmLiteConfig.ExceptionFilter?.Invoke(dbCmd, ex); + throw; + } finally { DisposeCommand(dbCmd, dbConn); } } - public IDbCommand Exec(IDbConnection dbConn, Func filter) + public virtual IDbCommand Exec(IDbConnection dbConn, Func filter) { var dbCmd = CreateCommand(dbConn); var ret = filter(dbCmd); @@ -85,41 +93,61 @@ public virtual void Exec(IDbConnection dbConn, Action filter) { filter(dbCmd); } + catch (Exception ex) + { + OrmLiteConfig.ExceptionFilter?.Invoke(dbCmd, ex); + throw; + } finally { DisposeCommand(dbCmd, dbConn); } } - public virtual Task Exec(IDbConnection dbConn, Func> filter) + public virtual async Task Exec(IDbConnection dbConn, Func> filter) { var dbCmd = CreateCommand(dbConn); - return filter(dbCmd) - .Then(t => - { - DisposeCommand(dbCmd, dbConn); - return t; - }); + try + { + return await filter(dbCmd); + } + catch (Exception ex) + { + var useEx = ex.UnwrapIfSingleException(); + OrmLiteConfig.ExceptionFilter?.Invoke(dbCmd, useEx); + throw useEx; + } + finally + { + DisposeCommand(dbCmd, dbConn); + } } - public Task Exec(IDbConnection dbConn, Func> filter) + public virtual async Task Exec(IDbConnection dbConn, Func> filter) { var dbCmd = CreateCommand(dbConn); - - return filter(dbCmd).Then(t => t); + return await filter(dbCmd); } - public virtual Task Exec(IDbConnection dbConn, Func filter) + public virtual async Task Exec(IDbConnection dbConn, Func filter) { var dbCmd = CreateCommand(dbConn); - return filter(dbCmd) - .Then(t => - { - DisposeCommand(dbCmd, dbConn); - return t; - }); + try + { + await filter(dbCmd); + } + catch (Exception ex) + { + var useEx = ex.UnwrapIfSingleException(); + OrmLiteConfig.ExceptionFilter?.Invoke(dbCmd, useEx); + throw useEx; + } + finally + { + DisposeCommand(dbCmd, dbConn); + } } public virtual IEnumerable ExecLazy(IDbConnection dbConn, Func> filter) diff --git a/src/ServiceStack.OrmLite/OrmLiteNamingStrategyBase.cs b/src/ServiceStack.OrmLite/OrmLiteNamingStrategyBase.cs index 4d25e007f..13554a53e 100644 --- a/src/ServiceStack.OrmLite/OrmLiteNamingStrategyBase.cs +++ b/src/ServiceStack.OrmLite/OrmLiteNamingStrategyBase.cs @@ -14,39 +14,18 @@ namespace ServiceStack.OrmLite { public class OrmLiteNamingStrategyBase : INamingStrategy { - public virtual string GetSchemaName(string name) - { - return name; - } + public virtual string GetSchemaName(string name) => name; - public virtual string GetSchemaName(ModelDefinition modelDef) - { - return GetSchemaName(modelDef.Schema); - } + public virtual string GetSchemaName(ModelDefinition modelDef) => GetSchemaName(modelDef.Schema); - public virtual string GetTableName(string name) - { - return name; - } + public virtual string GetTableName(string name) => name; - public virtual string GetTableName(ModelDefinition modelDef) - { - return GetTableName(modelDef.ModelName); - } + public virtual string GetTableName(ModelDefinition modelDef) => GetTableName(modelDef.ModelName); - public virtual string GetColumnName(string name) - { - return name; - } + public virtual string GetColumnName(string name) => name; - public virtual string GetSequenceName(string modelName, string fieldName) - { - return "SEQ_" + modelName + "_" + fieldName; - } + public virtual string GetSequenceName(string modelName, string fieldName) => "SEQ_" + modelName + "_" + fieldName; - public virtual string ApplyNameRestrictions(string name) - { - return name; - } + public virtual string ApplyNameRestrictions(string name) => name; } } diff --git a/src/ServiceStack.OrmLite/OrmLitePersistenceProvider.cs b/src/ServiceStack.OrmLite/OrmLitePersistenceProvider.cs index 4afbe333f..539cbac76 100644 --- a/src/ServiceStack.OrmLite/OrmLitePersistenceProvider.cs +++ b/src/ServiceStack.OrmLite/OrmLitePersistenceProvider.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // diff --git a/src/ServiceStack.OrmLite/OrmLiteReadApi.cs b/src/ServiceStack.OrmLite/OrmLiteReadApi.cs index edc470226..f748d7ae2 100644 --- a/src/ServiceStack.OrmLite/OrmLiteReadApi.cs +++ b/src/ServiceStack.OrmLite/OrmLiteReadApi.cs @@ -27,6 +27,15 @@ public static List Select(this IDbConnection dbConn, string sql) return dbConn.Exec(dbCmd => dbCmd.Select(sql)); } + /// + /// Returns results from using sql. E.g: + /// db.Select<Person>("SELECT * FROM Person WHERE Age > @age", new[] { db.CreateParam("age", 40) }) + /// + public static List Select(this IDbConnection dbConn, string sql, IEnumerable sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.Select(sql, sqlParams)); + } + /// /// Returns results from using a parameterized query. E.g: /// db.Select<Person>("Age > @age", new { age = 40}) @@ -48,13 +57,13 @@ public static List Select(this IDbConnection dbConn, string sql, Dictionar } /// - /// Returns results from using an SqlFormat query. E.g: - /// db.SelectFmt<Person>("Age > {0}", 40) - /// db.SelectFmt<Person>("SELECT * FROM Person WHERE Age > {0}", 40) + /// Returns a partial subset of results from the specified tableType. E.g: + /// db.Select<EntityWithId>(typeof(Person)) + /// /// - public static List SelectFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + public static List Select(this IDbConnection dbConn, Type fromTableType, string sql, object anonType) { - return dbConn.Exec(dbCmd => dbCmd.SelectFmt(sqlFormat, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.Select(fromTableType, sql, anonType)); } /// @@ -67,15 +76,6 @@ public static List Select(this IDbConnection dbConn, Type fromTa return dbConn.Exec(dbCmd => dbCmd.Select(fromTableType)); } - /// - /// Returns a partial subset of results from the specified tableType using a SqlFormat query. E.g: - /// db.SelectFmt<EntityWithId>(typeof(Person), "Age > {0}", 40) - /// - public static List SelectFmt(this IDbConnection dbConn, Type fromTableType, string sqlFormat, params object[] filterParams) - { - return dbConn.Exec(dbCmd => dbCmd.SelectFmt(fromTableType, sqlFormat, filterParams)); - } - /// /// Returns results from using a single name, value filter. E.g: /// db.Where<Person>("Age", 27) @@ -140,12 +140,12 @@ public static IEnumerable SelectLazy(this IDbConnection dbConn, string sql } /// - /// Returns a lazyily loaded stream of results using an SqlFilter query. E.g: - /// db.SelectLazyFmt<Person>("Age > {0}", 40) + /// Returns a lazyily loaded stream of results using a parameterized query. E.g: + /// db.SelectLazy(db.From<Person>().Where(x => x == 40)) /// - public static IEnumerable SelectLazyFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + public static IEnumerable SelectLazy(this IDbConnection dbConn, SqlExpression expression) { - return dbConn.ExecLazy(dbCmd => dbCmd.SelectLazyFmt(sqlFormat, filterParams)); + return dbConn.ExecLazy(dbCmd => dbCmd.SelectLazy(expression.ToSelectStatement(QueryType.Select), expression.Params)); } /// @@ -168,20 +168,20 @@ public static T Single(this IDbConnection dbConn, object anonType) /// /// Returns results from using a single name, value filter. E.g: - /// db.Single<Person>("Age = @age", new { age = 42 }) + /// db.Single<Person>("Age = @age", new[] { db.CreateParam("age",40) }) /// - public static T Single(this IDbConnection dbConn, string sql, object anonType = null) + public static T Single(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.Exec(dbCmd => dbCmd.Single(sql, anonType)); + return dbConn.Exec(dbCmd => dbCmd.Single(sql, sqlParams)); } /// - /// Returns the first result using a SqlFormat query. E.g: - /// db.SingleFmt<Person>("Age = {0}", 42) + /// Returns results from using a single name, value filter. E.g: + /// db.Single<Person>("Age = @age", new { age = 42 }) /// - public static T SingleFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + public static T Single(this IDbConnection dbConn, string sql, object anonType = null) { - return dbConn.Exec(dbCmd => dbCmd.SingleFmt(sqlFormat, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.Single(sql, anonType)); } /// @@ -204,83 +204,92 @@ public static T SingleWhere(this IDbConnection dbConn, string name, object va /// /// Returns a single scalar value using an SqlExpression. E.g: - /// db.Column<int>(db.From<Persion>().Select(x => Sql.Count("*")).Where(q => q.Age > 40)) + /// db.Column<int>(db.From<Person>().Select(x => Sql.Count("*")).Where(q => q.Age > 40)) /// public static T Scalar(this IDbConnection dbConn, ISqlExpression sqlExpression) { - return dbConn.Exec(dbCmd => dbCmd.Scalar(sqlExpression.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.Scalar(sqlExpression.ToSelectStatement(QueryType.Scalar), sqlExpression.Params)); } /// /// Returns a single scalar value using a parameterized query. E.g: - /// db.Scalar<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }) + /// db.Scalar<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new[] { db.CreateParam("age",40) }) /// - public static T Scalar(this IDbConnection dbConn, string sql, object anonType = null) + public static T Scalar(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.Exec(dbCmd => dbCmd.Scalar(sql, anonType)); + return dbConn.Exec(dbCmd => dbCmd.Scalar(sql, sqlParams)); } /// - /// Returns a single scalar value using an SqlFormat query. E.g: - /// db.ScalarFmt<int>("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40) + /// Returns a single scalar value using a parameterized query. E.g: + /// db.Scalar<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }) /// - public static T ScalarFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + public static T Scalar(this IDbConnection dbConn, string sql, object anonType = null) { - return dbConn.Exec(dbCmd => dbCmd.ScalarFmt(sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.Scalar(sql, anonType)); } /// /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: - /// db.Column<int>(db.From<Persion>().Select(x => x.LastName).Where(q => q.Age == 27)) + /// db.Column<int>(db.From<Person>().Select(x => x.LastName).Where(q => q.Age == 27)) /// public static List Column(this IDbConnection dbConn, ISqlExpression query) { - return dbConn.Exec(dbCmd => dbCmd.Column(query.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.Column(query.ToSelectStatement(QueryType.Select), query.Params)); } /// /// Returns the first column in a List using a SqlFormat query. E.g: - /// db.ColumnLazy<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) + /// db.Column<string>("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age",27) }) /// - public static IEnumerable ColumnLazy(this IDbConnection dbConn, string sql, object anonType = null) + public static List Column(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.ExecLazy(dbCmd => dbCmd.ColumnLazy(sql, anonType)); + return dbConn.Exec(dbCmd => dbCmd.Column(sql, sqlParams)); } /// /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: - /// db.ColumnLazy<int>(db.From<Persion>().Select(x => x.LastName).Where(q => q.Age == 27)) + /// db.ColumnLazy<int>(db.From<Person>().Select(x => x.LastName).Where(q => q.Age == 27)) /// public static IEnumerable ColumnLazy(this IDbConnection dbConn, ISqlExpression query) { - return dbConn.ExecLazy(dbCmd => dbCmd.ColumnLazy(query.ToSelectStatement())); + return dbConn.ExecLazy(dbCmd => dbCmd.ColumnLazy(query.ToSelectStatement(QueryType.Select), query.Params)); } /// /// Returns the first column in a List using a SqlFormat query. E.g: - /// db.Column<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) + /// db.ColumnLazy<string>("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age",27) }) /// - public static List Column(this IDbConnection dbConn, string sql, object anonType = null) + public static IEnumerable ColumnLazy(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.Exec(dbCmd => dbCmd.Column(sql, anonType)); + return dbConn.ExecLazy(dbCmd => dbCmd.ColumnLazy(sql, sqlParams)); } /// /// Returns the first column in a List using a SqlFormat query. E.g: - /// db.ColumnFmt<string>("SELECT LastName FROM Person WHERE Age = {0}", 27) + /// db.ColumnLazy<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) /// - public static List ColumnFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + public static IEnumerable ColumnLazy(this IDbConnection dbConn, string sql, object anonType = null) + { + return dbConn.ExecLazy(dbCmd => dbCmd.ColumnLazy(sql, anonType)); + } + + /// + /// Returns the first column in a List using a SqlFormat query. E.g: + /// db.Column<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) + /// + public static List Column(this IDbConnection dbConn, string sql, object anonType = null) { - return dbConn.Exec(dbCmd => dbCmd.ColumnFmt(sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.Column(sql, anonType)); } /// /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: - /// db.ColumnDistinct<int>(db.From<Persion>().Select(x => x.Age).Where(q => q.Age < 50)) + /// db.ColumnDistinct<int>(db.From<Person>().Select(x => x.Age).Where(q => q.Age < 50)) /// public static HashSet ColumnDistinct(this IDbConnection dbConn, ISqlExpression query) { - return dbConn.Exec(dbCmd => dbCmd.ColumnDistinct(query.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinct(query)); } /// @@ -294,38 +303,38 @@ public static HashSet ColumnDistinct(this IDbConnection dbConn, string sql /// /// Returns the distinct first column values in a HashSet using an SqlFormat query. E.g: - /// db.ColumnDistinctFmt<int>("SELECT Age FROM Person WHERE Age < {0}", 50) + /// db.ColumnDistinct<int>("SELECT Age FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) /// - public static HashSet ColumnDistinctFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + public static HashSet ColumnDistinct(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctFmt(sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinct(sql, sqlParams)); } /// /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an Sql Expression. E.g: - /// db.Lookup<int, string>(db.From<Person>().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)) + /// db.Lookup<int, string>(db.From<Person>().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)) /// public static Dictionary> Lookup(this IDbConnection dbConn, ISqlExpression sqlExpression) { - return dbConn.Exec(dbCmd => dbCmd.Lookup(sqlExpression.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.Lookup(sqlExpression.ToSelectStatement(QueryType.Select), sqlExpression.Params)); } /// /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an parameterized query. E.g: - /// db.Lookup<int, string>("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }) + /// db.Lookup<int, string>("SELECT Age, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) /// - public static Dictionary> Lookup(this IDbConnection dbConn, string sql, object anonType = null) + public static Dictionary> Lookup(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.Exec(dbCmd => dbCmd.Lookup(sql, anonType)); + return dbConn.Exec(dbCmd => dbCmd.Lookup(sql, sqlParams)); } /// - /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an SqlFormat query. E.g: - /// db.LookupFmt<int, string>("SELECT Age, LastName FROM Person WHERE Age < {0}", 50) + /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an parameterized query. E.g: + /// db.Lookup<int, string>("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }) /// - public static Dictionary> LookupFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + public static Dictionary> Lookup(this IDbConnection dbConn, string sql, object anonType = null) { - return dbConn.Exec(dbCmd => dbCmd.LookupFmt(sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.Lookup(sql, anonType)); } /// @@ -334,7 +343,7 @@ public static Dictionary> LookupFmt(this IDbConnection dbConn, /// public static Dictionary Dictionary(this IDbConnection dbConn, ISqlExpression query) { - return dbConn.Exec(dbCmd => dbCmd.Dictionary(query.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.Dictionary(query)); } /// @@ -347,30 +356,30 @@ public static Dictionary Dictionary(this IDbConnection dbConn, strin } /// - /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlFormat query. E.g: - /// db.DictionaryFmt<int, string>("SELECT Id, LastName FROM Person WHERE Age < {0}", 50) + /// Returns a list KeyValuePairs from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlExpression. E.g: + /// db.KeyValuePairs<int, string>(db.From<Person>().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)) /// - public static Dictionary DictionaryFmt(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + public static List> KeyValuePairs(this IDbConnection dbConn, ISqlExpression query) { - return dbConn.Exec(dbCmd => dbCmd.DictionaryFmt(sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.KeyValuePairs(query)); } /// - /// Returns true if the Query returns any records that match the LINQ expression, E.g: - /// db.Exists<Person>(x => x.Age < 50) + /// Returns a list of KeyValuePairs from the first 2 columns: Column 1 (Keys), Column 2 (Values) using sql. E.g: + /// db.KeyValuePairs<int, string>("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }) /// - public static bool Exists(this IDbConnection dbConn, Expression> expression) + public static List> KeyValuePairs(this IDbConnection dbConn, string sql, object anonType = null) { - return dbConn.Exec(dbCmd => dbCmd.Count(expression)) > 0; + return dbConn.Exec(dbCmd => dbCmd.KeyValuePairs(sql, anonType)); } /// - /// Returns true if the Query returns any records that match the SqlExpression lambda, E.g: - /// db.Exists<Person>(q => q.Where(x => x.Age < 50)) + /// Returns true if the Query returns any records that match the LINQ expression, E.g: + /// db.Exists<Person>(x => x.Age < 50) /// - public static bool Exists(this IDbConnection dbConn, Func, SqlExpression> expression) + public static bool Exists(this IDbConnection dbConn, Expression> expression) { - return dbConn.Exec(dbCmd => dbCmd.Count(expression)) > 0; + return dbConn.Exec(dbCmd => dbCmd.Scalar(dbConn.From().Where(expression).Limit(1).Select("'exists'"))) != null; } /// @@ -379,7 +388,7 @@ public static bool Exists(this IDbConnection dbConn, Func, S /// public static bool Exists(this IDbConnection dbConn, SqlExpression expression) { - return dbConn.Exec(dbCmd => dbCmd.Count(expression)) > 0; + return dbConn.Exec(dbCmd => dbCmd.Scalar(expression.Limit(1).Select("'exists'"))) != null; } /// /// Returns true if the Query returns any records, using an SqlFormat query. E.g: @@ -401,22 +410,21 @@ public static bool Exists(this IDbConnection dbConn, string sql, object anonT } /// - /// Returns true if the Query returns any records, using an SqlFormat query. E.g: - /// db.ExistsFmt<Person>("Age = {0}", 42) - /// db.ExistsFmt<Person>("SELECT * FROM Person WHERE Age = {0}", 50) + /// Returns results from an arbitrary SqlExpression. E.g: + /// db.SqlList<Person>(db.From<Person>().Select("*").Where(q => q.Age < 50)) /// - public static bool ExistsFmt(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) + public static List SqlList(this IDbConnection dbConn, ISqlExpression sqlExpression) { - return dbConn.Exec(dbCmd => dbCmd.ExistsFmt(sqlFormat, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.SqlList(sqlExpression.ToSelectStatement(QueryType.Select), sqlExpression.Params)); } /// - /// Returns results from an arbitrary SqlExpression. E.g: - /// db.SqlList<Person>(db.From<Person>().Select("*").Where(q => q.Age < 50)) + /// Returns results from an arbitrary parameterized raw sql query. E.g: + /// db.SqlList<Person>("EXEC GetRockstarsAged @age", new[] { db.CreateParam("age",50) }) /// - public static List SqlList(this IDbConnection dbConn, ISqlExpression sqlExpression) + public static List SqlList(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.Exec(dbCmd => dbCmd.SqlList(sqlExpression.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.SqlList(sql, sqlParams)); } /// @@ -461,7 +469,16 @@ public static IDbCommand SqlProc(this IDbConnection dbConn, string name, object /// public static List SqlColumn(this IDbConnection dbConn, ISqlExpression sqlExpression) { - return dbConn.Exec(dbCmd => dbCmd.SqlColumn(sqlExpression.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.SqlColumn(sqlExpression.ToSelectStatement(QueryType.Select), sqlExpression.Params)); + } + + /// + /// Returns the first column in a List using a parameterized query. E.g: + /// db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) + /// + public static List SqlColumn(this IDbConnection dbConn, string sql, IEnumerable sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.SqlColumn(sql, sqlParams)); } /// @@ -488,7 +505,16 @@ public static List SqlColumn(this IDbConnection dbConn, string sql, Dictio /// public static T SqlScalar(this IDbConnection dbConn, ISqlExpression sqlExpression) { - return dbConn.Exec(dbCmd => dbCmd.SqlScalar(sqlExpression.ToSelectStatement())); + return dbConn.Exec(dbCmd => dbCmd.SqlScalar(sqlExpression.ToSelectStatement(QueryType.Scalar), sqlExpression.Params)); + } + + /// + /// Returns a single Scalar value using a parameterized query. E.g: + /// db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new[]{ db.CreateParam("age",50) }) + /// + public static T SqlScalar(this IDbConnection dbConn, string sql, IEnumerable sqlParams) + { + return dbConn.Exec(dbCmd => dbCmd.SqlScalar(sql, sqlParams)); } /// @@ -546,6 +572,15 @@ public static int ExecuteNonQuery(this IDbConnection dbConn, string sql, Diction return dbConn.Exec(dbCmd => dbCmd.ExecNonQuery(sql, dict)); } + /// + /// Executes a raw sql non-query using a parameterized query with a dbCmd filter. E.g: + /// + /// number of rows affected + public static int ExecuteNonQuery(this IDbConnection dbConn, string sql, Action dbCmdFilter) + { + return dbConn.Exec(dbCmd => dbCmd.ExecNonQuery(sql, dbCmdFilter)); + } + /// /// Returns results from a Stored Procedure, using a parameterized query. /// @@ -578,11 +613,20 @@ public static long LongScalar(this IDbConnection dbConn) /// /// Returns the first result with all its references loaded, using a primary key id. E.g: - /// db.LoadSingleById<Person>(1) + /// db.LoadSingleById<Person>(1, include = new[]{ "Address" }) + /// + public static T LoadSingleById(this IDbConnection dbConn, object idValue, string[] include = null) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSingleById(idValue, include)); + } + + /// + /// Returns the first result with all its references loaded, using a primary key id. E.g: + /// db.LoadSingleById<Person>(1, include = x => new{ x.Address }) /// - public static T LoadSingleById(this IDbConnection dbConn, object idValue) + public static T LoadSingleById(this IDbConnection dbConn, object idValue, Expression> include) { - return dbConn.Exec(dbCmd => dbCmd.LoadSingleById(idValue)); + return dbConn.Exec(dbCmd => dbCmd.LoadSingleById(idValue, include.GetFieldNames() )); } /// diff --git a/src/ServiceStack.OrmLite/OrmLiteReadApiAsync.cs b/src/ServiceStack.OrmLite/OrmLiteReadApiAsync.cs index da0d20f6c..0bdf62573 100644 --- a/src/ServiceStack.OrmLite/OrmLiteReadApiAsync.cs +++ b/src/ServiceStack.OrmLite/OrmLiteReadApiAsync.cs @@ -1,5 +1,5 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; @@ -15,474 +15,483 @@ namespace ServiceStack.OrmLite public static class OrmLiteReadApiAsync { /// - /// Returns results from the active connection. + /// Returns results from the active connection, E.g: + /// db.SelectAsync<Person>() /// - public static Task> SelectAsync(this IDbConnection dbConn, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectAsync(token)); } /// /// Returns results from using sql. E.g: - /// db.Select<Person>("Age > 40") - /// db.Select<Person>("SELECT * FROM Person WHERE Age > 40") + /// db.SelectAsync<Person>("Age > 40") + /// db.SelectAsync<Person>("SELECT * FROM Person WHERE Age > 40") /// - public static Task> SelectAsync(this IDbConnection dbConn, string sql, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, string sql, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SelectAsync(sql, null, token)); + return dbConn.Exec(dbCmd => dbCmd.SelectAsync(sql, (object)null, token)); } /// /// Returns results from using a parameterized query. E.g: - /// db.Select<Person>("Age > @age", new { age = 40}) - /// db.Select<Person>("SELECT * FROM Person WHERE Age > @age", new { age = 40}) + /// db.SelectAsync<Person>("Age > @age", new { age = 40}) + /// db.SelectAsync<Person>("SELECT * FROM Person WHERE Age > @age", new[] { db.CreateParam("age",40) }) /// - public static Task> SelectAsync(this IDbConnection dbConn, string sql, object anonType, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SelectAsync(sql, anonType, token)); + return dbConn.Exec(dbCmd => dbCmd.SelectAsync(sql, sqlParams, token)); } /// /// Returns results from using a parameterized query. E.g: - /// db.Select<Person>("Age > @age", new Dictionary<string, object> { { "age", 40 } }) - /// db.Select<Person>("SELECT * FROM Person WHERE Age > @age", new Dictionary<string, object> { { "age", 40 } }) + /// db.SelectAsync<Person>("Age > @age", new { age = 40}) + /// db.SelectAsync<Person>("SELECT * FROM Person WHERE Age > @age", new { age = 40}) /// - public static Task> SelectAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, string sql, object anonType, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SelectAsync(sql, dict, token)); + return dbConn.Exec(dbCmd => dbCmd.SelectAsync(sql, anonType, token)); } /// - /// Returns results from using an SqlFormat query. E.g: - /// db.SelectFmt<Person>("Age > {0}", 40) - /// db.SelectFmt<Person>("SELECT * FROM Person WHERE Age > {0}", 40) + /// Returns results from using a parameterized query. E.g: + /// db.SelectAsync<Person>("Age > @age", new Dictionary<string, object> { { "age", 40 } }) + /// db.SelectAsync<Person>("SELECT * FROM Person WHERE Age > @age", new Dictionary<string, object> { { "age", 40 } }) /// - public static Task> SelectFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] filterParams) + public static Task> SelectAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(token, sqlFormat, filterParams)); - } - public static Task> SelectFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) - { - return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(default(CancellationToken), sqlFormat, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.SelectAsync(sql, dict, token)); } /// /// Returns a partial subset of results from the specified tableType. E.g: - /// db.Select<EntityWithId>(typeof(Person)) + /// db.SelectAsync<EntityWithId>(typeof(Person)) /// /// - public static Task> SelectAsync(this IDbConnection dbConn, Type fromTableType, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, Type fromTableType, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectAsync(fromTableType, token)); } /// - /// Returns a partial subset of results from the specified tableType using a SqlFormat query. E.g: - /// db.SelectFmt<EntityWithId>(typeof(Person), "Age > {0}", 40) + /// Returns a partial subset of results from the specified tableType. E.g: + /// db.SelectAsync<EntityWithId>(typeof(Person), "Age = @age", new { age = 27 }) + /// /// - public static Task> SelectFmtAsync(this IDbConnection dbConn, CancellationToken token, Type fromTableType, string sqlFormat, params object[] filterParams) + public static Task> SelectAsync(this IDbConnection dbConn, Type fromTableType, string sqlFilter, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(token, fromTableType, sqlFormat, filterParams)); - } - public static Task> SelectFmtAsync(this IDbConnection dbConn, Type fromTableType, string sqlFormat, params object[] filterParams) - { - return dbConn.Exec(dbCmd => dbCmd.SelectFmtAsync(default(CancellationToken), fromTableType, sqlFormat, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.SelectAsync(fromTableType, sqlFilter, anonType, token)); } /// /// Returns results from using a single name, value filter. E.g: - /// db.Where<Person>("Age", 27) + /// db.WhereAsync<Person>("Age", 27) /// - public static Task> WhereAsync(this IDbConnection dbConn, string name, object value, CancellationToken token = default(CancellationToken)) + public static Task> WhereAsync(this IDbConnection dbConn, string name, object value, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.WhereAsync(name, value, token)); } /// /// Returns results from using an anonymous type filter. E.g: - /// db.Where<Person>(new { Age = 27 }) + /// db.WhereAsync<Person>(new { Age = 27 }) /// - public static Task> WhereAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default(CancellationToken)) + public static Task> WhereAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.WhereAsync(anonType, token)); } /// /// Returns results using the supplied primary key ids. E.g: - /// db.SelectByIds<Person>(new[] { 1, 2, 3 }) + /// db.SelectByIdsAsync<Person>(new[] { 1, 2, 3 }) /// - public static Task> SelectByIdsAsync(this IDbConnection dbConn, IEnumerable idValues, CancellationToken token = default(CancellationToken)) + public static Task> SelectByIdsAsync(this IDbConnection dbConn, IEnumerable idValues, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectByIdsAsync(idValues, token)); } /// /// Query results using the non-default values in the supplied partially populated POCO example. E.g: - /// db.SelectNonDefaults(new Person { Id = 1 }) + /// db.SelectNonDefaultsAsync(new Person { Id = 1 }) /// - public static Task> SelectNonDefaultsAsync(this IDbConnection dbConn, T filter, CancellationToken token = default(CancellationToken)) + public static Task> SelectNonDefaultsAsync(this IDbConnection dbConn, T filter, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectNonDefaultsAsync(filter, token)); } /// /// Query results using the non-default values in the supplied partially populated POCO example. E.g: - /// db.SelectNonDefaults("Age > @Age", new Person { Age = 42 }) + /// db.SelectNonDefaultsAsync("Age > @Age", new Person { Age = 42 }) /// - public static Task> SelectNonDefaultsAsync(this IDbConnection dbConn, string sql, T filter, CancellationToken token = default(CancellationToken)) + public static Task> SelectNonDefaultsAsync(this IDbConnection dbConn, string sql, T filter, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectNonDefaultsAsync(sql, filter, token)); } /// /// Returns the first result using a parameterized query. E.g: - /// db.Single<Person>(new { Age = 42 }) + /// db.SingleAsync<Person>(new { Age = 42 }) /// - public static Task SingleAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default(CancellationToken)) + public static Task SingleAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SingleAsync(anonType, token)); } /// /// Returns results from using a single name, value filter. E.g: - /// db.Single<Person>("Age = @age", new { age = 42 }) + /// db.SingleAsync<Person>("Age = @age", new[] { db.CreateParam("age",42) }) /// - public static Task SingleAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task SingleAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SingleAsync(sql, anonType, token)); + return dbConn.Exec(dbCmd => dbCmd.SingleAsync(sql, sqlParams, token)); } /// - /// Returns the first result using a SqlFormat query. E.g: - /// db.SingleFmt<Person>("Age = {0}", 42) + /// Returns results from using a single name, value filter. E.g: + /// db.SingleAsync<Person>("Age = @age", new { age = 42 }) /// - public static Task SingleFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] filterParams) + public static Task SingleAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SingleFmtAsync(token, sqlFormat, filterParams)); - } - public static Task SingleFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) - { - return dbConn.Exec(dbCmd => dbCmd.SingleFmtAsync(default(CancellationToken), sqlFormat, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.SingleAsync(sql, anonType, token)); } /// /// Returns the first result using a primary key id. E.g: - /// db.SingleById<Person>(1) + /// db.SingleByIdAsync<Person>(1) /// - public static Task SingleByIdAsync(this IDbConnection dbConn, object idValue, CancellationToken token = default(CancellationToken)) + public static Task SingleByIdAsync(this IDbConnection dbConn, object idValue, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SingleByIdAsync(idValue, token)); } /// /// Returns the first result using a name, value filter. E.g: - /// db.SingleWhere<Person>("Age", 42) + /// db.SingleWhereAsync<Person>("Age", 42) /// - public static Task SingleWhereAsync(this IDbConnection dbConn, string name, object value, CancellationToken token = default(CancellationToken)) + public static Task SingleWhereAsync(this IDbConnection dbConn, string name, object value, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SingleWhereAsync(name, value, token)); } + public static T ScalarAsync(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + if (sqlParams != null) + dbCmd.SetParameters(sqlParams); + + return dbCmd.Scalar(sql); + } + /// /// Returns a single scalar value using an SqlExpression. E.g: - /// db.Column<int>(db.From<Persion>().Select(x => Sql.Count("*")).Where(q => q.Age > 40)) + /// db.ScalarAsync<int>(db.From<Person>().Select(x => Sql.Count("*")).Where(q => q.Age > 40)) /// - public static Task ScalarAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default(CancellationToken)) + public static Task ScalarAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(sqlExpression.ToSelectStatement(), token)); + return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(sqlExpression.ToSelectStatement(QueryType.Scalar), sqlExpression.Params, token)); } /// /// Returns a single scalar value using a parameterized query. E.g: - /// db.Scalar<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }) + /// db.ScalarAsync<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new[] { db.CreateParam("age",40) }) /// - public static Task ScalarAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task ScalarAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(sql, anonType, token)); + return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(sql, sqlParams, token)); } /// - /// Returns a single scalar value using an SqlFormat query. E.g: - /// db.ScalarFmt<int>("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40) + /// Returns a single scalar value using a parameterized query. E.g: + /// db.ScalarAsync<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }) /// - public static Task ScalarFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + public static Task ScalarAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ScalarFmtAsync(token, sqlFormat, sqlParams)); - } - public static Task ScalarFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) - { - return dbConn.Exec(dbCmd => dbCmd.ScalarFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(sql, anonType, token)); } /// /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: - /// db.Column<int>(db.From<Persion>().Select(x => x.LastName).Where(q => q.Age == 27)) + /// db.ColumnAsync<int>(db.From<Person>().Select(x => x.LastName).Where(q => q.Age == 27)) /// - public static Task> ColumnAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token = default(CancellationToken)) + public static Task> ColumnAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ColumnAsync(query.ToSelectStatement(), token)); + return dbConn.Exec(dbCmd => dbCmd.ColumnAsync(query.ToSelectStatement(QueryType.Select), query.Params, token)); } /// /// Returns the first column in a List using a SqlFormat query. E.g: - /// db.Column<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) + /// db.ColumnAsync<string>("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age",27) }) /// - public static Task> ColumnAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task> ColumnAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ColumnAsync(sql, anonType, token)); + return dbConn.Exec(dbCmd => dbCmd.ColumnAsync(sql, sqlParams, token)); } /// /// Returns the first column in a List using a SqlFormat query. E.g: - /// db.ColumnFmt<string>("SELECT LastName FROM Person WHERE Age = {0}", 27) + /// db.ColumnAsync<string>("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }) /// - public static Task> ColumnFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) - { - return dbConn.Exec(dbCmd => dbCmd.ColumnFmtAsync(token, sqlFormat, sqlParams)); - } - public static Task> ColumnFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + public static Task> ColumnAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ColumnFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.ColumnAsync(sql, anonType, token)); } /// /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: - /// db.ColumnDistinct<int>(db.From<Persion>().Select(x => x.Age).Where(q => q.Age < 50)) + /// db.ColumnDistinctAsync<int>(db.From<Person>().Select(x => x.Age).Where(q => q.Age < 50)) /// - public static Task> ColumnDistinctAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token = default(CancellationToken)) + public static Task> ColumnDistinctAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctAsync(query.ToSelectStatement(), token)); + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctAsync(query.ToSelectStatement(QueryType.Select), query.Params, token)); } /// /// Returns the distinct first column values in a HashSet using an SqlFormat query. E.g: - /// db.ColumnDistinct<int>("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }) + /// db.ColumnDistinctAsync<int>("SELECT Age FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) /// - public static Task> ColumnDistinctAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task> ColumnDistinctAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctAsync(sql, anonType, token)); + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctAsync(sql, sqlParams, token)); } /// /// Returns the distinct first column values in a HashSet using an SqlFormat query. E.g: - /// db.ColumnDistinctFmt<int>("SELECT Age FROM Person WHERE Age < {0}", 50) + /// db.ColumnDistinctAsync<int>("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }) /// - public static Task> ColumnDistinctFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) - { - return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctFmtAsync(token, sqlFormat, sqlParams)); - } - public static Task> ColumnDistinctFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + public static Task> ColumnDistinctAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.ColumnDistinctAsync(sql, anonType, token)); } /// /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an Sql Expression. E.g: - /// db.Lookup<int, string>(db.From<Person>().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)) + /// db.LookupAsync<int, string>(db.From<Person>().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)) /// - public static Task>> LookupAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default(CancellationToken)) + public static Task>> LookupAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LookupAsync(sqlExpression.ToSelectStatement(), token)); + return dbConn.Exec(dbCmd => dbCmd.LookupAsync(sqlExpression.ToSelectStatement(QueryType.Select), sqlExpression.Params, token)); } /// /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an parameterized query. E.g: - /// db.Lookup<int, string>("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }) + /// db.LookupAsync<int, string>("SELECT Age, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) /// - public static Task>> LookupAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task>> LookupAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LookupAsync(sql, anonType, token)); + return dbConn.Exec(dbCmd => dbCmd.LookupAsync(sql, sqlParams, token)); } /// - /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an SqlFormat query. E.g: - /// db.LookupFmt<int, string>("SELECT Age, LastName FROM Person WHERE Age < {0}", 50) + /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an parameterized query. E.g: + /// db.LookupAsync<int, string>("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }) /// - public static Task>> LookupFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + public static Task>> LookupAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LookupFmtAsync(token, sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.LookupAsync(sql, anonType, token)); } - public static Task>> LookupFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + + /// + /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlExpression. E.g: + /// db.DictionaryAsync<int, string>(db.From<Person>().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)) + /// + public static Task> DictionaryAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LookupFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.DictionaryAsync(query.ToSelectStatement(QueryType.Select), query.Params, token)); } /// - /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlExpression. E.g: - /// db.Dictionary<int, string>(db.From<Person>().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)) + /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using sql. E.g: + /// db.DictionaryAsync<int, string>("SELECT Id, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) /// - public static Task> DictionaryAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token = default(CancellationToken)) + public static Task> DictionaryAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DictionaryAsync(query.ToSelectStatement(), token)); + return dbConn.Exec(dbCmd => dbCmd.DictionaryAsync(sql, sqlParams, token)); } /// /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using sql. E.g: - /// db.Dictionary<int, string>("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }) + /// db.DictionaryAsync<int, string>("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }) /// - public static Task> DictionaryAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task> DictionaryAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.DictionaryAsync(sql, anonType, token)); } /// - /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlFormat query. E.g: - /// db.DictionaryFmt<int, string>("SELECT Id, LastName FROM Person WHERE Age < {0}", 50) + /// Returns a list of KeyValuePairs from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlExpression. E.g: + /// db.KeyValuePairsAsync<int, string>(db.From<Person>().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)) /// - public static Task> DictionaryFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] sqlParams) + public static Task>> KeyValuePairsAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DictionaryFmtAsync(token, sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.KeyValuePairsAsync(query.ToSelectStatement(QueryType.Select), query.Params, token)); } - public static Task> DictionaryFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] sqlParams) + + /// + /// Returns a list of KeyValuePairs from the first 2 columns: Column 1 (Keys), Column 2 (Values) using sql. E.g: + /// db.KeyValuePairsAsync<int, string>("SELECT Id, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) + /// + public static Task>> KeyValuePairsAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DictionaryFmtAsync(default(CancellationToken), sqlFormat, sqlParams)); + return dbConn.Exec(dbCmd => dbCmd.KeyValuePairsAsync(sql, sqlParams, token)); } /// - /// Returns true if the Query returns any records that match the LINQ expression, E.g: - /// db.Exists<Person>(x => x.Age < 50) + /// Returns a list of KeyValuePairs from the first 2 columns: Column 1 (Keys), Column 2 (Values) using sql. E.g: + /// db.KeyValuePairsAsync<int, string>("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }) /// - public static Task ExistsAsync(this IDbConnection dbConn, Expression> expression, CancellationToken token = default(CancellationToken)) + public static Task>> KeyValuePairsAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token).Then(x => x > 0)); + return dbConn.Exec(dbCmd => dbCmd.KeyValuePairsAsync(sql, anonType, token)); } /// - /// Returns true if the Query returns any records that match the SqlExpression lambda, E.g: - /// db.Exists<Person>(q => q.Where(x => x.Age < 50)) + /// Returns true if the Query returns any records that match the LINQ expression, E.g: + /// db.ExistsAsync<Person>(x => x.Age < 50) /// - public static Task ExistsAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default(CancellationToken)) + public static Task ExistsAsync(this IDbConnection dbConn, Expression> expression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token).Then(x => x > 0)); + return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(dbConn.From().Where(expression).Limit(1).Select("'exists'"), token).Then(x => x != null)); } /// /// Returns true if the Query returns any records that match the supplied SqlExpression, E.g: - /// db.Exists(db.From<Person>().Where(x => x.Age < 50)) + /// db.ExistsAsync(db.From<Person>().Where(x => x.Age < 50)) /// - public static Task ExistsAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) + public static Task ExistsAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token).Then(x => x > 0)); + return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(expression.Limit(1).Select("'exists'"), token).Then(x => x != null)); } /// /// Returns true if the Query returns any records, using an SqlFormat query. E.g: - /// db.Exists<Person>(new { Age = 42 }) + /// db.ExistsAsync<Person>(new { Age = 42 }) /// - public static Task ExistsAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default(CancellationToken)) + public static Task ExistsAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.ExistsAsync(anonType, token)); } /// /// Returns true if the Query returns any records, using a parameterized query. E.g: - /// db.Exists<Person>("Age = @age", new { age = 42 }) - /// db.Exists<Person>("SELECT * FROM Person WHERE Age = @age", new { age = 42 }) + /// db.ExistsAsync<Person>("Age = @age", new { age = 42 }) + /// db.ExistsAsync<Person>("SELECT * FROM Person WHERE Age = @age", new { age = 42 }) /// - public static Task ExistsAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task ExistsAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.ExistsAsync(sql, anonType, token)); } /// - /// Returns true if the Query returns any records, using an SqlFormat query. E.g: - /// db.ExistsFmt<Person>("Age = {0}", 42) - /// db.ExistsFmt<Person>("SELECT * FROM Person WHERE Age = {0}", 50) + /// Returns results from an arbitrary SqlExpression. E.g: + /// db.SqlListAsync<Person>(db.From<Person>().Select("*").Where(q => q.Age < 50)) /// - public static Task ExistsFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFormat, params object[] filterParams) + public static Task> SqlListAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ExistsFmtAsync(token, sqlFormat, filterParams)); - } - public static Task ExistsFmtAsync(this IDbConnection dbConn, string sqlFormat, params object[] filterParams) - { - return dbConn.Exec(dbCmd => dbCmd.ExistsFmtAsync(default(CancellationToken), sqlFormat, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.SqlListAsync(sqlExpression.ToSelectStatement(QueryType.Select), sqlExpression.Params, token)); } /// - /// Returns results from an arbitrary SqlExpression. E.g: - /// db.SqlList<Person>(db.From<Person>().Select("*").Where(q => q.Age < 50)) + /// Returns results from an arbitrary parameterized raw sql query. E.g: + /// db.SqlListAsync<Person>("EXEC GetRockstarsAged @age", new { age = 50 }) /// - public static Task> SqlListAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default(CancellationToken)) + public static Task> SqlListAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SqlListAsync(sqlExpression.ToSelectStatement(), (object)null, token)); + return dbConn.Exec(dbCmd => dbCmd.SqlListAsync(sql, sqlParams, token)); } /// /// Returns results from an arbitrary parameterized raw sql query. E.g: - /// db.SqlList<Person>("EXEC GetRockstarsAged @age", new { age = 50 }) + /// db.SqlListAsync<Person>("EXEC GetRockstarsAged @age", new { age = 50 }) /// - public static Task> SqlListAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task> SqlListAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlListAsync(sql, anonType, token)); } /// /// Returns results from an arbitrary parameterized raw sql query. E.g: - /// db.SqlList<Person>("EXEC GetRockstarsAged @age", new Dictionary<string, object> { { "age", 42 } }) + /// db.SqlListAsync<Person>("EXEC GetRockstarsAged @age", new Dictionary<string, object> { { "age", 42 } }) /// - public static Task> SqlListAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default(CancellationToken)) + public static Task> SqlListAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlListAsync(sql, dict, token)); } /// /// Returns results from an arbitrary parameterized raw sql query with a dbCmd filter. E.g: - /// db.SqlList<Person>("EXEC GetRockstarsAged @age", dbCmd => ...) + /// db.SqlListAsync<Person>("EXEC GetRockstarsAged @age", dbCmd => ...) /// - public static Task> SqlListAsync(this IDbConnection dbConn, string sql, Action dbCmdFilter, CancellationToken token = default(CancellationToken)) + public static Task> SqlListAsync(this IDbConnection dbConn, string sql, Action dbCmdFilter, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlListAsync(sql, dbCmdFilter, token)); } /// /// Returns the first column in a List using an SqlExpression. E.g: - /// db.SqlColumn<string>(db.From<Person>().Select(x => x.LastName).Where(q => q.Age < 50)) + /// db.SqlColumnAsync<string>(db.From<Person>().Select(x => x.LastName).Where(q => q.Age < 50)) /// - public static Task> SqlColumnAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default(CancellationToken)) + public static Task> SqlColumnAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SqlColumnAsync(sqlExpression.ToSelectStatement(), null, token)); + return dbConn.Exec(dbCmd => dbCmd.SqlColumnAsync(sqlExpression.ToSelectStatement(QueryType.Select), sqlExpression.Params, token)); } /// /// Returns the first column in a List using a parameterized query. E.g: - /// db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }) + /// db.SqlColumnAsync<string>("SELECT LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) /// - public static Task> SqlColumnAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task> SqlColumnAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.SqlColumnAsync(sql, sqlParams, token)); + } + + /// + /// Returns the first column in a List using a parameterized query. E.g: + /// db.SqlColumnAsync<string>("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }) + /// + public static Task> SqlColumnAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlColumnAsync(sql, anonType, token)); } /// /// Returns the first column in a List using a parameterized query. E.g: - /// db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } }) + /// db.SqlColumnAsync<string>("SELECT LastName FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } }) /// - public static Task> SqlColumnAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default(CancellationToken)) + public static Task> SqlColumnAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlColumnAsync(sql, dict, token)); } /// /// Returns a single Scalar value using an SqlExpression. E.g: - /// db.SqlScalar<int>(db.From<Person>().Select(Sql.Count("*")).Where(q => q.Age < 50)) + /// db.SqlScalarAsync<int>(db.From<Person>().Select(Sql.Count("*")).Where(q => q.Age < 50)) /// - public static Task SqlScalarAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default(CancellationToken)) + public static Task SqlScalarAsync(this IDbConnection dbConn, ISqlExpression sqlExpression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SqlScalarAsync(sqlExpression.ToSelectStatement(), null, token)); + return dbConn.Exec(dbCmd => dbCmd.SqlScalarAsync(sqlExpression.ToSelectStatement(QueryType.Scalar), sqlExpression.Params, token)); } /// /// Returns a single Scalar value using a parameterized query. E.g: - /// db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }) + /// db.SqlScalarAsync<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }) /// - public static Task SqlScalarAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default(CancellationToken)) + public static Task SqlScalarAsync(this IDbConnection dbConn, string sql, IEnumerable sqlParams, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.SqlScalarAsync(sql, sqlParams, token)); + } + + /// + /// Returns a single Scalar value using a parameterized query. E.g: + /// db.SqlScalarAsync<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }) + /// + public static Task SqlScalarAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlScalarAsync(sql, anonType, token)); } /// /// Returns a single Scalar value using a parameterized query. E.g: - /// db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } }) + /// db.SqlScalarAsync<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } }) /// - public static Task SqlScalarAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default(CancellationToken)) + public static Task SqlScalarAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlScalarAsync(sql, dict, token)); } @@ -492,7 +501,7 @@ public static Task ExistsFmtAsync(this IDbConnection dbConn, string sql /// var rowsAffected = db.ExecuteNonQueryAsync("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFormat("WaterHouse", 7)) /// /// number of rows affected - public static Task ExecuteNonQueryAsync(this IDbConnection dbConn, string sql, CancellationToken token = default(CancellationToken)) + public static Task ExecuteNonQueryAsync(this IDbConnection dbConn, string sql, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.ExecNonQueryAsync(sql, null, token)); } @@ -502,7 +511,7 @@ public static Task ExistsFmtAsync(this IDbConnection dbConn, string sql /// var rowsAffected = db.ExecuteNonQueryAsync("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }) /// /// number of rows affected - public static Task ExecuteNonQueryAsync(this IDbConnection dbConn, string sql, object anonType, CancellationToken token = default(CancellationToken)) + public static Task ExecuteNonQueryAsync(this IDbConnection dbConn, string sql, object anonType, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.ExecNonQueryAsync(sql, anonType, token)); } @@ -511,7 +520,7 @@ public static Task ExistsFmtAsync(this IDbConnection dbConn, string sql /// Executes a raw sql non-query using a parameterized query. /// /// number of rows affected - public static Task ExecuteNonQueryAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default(CancellationToken)) + public static Task ExecuteNonQueryAsync(this IDbConnection dbConn, string sql, Dictionary dict, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.ExecNonQueryAsync(sql, dict, token)); } @@ -519,49 +528,44 @@ public static Task ExistsFmtAsync(this IDbConnection dbConn, string sql /// /// Returns results from a Stored Procedure, using a parameterized query. /// - public static Task> SqlProcedureAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default(CancellationToken)) + public static Task> SqlProcedureAsync(this IDbConnection dbConn, object anonType, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SqlProcedureAsync(anonType, token)); } /// - /// Returns results from a Stored Procedure using an SqlFormat query. E.g: - /// + /// Returns the scalar result as a long. /// - public static Task> SqlProcedureFmtAsync(this IDbConnection dbConn, CancellationToken token, - object anonType, - string sqlFilter, - params object[] filterParams) - where TOutputModel : new() + public static Task LongScalarAsync(this IDbConnection dbConn, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SqlProcedureFmtAsync(token, - anonType, sqlFilter, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.ExecLongScalarAsync(null, token)); } /// - /// Returns the scalar result as a long. + /// Returns the first result with all its references loaded, using a primary key id. E.g: + /// db.LoadSingleByIdAsync<Person>(1) /// - public static Task LongScalarAsync(this IDbConnection dbConn, CancellationToken token = default(CancellationToken)) + public static Task LoadSingleByIdAsync(this IDbConnection dbConn, object idValue, string[] include = null, CancellationToken token=default(CancellationToken)) { - return dbConn.Exec(dbCmd => dbCmd.ExecLongScalarAsync(null, token)); + return dbConn.Exec(dbCmd => dbCmd.LoadSingleByIdAsync(idValue, include, token)); } /// /// Returns the first result with all its references loaded, using a primary key id. E.g: - /// db.LoadSingleById<Person>(1) + /// db.LoadSingleByIdAsync<Person>(1, include = x => new { x.Address }) /// - public static Task LoadSingleByIdAsync(this IDbConnection dbConn, object idValue, CancellationToken token=default(CancellationToken)) + public static Task LoadSingleByIdAsync(this IDbConnection dbConn, object idValue, Expression> include, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LoadSingleByIdAsync(idValue, token)); + return dbConn.Exec(dbCmd => dbCmd.LoadSingleByIdAsync(idValue, include.GetFieldNames(), token)); } /// /// Loads all the related references onto the instance. E.g: /// db.LoadReferencesAsync(customer) /// - public static Task LoadReferencesAsync(this IDbConnection dbConn, T instance, CancellationToken token = default(CancellationToken)) + public static Task LoadReferencesAsync(this IDbConnection dbConn, T instance, string[] include = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LoadReferencesAsync(instance, token)); + return dbConn.Exec(dbCmd => dbCmd.LoadReferencesAsync(instance, include, token)); } } } diff --git a/src/ServiceStack.OrmLite/OrmLiteReadCommandExtensions.cs b/src/ServiceStack.OrmLite/OrmLiteReadCommandExtensions.cs index 0d3a66649..6c97730eb 100644 --- a/src/ServiceStack.OrmLite/OrmLiteReadCommandExtensions.cs +++ b/src/ServiceStack.OrmLite/OrmLiteReadCommandExtensions.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // @@ -23,39 +23,39 @@ namespace ServiceStack.OrmLite { - public delegate string GetQuotedValueDelegate(object value, Type fieldType); - public delegate object ConvertDbValueDelegate(object value, Type type); - public delegate void PropertySetterDelegate(object instance, object value); - public delegate object PropertyGetterDelegate(object instance); - public delegate object GetValueDelegate(int i); public static class OrmLiteReadCommandExtensions { - private static readonly ILog Log = LogManager.GetLogger(typeof(OrmLiteReadCommandExtensions)); + internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteReadCommandExtensions)); public const string UseDbConnectionExtensions = "Use IDbConnection Extensions instead"; - private static void LogDebug(string fmt) - { - Log.Debug(fmt); - } - internal static IDataReader ExecReader(this IDbCommand dbCmd, string sql) { + dbCmd.CommandText = sql; + if (Log.IsDebugEnabled) - LogDebug(sql); + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); - dbCmd.CommandTimeout = OrmLiteConfig.CommandTimeout; - dbCmd.CommandText = sql; return dbCmd.ExecuteReader(); } - internal static IDataReader ExecReader(this IDbCommand dbCmd, string sql, IEnumerable parameters) + internal static IDataReader ExecReader(this IDbCommand dbCmd, string sql, CommandBehavior commandBehavior) { + dbCmd.CommandText = sql; + if (Log.IsDebugEnabled) - LogDebug(sql); + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + + return dbCmd.ExecuteReader(commandBehavior); + } - dbCmd.CommandTimeout = OrmLiteConfig.CommandTimeout; + internal static IDataReader ExecReader(this IDbCommand dbCmd, string sql, IEnumerable parameters) + { dbCmd.CommandText = sql; dbCmd.Parameters.Clear(); @@ -64,153 +64,289 @@ internal static IDataReader ExecReader(this IDbCommand dbCmd, string sql, IEnume dbCmd.Parameters.Add(param); } + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + return dbCmd.ExecuteReader(); } internal static List Select(this IDbCommand dbCmd) { - return SelectFmt(dbCmd, (string)null); + return Select(dbCmd, (string)null); } - internal static List SelectFmt(this IDbCommand dbCmd, string sqlFilter, params object[] filterParams) + internal static void SetFilter(this IDbCommand dbCmd, string name, object value) { - return dbCmd.ConvertToList( - dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sqlFilter, filterParams)); + var dialectProvider = dbCmd.GetDialectProvider(); + + dbCmd.Parameters.Clear(); + var p = dbCmd.CreateParameter(); + p.ParameterName = name; + p.Direction = ParameterDirection.Input; + dialectProvider.InitDbParam(p, value.GetType(), value); + + dbCmd.Parameters.Add(p); + dbCmd.CommandText = GetFilterSql(dbCmd); } - internal static List Select(this IDbCommand dbCmd, Type fromTableType) + internal static IDbCommand SetFilters(this IDbCommand dbCmd, object anonType, bool excludeDefaults) { - return SelectFmt(dbCmd, fromTableType, null); + string ignore = null; + dbCmd.SetParameters(anonType, excludeDefaults, ref ignore); //needs to be called first + dbCmd.CommandText = dbCmd.GetFilterSql(); + return dbCmd; } - internal static List SelectFmt(this IDbCommand dbCmd, Type fromTableType, string sqlFilter, params object[] filterParams) + internal static void PopulateWith(this IDbCommand dbCmd, ISqlExpression expression, QueryType queryType) { - var sql = ToSelectFmt(dbCmd.GetDialectProvider(), fromTableType, sqlFilter, filterParams); - - return dbCmd.ConvertToList(sql.ToString()); + dbCmd.CommandText = expression.ToSelectStatement(queryType); //needs to evaluate SQL before setting params + dbCmd.SetParameters(expression.Params); } - internal static StringBuilder ToSelectFmt(IOrmLiteDialectProvider dialectProvider, Type fromTableType, string sqlFilter, object[] filterParams) + internal static IDbCommand SetParameters(this IDbCommand dbCmd, object anonType, bool excludeDefaults, ref string sql) => + dbCmd.SetParameters(typeof(T), anonType, excludeDefaults, ref sql); + + internal static IDbCommand SetParameters(this IDbCommand dbCmd, IEnumerable sqlParams) { - var sql = new StringBuilder(); - var modelDef = ModelDefinition.Definition; - sql.AppendFormat("SELECT {0} FROM {1}", dialectProvider.GetColumnNames(modelDef), - dialectProvider.GetQuotedTableName(fromTableType.GetModelDefinition())); - if (!string.IsNullOrEmpty(sqlFilter)) + if (sqlParams == null) + return dbCmd; + + try { - sqlFilter = sqlFilter.SqlFmt(filterParams); - sql.Append(" WHERE "); - sql.Append(sqlFilter); + dbCmd.Parameters.Clear(); + foreach (var sqlParam in sqlParams) + { + dbCmd.Parameters.Add(sqlParam); + } } - return sql; - } + catch (Exception ex) + { + //SQL Server + PostgreSql doesn't allow re-using db params in multiple queries + if (Log.IsDebugEnabled) + Log.Debug("Exception trying to reuse db params, executing with cloned params instead", ex); - internal static T SelectByIdFmt(this IDbCommand dbCmd, object idValue) - { - return SingleFmt(dbCmd, dbCmd.GetDialectProvider().GetQuotedColumnName(ModelDefinition.PrimaryKeyName) + " = {0}".SqlFmt(idValue)); + dbCmd.Parameters.Clear(); + foreach (var sqlParam in sqlParams) + { + var p = dbCmd.CreateParameter(); + p.PopulateWith(sqlParam); + dbCmd.Parameters.Add(p); + } + } + + return dbCmd; } - internal static T SingleFmt(this IDbCommand dbCmd, string filter, params object[] filterParams) + private static IEnumerable GetMultiValues(object value) { - return dbCmd.ConvertTo(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), filter, filterParams)); + if (value is SqlInValues inValues) + return inValues.GetValues(); + + return (value is IEnumerable enumerable && + !(enumerable is string || + enumerable is IEnumerable> || + enumerable is byte[]) + ) ? enumerable : null; } - [ThreadStatic] - private static Type lastQueryType; - internal static void SetFilter(this IDbCommand dbCmd, string name, object value) + internal static IDbCommand SetParameters(this IDbCommand dbCmd, Dictionary dict, bool excludeDefaults, ref string sql) { + if (dict == null) + return dbCmd; + dbCmd.Parameters.Clear(); - var p = dbCmd.CreateParameter(); - p.ParameterName = name; - p.DbType = dbCmd.GetDialectProvider().GetColumnDbType(value.GetType()); - p.Direction = ParameterDirection.Input; - dbCmd.Parameters.Add(p); - dbCmd.CommandText = GetFilterSql(dbCmd); - lastQueryType = typeof(T); - } + var dialectProvider = dbCmd.GetDialectProvider(); - internal static void SetFilters(this IDbCommand dbCmd, object anonType, bool excludeDefaults) - { - dbCmd.SetParameters(anonType, excludeDefaults); + var paramIndex = 0; + var sqlCopy = sql; //C# doesn't allow changing ref params in lambda's - dbCmd.CommandText = dbCmd.GetFilterSql(); + foreach (var kvp in dict) + { + var value = kvp.Value; + var propName = kvp.Key; + if (excludeDefaults && value == null) continue; + + var inValues = sql != null ? GetMultiValues(value) : null; + if (inValues != null) + { + var propType = value?.GetType() ?? typeof(object); + var sb = StringBuilderCache.Allocate(); + foreach (var item in inValues) + { + var p = dbCmd.CreateParameter(); + p.ParameterName = "v" + paramIndex++; + + if (sb.Length > 0) + sb.Append(','); + sb.Append(dialectProvider.ParamString + p.ParameterName); + + p.Direction = ParameterDirection.Input; + dialectProvider.InitDbParam(p, item.GetType()); + + dialectProvider.SetParamValue(p, item, item.GetType()); + + dbCmd.Parameters.Add(p); + } + + var sqlIn = StringBuilderCache.ReturnAndFree(sb); + if (string.IsNullOrEmpty(sqlIn)) + sqlIn = "NULL"; + sqlCopy = sqlCopy?.Replace(dialectProvider.ParamString + propName, sqlIn); + if (dialectProvider.ParamString != "@") + sqlCopy = sqlCopy?.Replace("@" + propName, sqlIn); + } + else + { + var p = dbCmd.CreateParameter(); + p.ParameterName = propName; + + p.Direction = ParameterDirection.Input; + p.Value = value ?? DBNull.Value; + if (value != null) + dialectProvider.InitDbParam(p, value.GetType()); + + dbCmd.Parameters.Add(p); + } + } + + sql = sqlCopy; + + return dbCmd; } - internal static void SetParameters(this IDbCommand dbCmd, object anonType, bool excludeDefaults) + internal static IDbCommand SetParameters(this IDbCommand dbCmd, Type type, object anonType, bool excludeDefaults, ref string sql) { + if (anonType == null) + return dbCmd; + dbCmd.Parameters.Clear(); - lastQueryType = null; + var modelDef = type.GetModelDefinition(); var dialectProvider = dbCmd.GetDialectProvider(); - var fieldMap = typeof(T).IsUserType() //Ensure T != Scalar() - ? dialectProvider.GetFieldDefinitionMap(typeof(T).GetModelDefinition()) + var fieldMap = type.IsUserType() //Ensure T != Scalar() + ? dialectProvider.GetFieldDefinitionMap(modelDef) : null; - anonType.ForEachParam(excludeDefaults, (pi, columnName, value) => - { - var p = dbCmd.CreateParameter(); - p.ParameterName = columnName; - p.DbType = dialectProvider.GetColumnDbType(pi.PropertyType); - p.Direction = ParameterDirection.Input; + var sqlCopy = sql; //C# doesn't allow changing ref params in lambda's + Dictionary anonTypeProps = null; - FieldDefinition fieldDef; - if (fieldMap != null && fieldMap.TryGetValue(columnName, out fieldDef)) + var paramIndex = 0; + anonType.ToObjectDictionary().ForEachParam(modelDef, excludeDefaults, (propName, columnName, value) => + { + var propType = value?.GetType() ?? ((anonTypeProps ??= TypeProperties.Get(anonType.GetType()).PropertyMap) + .TryGetValue(propName, out var pType) + ? pType.PropertyInfo.PropertyType + : typeof(object)); + var inValues = GetMultiValues(value); + if (inValues != null) { - value = dialectProvider.GetFieldValue(fieldDef, value); - var valueType = value != null ? value.GetType() : null; - if (valueType != null && valueType != pi.PropertyType) + var sb = StringBuilderCache.Allocate(); + foreach (var item in inValues) { - p.DbType = dialectProvider.GetColumnDbType(valueType); + var p = dbCmd.CreateParameter(); + p.ParameterName = "v" + paramIndex++; + + if (sb.Length > 0) + sb.Append(','); + sb.Append(dialectProvider.ParamString + p.ParameterName); + + p.Direction = ParameterDirection.Input; + dialectProvider.InitDbParam(p, item.GetType()); + + dialectProvider.SetParamValue(p, item, item.GetType()); + + dbCmd.Parameters.Add(p); } + + var sqlIn = StringBuilderCache.ReturnAndFree(sb); + if (string.IsNullOrEmpty(sqlIn)) + sqlIn = "NULL"; + sqlCopy = sqlCopy?.Replace(dialectProvider.ParamString + propName, sqlIn); + if (dialectProvider.ParamString != "@") + sqlCopy = sqlCopy?.Replace("@" + propName, sqlIn); } + else + { + var p = dbCmd.CreateParameter(); + p.ParameterName = propName; + p.Direction = ParameterDirection.Input; + dialectProvider.InitDbParam(p, propType); + + FieldDefinition fieldDef = null; + fieldMap?.TryGetValue(columnName, out fieldDef); - p.Value = value == null ? - DBNull.Value - : p.DbType == DbType.String ? - value.ToString() : - value; + dialectProvider.SetParamValue(p, value, propType, fieldDef); - dbCmd.Parameters.Add(p); + dbCmd.Parameters.Add(p); + } }); - } - internal delegate void ParamIterDelegate(PropertyInfo pi, string columnName, object value); + sql = sqlCopy; + return dbCmd; + } - internal static void ForEachParam(this object anonType, bool excludeDefaults, ParamIterDelegate fn) + internal static void SetParamValue(this IOrmLiteDialectProvider dialectProvider, IDbDataParameter p, object value, Type propType, FieldDefinition fieldDef=null) { - if (anonType == null) return; + if (fieldDef != null) + { + value = dialectProvider.GetFieldValue(fieldDef, value); + var valueType = value?.GetType(); + if (valueType != null && valueType != propType) + dialectProvider.InitDbParam(p, valueType); + } + else + { + value = dialectProvider.GetFieldValue(propType, value); + var valueType = value?.GetType(); + if (valueType != null && valueType != propType) + dialectProvider.InitDbParam(p, valueType); + } + + p.Value = value == null + ? DBNull.Value + : p.DbType == DbType.String + ? value.ToString() + : value; + } + + internal delegate void ParamIterDelegate(string propName, string columnName, object value); - var pis = anonType.GetType().GetSerializableProperties(); - var model = ModelDefinition.Definition; + internal static void ForEachParam(this Dictionary values, ModelDefinition modelDef, bool excludeDefaults, ParamIterDelegate fn) + { + if (values == null) + return; - foreach (var pi in pis) + foreach (var kvp in values) { - var mi = pi.GetGetMethod(); - if (mi == null) continue; + var value = kvp.Value; - var value = mi.Invoke(anonType, new object[0]); - if (excludeDefaults && (value == null || value.Equals(pi.PropertyType.GetDefaultValue()))) continue; + if (excludeDefaults && (value == null || value.Equals(value.GetType().GetDefaultValue()))) + continue; - var targetField = model != null ? model.FieldDefinitions.FirstOrDefault(f => String.Equals(f.Name, pi.Name)) : null; - var columnName = targetField != null && !String.IsNullOrEmpty(targetField.Alias) + var targetField = modelDef?.FieldDefinitions.FirstOrDefault(f => string.Equals(f.Name, kvp.Key)); + var columnName = !string.IsNullOrEmpty(targetField?.Alias) ? targetField.Alias - : pi.Name; + : kvp.Key; - fn(pi, columnName, value); + fn(kvp.Key, columnName, value); } } internal static List AllFields(this object anonType) { var ret = new List(); - ForEachParam(anonType, excludeDefaults: false, fn: (pi, columnName, value) => ret.Add(pi.Name)); + anonType.ToObjectDictionary().ForEachParam(typeof(T).GetModelDefinition(), excludeDefaults: false, fn: (propName, columnName, value) => ret.Add(propName)); return ret; } internal static Dictionary AllFieldsMap(this object anonType) { var ret = new Dictionary(); - ForEachParam(anonType, excludeDefaults: false, fn: (pi, columnName, value) => ret[pi.Name] = value); + anonType.ToObjectDictionary() + .ForEachParam(typeof(T).GetModelDefinition(), excludeDefaults: false, fn: + (propName, columnName, value) => ret[propName] = value); return ret; } @@ -231,69 +367,9 @@ internal static Dictionary NonDefaultsOnly(this Dictionary NonDefaultFields(this object anonType) - { - var ret = new List(); - ForEachParam(anonType, excludeDefaults: true, fn: (pi, columnName, value) => ret.Add(pi.Name)); - return ret; - } - - internal static void SetParameters(this IDbCommand dbCmd, object anonType, bool excludeDefaults) + public static IDbCommand SetFilters(this IDbCommand dbCmd, object anonType) { - dbCmd.Parameters.Clear(); - lastQueryType = null; - if (anonType == null) - return; - - var pis = anonType.GetType().GetSerializableProperties(); - - foreach (var pi in pis) - { - var mi = pi.GetGetMethod(); - if (mi == null) - continue; - - var value = mi.Invoke(anonType, new object[0]); - if (excludeDefaults && value == null) - continue; - - var p = dbCmd.CreateParameter(); - - p.ParameterName = pi.Name; - p.DbType = dbCmd.GetDialectProvider().GetColumnDbType(pi.PropertyType); - p.Direction = ParameterDirection.Input; - p.Value = value ?? DBNull.Value; - dbCmd.Parameters.Add(p); - } - } - - internal static void SetParameters(this IDbCommand dbCmd, IDictionary dict, bool excludeDefaults) - { - dbCmd.Parameters.Clear(); - lastQueryType = null; - if (dict == null) return; - - foreach (var kvp in dict) - { - var value = dict[kvp.Key]; - if (excludeDefaults && value == null) continue; - var p = dbCmd.CreateParameter(); - p.ParameterName = kvp.Key; - - if (value != null) - { - p.DbType = dbCmd.GetDialectProvider().GetColumnDbType(value.GetType()); - } - - p.Direction = ParameterDirection.Input; - p.Value = value ?? DBNull.Value; - dbCmd.Parameters.Add(p); - } - } - - public static void SetFilters(this IDbCommand dbCmd, object anonType) - { - dbCmd.SetFilters(anonType, excludeDefaults: false); + return dbCmd.SetFilters(anonType, excludeDefaults: false); } public static void ClearFilters(this IDbCommand dbCmd) @@ -303,52 +379,55 @@ public static void ClearFilters(this IDbCommand dbCmd) internal static string GetFilterSql(this IDbCommand dbCmd) { - var sb = new StringBuilder(); + var dialectProvider = dbCmd.GetDialectProvider(); + var modelDef = typeof(T).GetModelDefinition(); + + var sb = StringBuilderCache.Allocate(); foreach (IDbDataParameter p in dbCmd.Parameters) { if (sb.Length > 0) sb.Append(" AND "); - sb.Append(dbCmd.GetDialectProvider().GetQuotedColumnName(p.ParameterName)); + var fieldName = p.ParameterName; + var fieldDef = modelDef.GetFieldDefinition(fieldName); + if (fieldDef != null) + fieldName = fieldDef.FieldName; + + sb.Append(dialectProvider.GetQuotedColumnName(fieldName)); + + p.ParameterName = dialectProvider.SanitizeFieldNameForParamName(fieldName); + sb.Append(" = "); - sb.Append(dbCmd.GetDialectProvider().GetParam(p.ParameterName)); + sb.Append(dialectProvider.GetParam(p.ParameterName)); } - return dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sb.ToString()); + return dialectProvider.ToSelectStatement(typeof(T), StringBuilderCache.ReturnAndFree(sb)); } - internal static bool CanReuseParam(this IDbCommand dbCmd, string paramName) - { - return (dbCmd.Parameters.Count == 1 - && ((IDbDataParameter)dbCmd.Parameters[0]).ParameterName == paramName - && lastQueryType != typeof(T)); - } +// internal static bool CanReuseParam(this IDbCommand dbCmd, string paramName) +// { +// return (dbCmd.Parameters.Count == 1 +// && ((IDbDataParameter)dbCmd.Parameters[0]).ParameterName == paramName +// && lastQueryType != typeof(T)); +// } internal static List SelectByIds(this IDbCommand dbCmd, IEnumerable idValues) { - var sql = idValues.GetIdsInSql(); - return sql == null + var sqlIn = dbCmd.SetIdsInSqlParams(idValues); + return string.IsNullOrEmpty(sqlIn) ? new List() - : SelectFmt(dbCmd, dbCmd.GetDialectProvider().GetQuotedColumnName(ModelDefinition.PrimaryKeyName) + " IN (" + sql + ")"); + : Select(dbCmd, dbCmd.GetDialectProvider().GetQuotedColumnName(ModelDefinition.PrimaryKeyName) + " IN (" + sqlIn + ")"); } internal static T SingleById(this IDbCommand dbCmd, object value) { - if (!dbCmd.CanReuseParam(ModelDefinition.PrimaryKeyName)) - SetFilter(dbCmd, ModelDefinition.PrimaryKeyName, value); - - ((IDbDataParameter)dbCmd.Parameters[0]).Value = value; - + SetFilter(dbCmd, ModelDefinition.PrimaryKeyName, value); return dbCmd.ConvertTo(); } internal static T SingleWhere(this IDbCommand dbCmd, string name, object value) { - if (!dbCmd.CanReuseParam(name)) - SetFilter(dbCmd, name, value); - - ((IDbDataParameter)dbCmd.Parameters[0]).Value = value; - + SetFilter(dbCmd, name, value); return dbCmd.ConvertTo(); } @@ -359,22 +438,27 @@ internal static T Single(this IDbCommand dbCmd, object anonType) return dbCmd.ConvertTo(); } - internal static T Single(this IDbCommand dbCmd, string sql, object anonType) + internal static T Single(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) { - if (OrmLiteUtils.IsScalar()) return Scalar(dbCmd, sql, anonType); - - dbCmd.SetParameters(anonType, excludeDefaults: false); + dbCmd.SetParameters(sqlParams); - return dbCmd.ConvertTo(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql)); + return OrmLiteUtils.IsScalar() + ? dbCmd.Scalar(sql) + : dbCmd.ConvertTo(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql)); } - internal static List Where(this IDbCommand dbCmd, string name, object value) + internal static T Single(this IDbCommand dbCmd, string sql, object anonType) { - if (!dbCmd.CanReuseParam(name)) - SetFilter(dbCmd, name, value); + dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); - ((IDbDataParameter)dbCmd.Parameters[0]).Value = value; + return OrmLiteUtils.IsScalar() + ? dbCmd.Scalar(sql) + : dbCmd.ConvertTo(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql)); + } + internal static List Where(this IDbCommand dbCmd, string name, object value) + { + SetFilter(dbCmd, name, value); return dbCmd.ConvertToList(); } @@ -385,9 +469,17 @@ internal static List Where(this IDbCommand dbCmd, object anonType) return dbCmd.ConvertToList(); } + internal static List Select(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + dbCmd.CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); + if (sqlParams != null) dbCmd.SetParameters(sqlParams); + + return dbCmd.ConvertToList(); + } + internal static List Select(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); dbCmd.CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); return dbCmd.ConvertToList(); @@ -395,15 +487,51 @@ internal static List Select(this IDbCommand dbCmd, string sql, object anon internal static List Select(this IDbCommand dbCmd, string sql, Dictionary dict) { - if (dict != null) SetParameters(dbCmd, (IDictionary)dict, (bool)false); + if (dict != null) SetParameters(dbCmd, dict, (bool)false, sql:ref sql); dbCmd.CommandText = dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql); return dbCmd.ConvertToList(); } + internal static List Select(this IDbCommand dbCmd, Type fromTableType) + { + return Select(dbCmd, fromTableType, null); + } + + internal static List Select(this IDbCommand dbCmd, Type fromTableType, string sql, object anonType = null) + { + if (anonType != null) dbCmd.SetParameters(fromTableType, anonType, excludeDefaults: false, sql: ref sql); + dbCmd.CommandText = ToSelect(dbCmd.GetDialectProvider(), fromTableType, sql); + + return dbCmd.ConvertToList(); + } + + internal static string ToSelect(IOrmLiteDialectProvider dialectProvider, Type fromTableType, string sqlFilter) + { + var sql = StringBuilderCache.Allocate(); + var modelDef = ModelDefinition.Definition; + sql.Append( + $"SELECT {dialectProvider.GetColumnNames(modelDef)} " + + $"FROM {dialectProvider.GetQuotedTableName(fromTableType.GetModelDefinition())}"); + + if (string.IsNullOrEmpty(sqlFilter)) + return StringBuilderCache.ReturnAndFree(sql); + + sql.Append(" WHERE "); + sql.Append(sqlFilter); + return StringBuilderCache.ReturnAndFree(sql); + } + + internal static List SqlList(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + dbCmd.CommandText = sql; + + return dbCmd.SetParameters(sqlParams).ConvertToList(); + } + internal static List SqlList(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); dbCmd.CommandText = sql; return dbCmd.ConvertToList(); @@ -411,7 +539,7 @@ internal static List SqlList(this IDbCommand dbCmd, string sql, object ano internal static List SqlList(this IDbCommand dbCmd, string sql, Dictionary dict) { - if (dict != null) SetParameters(dbCmd, dict, false); + if (dict != null) SetParameters(dbCmd, dict, false, sql:ref sql); dbCmd.CommandText = sql; return dbCmd.ConvertToList(); @@ -419,38 +547,47 @@ internal static List SqlList(this IDbCommand dbCmd, string sql, Dictionary internal static List SqlList(this IDbCommand dbCmd, string sql, Action dbCmdFilter) { - if (dbCmdFilter != null) dbCmdFilter(dbCmd); + dbCmdFilter?.Invoke(dbCmd); dbCmd.CommandText = sql; return dbCmd.ConvertToList(); } - internal static List SqlColumn(this IDbCommand dbCmd, string sql, object anonType = null) + internal static List SqlColumn(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); - dbCmd.CommandText = sql; + dbCmd.SetParameters(sqlParams).CommandText = sql; + return dbCmd.ConvertToList(); + } + internal static List SqlColumn(this IDbCommand dbCmd, string sql, object anonType = null) + { + dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).CommandText = sql; return dbCmd.ConvertToList(); } internal static List SqlColumn(this IDbCommand dbCmd, string sql, Dictionary dict) { - if (dict != null) SetParameters(dbCmd, dict, false); + if (dict != null) SetParameters(dbCmd, dict, false, sql:ref sql); dbCmd.CommandText = sql; return dbCmd.ConvertToList(); } + internal static T SqlScalar(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + return dbCmd.SetParameters(sqlParams).Scalar(sql); + } + internal static T SqlScalar(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); return dbCmd.Scalar(sql); } internal static T SqlScalar(this IDbCommand dbCmd, string sql, Dictionary dict) { - if (dict != null) SetParameters(dbCmd, dict, false); + if (dict != null) SetParameters(dbCmd, dict, false, sql:ref sql); return dbCmd.Scalar(sql); } @@ -464,14 +601,19 @@ internal static List SelectNonDefaults(this IDbCommand dbCmd, object filte internal static List SelectNonDefaults(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults:true); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: true, sql: ref sql); return dbCmd.ConvertToList(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql)); } + internal static IEnumerable SelectLazy(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + foreach (var p in dbCmd.SetParameters(sqlParams).SelectLazy(sql)) yield return p; + } + internal static IEnumerable SelectLazy(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); var dialectProvider = dbCmd.GetDialectProvider(); dbCmd.CommandText = dialectProvider.ToSelectStatement(typeof(T), sql); @@ -485,22 +627,31 @@ internal static IEnumerable SelectLazy(this IDbCommand dbCmd, string sql, yield break; } - var fieldDefs = ModelDefinition.Definition.FieldDefinitionsArray; using (var reader = dbCmd.ExecuteReader()) { - var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition); + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider); + var values = new object[reader.FieldCount]; while (reader.Read()) { var row = OrmLiteUtils.CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, reader, fieldDefs, indexCache); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); yield return row; } } } - internal static IEnumerable ColumnLazy(this IDbCommand dbCmd, string sql, object anonType = null) + internal static IEnumerable ColumnLazy(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + foreach (var p in dbCmd.SetParameters(sqlParams).ColumnLazy(sql)) yield return p; + } + + internal static IEnumerable ColumnLazy(this IDbCommand dbCmd, string sql, object anonType) + { + foreach (var p in dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).ColumnLazy(sql)) yield return p; + } + + private static IEnumerable ColumnLazy(this IDbCommand dbCmd, string sql) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); var dialectProvider = dbCmd.GetDialectProvider(); dbCmd.CommandText = dialectProvider.ToSelectStatement(typeof(T), sql); @@ -517,7 +668,7 @@ internal static IEnumerable ColumnLazy(this IDbCommand dbCmd, string sql, { while (reader.Read()) { - var value = dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(T)); + var value = dialectProvider.FromDbValue(reader, 0, typeof(T)); if (value == DBNull.Value) yield return default(T); else @@ -539,15 +690,15 @@ internal static IEnumerable WhereLazy(this IDbCommand dbCmd, object anonTy yield break; } - var fieldDefs = ModelDefinition.Definition.FieldDefinitionsArray; var dialectProvider = dbCmd.GetDialectProvider(); using (var reader = dbCmd.ExecuteReader()) { - var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition); + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider); + var values = new object[reader.FieldCount]; while (reader.Read()) { var row = OrmLiteUtils.CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, reader, fieldDefs, indexCache); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); yield return row; } } @@ -555,109 +706,76 @@ internal static IEnumerable WhereLazy(this IDbCommand dbCmd, object anonTy internal static IEnumerable SelectLazy(this IDbCommand dbCmd) { - return SelectLazyFmt(dbCmd, null); - } - - internal static IEnumerable SelectLazyFmt(this IDbCommand dbCmd, string filter, params object[] filterParams) - { - var dialectProvider = dbCmd.GetDialectProvider(); - dbCmd.CommandText = dialectProvider.ToSelectStatement(typeof(T), filter, filterParams); - - if (OrmLiteConfig.ResultsFilter != null) - { - foreach (var item in OrmLiteConfig.ResultsFilter.GetList(dbCmd)) - { - yield return item; - } - yield break; - } - - var fieldDefs = ModelDefinition.Definition.FieldDefinitionsArray; - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition); - while (reader.Read()) - { - var row = OrmLiteUtils.CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, reader, fieldDefs, indexCache); - yield return row; - } - } + return SelectLazy(dbCmd, null); } internal static T Scalar(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); return dbCmd.Scalar(sql); } - internal static T ScalarFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) - { - return dbCmd.Scalar(sql.SqlFmt(sqlParams)); - } - internal static T Scalar(this IDataReader reader, IOrmLiteDialectProvider dialectProvider) { while (reader.Read()) { - object oValue = reader.GetValue(0); - return ToScalar(dialectProvider, oValue); + return ToScalar(dialectProvider, reader); } return default(T); } - internal static T ToScalar(IOrmLiteDialectProvider dialectProvider, object oValue) + internal static T ToScalar(IOrmLiteDialectProvider dialectProvider, IDataReader reader, int columnIndex = 0) { - if (oValue == DBNull.Value) return default(T); + var nullableType = Nullable.GetUnderlyingType(typeof(T)); + if (nullableType != null) + { + object oValue = reader.GetValue(columnIndex); + if (oValue == DBNull.Value) + return default(T); + } - var typeCode = typeof(T).GetUnderlyingTypeCode(); - switch (typeCode) + var underlyingType = nullableType ?? typeof(T); + if (underlyingType == typeof(object)) + return (T)reader.GetValue(0); + + var converter = dialectProvider.GetConverterBestMatch(underlyingType); + if (converter != null) { - case TypeCode.DateTime: - return (T) (object) DateTime.Parse(oValue.ToString(), CultureInfo.CurrentCulture); - case TypeCode.Decimal: - return (T) (object) Decimal.Parse(oValue.ToString(), CultureInfo.CurrentCulture); - case TypeCode.Single: - return (T) (object) System.Single.Parse(oValue.ToString(), CultureInfo.CurrentCulture); - case TypeCode.Double: - return (T) (object) Double.Parse(oValue.ToString(), CultureInfo.CurrentCulture); + object oValue = converter.GetValue(reader, columnIndex, null); + if (oValue == null) + return default(T); + + var convertedValue = converter.FromDbValue(underlyingType, oValue); + return convertedValue == null ? default(T) : (T)convertedValue; } - object o = dialectProvider.ConvertDbValue(oValue, typeof(T)); - return o == null ? default(T) : (T) o; + return (T)reader.GetValue(0); } internal static long LastInsertId(this IDbCommand dbCmd) { if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetLastInsertId(dbCmd); - } return dbCmd.GetDialectProvider().GetLastInsertId(dbCmd); } internal static List Column(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); return dbCmd.Column(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql)); } - internal static List ColumnFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) - { - return dbCmd.Column(sql.SqlFmt(sqlParams)); - } - internal static List Column(this IDataReader reader, IOrmLiteDialectProvider dialectProvider) { var columValues = new List(); while (reader.Read()) { - var value = dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(T)); + var value = dialectProvider.FromDbValue(reader, 0, typeof(T)); if (value == DBNull.Value) value = default(T); @@ -666,16 +784,14 @@ internal static List Column(this IDataReader reader, IOrmLiteDialectProvid return columValues; } - internal static HashSet ColumnDistinct(this IDbCommand dbCmd, string sql, object anonType = null) + internal static HashSet ColumnDistinct(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) { - if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false); - - return dbCmd.ColumnDistinct(sql); + return dbCmd.SetParameters(sqlParams).ColumnDistinct(sql); } - internal static HashSet ColumnDistinctFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) + internal static HashSet ColumnDistinct(this IDbCommand dbCmd, string sql, object anonType = null) { - return dbCmd.ColumnDistinct(sql.SqlFmt(sqlParams)); + return dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql).ColumnDistinct(sql); } internal static HashSet ColumnDistinct(this IDataReader reader, IOrmLiteDialectProvider dialectProvider) @@ -683,7 +799,7 @@ internal static HashSet ColumnDistinct(this IDataReader reader, IOrmLiteDi var columValues = new HashSet(); while (reader.Read()) { - var value = dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(T)); + var value = dialectProvider.FromDbValue(reader, 0, typeof(T)); if (value == DBNull.Value) value = default(T); @@ -694,14 +810,7 @@ internal static HashSet ColumnDistinct(this IDataReader reader, IOrmLiteDi internal static Dictionary> Lookup(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) SetParameters(dbCmd, anonType, (bool)false); - - return dbCmd.Lookup(sql); - } - - internal static Dictionary> LookupFmt(this IDbCommand dbCmd, string sql, params object[] sqlParams) - { - return dbCmd.Lookup(sql.SqlFmt(sqlParams)); + return dbCmd.SetParameters(anonType.ToObjectDictionary(), false, sql:ref sql).Lookup(sql); } internal static Dictionary> Lookup(this IDataReader reader, IOrmLiteDialectProvider dialectProvider) @@ -710,11 +819,10 @@ internal static Dictionary> Lookup(this IDataReader reader, IOr while (reader.Read()) { - var key = (K)dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(K)); - var value = (V)dialectProvider.ConvertDbValue(reader.GetValue(1), typeof(V)); + var key = (K)dialectProvider.FromDbValue(reader, 0, typeof(K)); + var value = (V)dialectProvider.FromDbValue(reader, 1, typeof(V)); - List values; - if (!lookup.TryGetValue(key, out values)) + if (!lookup.TryGetValue(key, out var values)) { values = new List(); lookup[key] = values; @@ -727,24 +835,19 @@ internal static Dictionary> Lookup(this IDataReader reader, IOr internal static Dictionary Dictionary(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) SetParameters(dbCmd, anonType, excludeDefaults: false); + if (anonType != null) SetParameters(dbCmd, anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); return dbCmd.Dictionary(sql); } - internal static Dictionary DictionaryFmt(this IDbCommand dbCmd, string sqlFormat, params object[] sqlParams) - { - return dbCmd.Dictionary(sqlFormat.SqlFmt(sqlParams)); - } - internal static Dictionary Dictionary(this IDataReader reader, IOrmLiteDialectProvider dialectProvider) { var map = new Dictionary(); while (reader.Read()) { - var key = (K)dialectProvider.ConvertDbValue(reader.GetValue(0), typeof(K)); - var value = (V)dialectProvider.ConvertDbValue(reader.GetValue(1), typeof(V)); + var key = (K)dialectProvider.FromDbValue(reader, 0, typeof(K)); + var value = (V)dialectProvider.FromDbValue(reader, 1, typeof(V)); map.Add(key, value); } @@ -752,12 +855,34 @@ internal static Dictionary Dictionary(this IDataReader reader, IOrmL return map; } + internal static List> KeyValuePairs(this IDbCommand dbCmd, string sql, object anonType = null) + { + if (anonType != null) SetParameters(dbCmd, anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); + + return dbCmd.KeyValuePairs(sql); + } + + internal static List> KeyValuePairs(this IDataReader reader, IOrmLiteDialectProvider dialectProvider) + { + var to = new List>(); + + while (reader.Read()) + { + var key = (K)dialectProvider.FromDbValue(reader, 0, typeof(K)); + var value = (V)dialectProvider.FromDbValue(reader, 1, typeof(V)); + + to.Add(new KeyValuePair(key, value)); + } + + return to; + } + internal static bool Exists(this IDbCommand dbCmd, object anonType) { - if (anonType != null) SetParameters(dbCmd, anonType, excludeDefaults: true); + string sql = null; + if (anonType != null) SetParameters(dbCmd, anonType.ToObjectDictionary(), excludeDefaults: true, sql:ref sql); - var sql = dbCmd.GetDialectProvider().ToExecuteProcedureStatement(anonType) - ?? GetFilterSql(dbCmd); + sql = GetFilterSql(dbCmd); var result = dbCmd.Scalar(sql); return result != null; @@ -765,19 +890,12 @@ internal static bool Exists(this IDbCommand dbCmd, object anonType) internal static bool Exists(this IDbCommand dbCmd, string sql, object anonType = null) { - if (anonType != null) SetParameters(dbCmd, anonType, (bool)false); + if (anonType != null) SetParameters(dbCmd, anonType.ToObjectDictionary(), (bool)false, sql:ref sql); var result = dbCmd.Scalar(dbCmd.GetDialectProvider().ToSelectStatement(typeof(T), sql)); return result != null; } - internal static bool ExistsFmt(this IDbCommand dbCmd, string sqlFilter, params object[] filterParams) - { - var fromTableType = typeof(T); - var result = dbCmd.Scalar(dbCmd.GetDialectProvider().ToSelectStatement(fromTableType, sqlFilter, filterParams)); - return result != null; - } - // procedures ... internal static List SqlProcedure(this IDbCommand dbCommand, object fromObjWithProperties) { @@ -803,37 +921,47 @@ public static long LongScalar(this IDbCommand dbCmd) return ToLong(result); } + internal static long ToLong(int result) => result; + internal static long ToLong(object result) { if (result is DBNull) return default(long); - if (result is int) return (int) result; - if (result is decimal) return Convert.ToInt64((decimal) result); - if (result is ulong) return (long) Convert.ToUInt64(result); - return (long) result; + if (result is int) return (int)result; + if (result is decimal) return Convert.ToInt64((decimal)result); + if (result is ulong) return (long)Convert.ToUInt64(result); + return (long)result; } - internal static T LoadSingleById(this IDbCommand dbCmd, object value) + internal static T LoadSingleById(this IDbCommand dbCmd, object value, string[] include = null) { var row = dbCmd.SingleById(value); if (row == null) return default(T); - dbCmd.LoadReferences(row); + dbCmd.LoadReferences(row, include); return row; } - public static void LoadReferences(this IDbCommand dbCmd, T instance) + public static void LoadReferences(this IDbCommand dbCmd, T instance, IEnumerable include = null) { var loadRef = new LoadReferencesSync(dbCmd, instance); + var fieldDefs = loadRef.FieldDefs; + + var includeSet = include != null + ? new HashSet(include, StringComparer.OrdinalIgnoreCase) + : null; - foreach (var fieldDef in loadRef.FieldDefs) + foreach (var fieldDef in fieldDefs) { + if (includeSet != null && !includeSet.Contains(fieldDef.Name)) + continue; + dbCmd.Parameters.Clear(); var listInterface = fieldDef.FieldType.GetTypeWithGenericInterfaceOf(typeof(IList<>)); if (listInterface != null) { - loadRef.SetRefFieldList(fieldDef, listInterface.GenericTypeArguments()[0]); + loadRef.SetRefFieldList(fieldDef, listInterface.GetGenericArguments()[0]); } else { @@ -842,16 +970,24 @@ public static void LoadReferences(this IDbCommand dbCmd, T instance) } } - internal static List LoadListWithReferences(this IDbCommand dbCmd, SqlExpression expr = null) + internal static List LoadListWithReferences(this IDbCommand dbCmd, SqlExpression expr = null, IEnumerable include = null) { var loadList = new LoadListSync(dbCmd, expr); + var fieldDefs = loadList.FieldDefs; + + var includeSet = include != null + ? new HashSet(include, StringComparer.OrdinalIgnoreCase) + : null; - foreach (var fieldDef in loadList.FieldDefs) + foreach (var fieldDef in fieldDefs) { + if (includeSet != null && !includeSet.Contains(fieldDef.Name)) + continue; + var listInterface = fieldDef.FieldType.GetTypeWithGenericInterfaceOf(typeof(IList<>)); if (listInterface != null) { - loadList.SetRefFieldList(fieldDef, listInterface.GenericTypeArguments()[0]); + loadList.SetRefFieldList(fieldDef, listInterface.GetGenericArguments()[0]); } else { @@ -866,14 +1002,14 @@ public static FieldDefinition GetRefFieldDef(this ModelDefinition modelDef, Mode { var refField = GetRefFieldDefIfExists(modelDef, refModelDef); if (refField == null) - throw new ArgumentException("Cant find '{0}' Property on Type '{1}'".Fmt(modelDef.ModelName + "Id", refType.Name)); + throw new ArgumentException($"Cant find '{modelDef.ModelName + "Id"}' Property on Type '{refType.Name}'"); return refField; } public static FieldDefinition GetRefFieldDefIfExists(this ModelDefinition modelDef, ModelDefinition refModelDef) { - var refField = - refModelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == modelDef.ModelType + var refField = + refModelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == modelDef.ModelType && modelDef.IsRefField(x)) ?? refModelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == modelDef.ModelType) ?? refModelDef.FieldDefinitions.FirstOrDefault(modelDef.IsRefField); @@ -896,9 +1032,14 @@ public static IDbDataParameter AddParam(this IDbCommand dbCmd, string name, object value = null, ParameterDirection direction = ParameterDirection.Input, - DbType? dbType = null) - { - var p = dbCmd.CreateParam(name, value, direction, dbType); + DbType? dbType = null, + byte? precision = null, + byte? scale = null, + int? size=null, + Action paramFilter = null) + { + var p = dbCmd.CreateParam(name, value, direction, dbType, precision, scale, size); + paramFilter?.Invoke(p); dbCmd.Parameters.Add(p); return p; } @@ -907,22 +1048,44 @@ public static IDbDataParameter CreateParam(this IDbCommand dbCmd, string name, object value = null, ParameterDirection direction = ParameterDirection.Input, - DbType? dbType=null) + DbType? dbType = null, + byte? precision=null, + byte? scale=null, + int? size=null) { var p = dbCmd.CreateParameter(); var dialectProvider = dbCmd.GetDialectProvider(); p.ParameterName = dialectProvider.GetParam(name); p.Direction = direction; + + if (p.DbType == DbType.String) + { + p.Size = dialectProvider.GetStringConverter().StringLength; + if (value is string strValue && strValue.Length > p.Size) + p.Size = strValue.Length; + } + if (value != null) { p.Value = value; - p.DbType = dialectProvider.GetColumnDbType(value.GetType()); + dialectProvider.InitDbParam(p, value.GetType()); + } + else + { + p.Value = DBNull.Value; } + if (dbType != null) p.DbType = dbType.Value; - if (p.DbType == DbType.String) - p.Size = dialectProvider.DefaultStringLength; + if (precision != null) + p.Precision = precision.Value; + + if (scale != null) + p.Scale = scale.Value; + + if (size != null) + p.Size = size.Value; return p; } @@ -931,9 +1094,9 @@ internal static IDbCommand SqlProc(this IDbCommand dbCmd, string name, object in { dbCmd.CommandType = CommandType.StoredProcedure; dbCmd.CommandText = name; - dbCmd.CommandTimeout = OrmLiteConfig.CommandTimeout; - dbCmd.SetParameters(inParams, excludeDefaults); + string sql = null; + dbCmd.SetParameters(inParams.ToObjectDictionary(), excludeDefaults, sql:ref sql); return dbCmd; } diff --git a/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs b/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs index 911c34476..17da825d9 100644 --- a/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs +++ b/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs @@ -1,8 +1,13 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Threading; using System.Threading.Tasks; +using ServiceStack.Text; namespace ServiceStack.OrmLite { @@ -43,16 +48,6 @@ public static Task Exec(this IDbConnection dbConn, Func - /// Create a new SqlExpression builder allowing typed LINQ-like queries. - /// - [Obsolete("Use From")] - public static SqlExpression SqlExpression(this IDbConnection dbConn) - { - return dbConn.GetExecFilter().SqlExpression(dbConn); - } - /// /// Creates a new SqlExpression builder allowing typed LINQ-like queries. /// Alias for SqlExpression. @@ -62,6 +57,13 @@ public static SqlExpression From(this IDbConnection dbConn) return dbConn.GetExecFilter().SqlExpression(dbConn); } + public static SqlExpression From(this IDbConnection dbConn, Action> options) + { + var q = dbConn.GetExecFilter().SqlExpression(dbConn); + options(q); + return q; + } + public static SqlExpression From(this IDbConnection dbConn, Expression> joinExpr=null) { var sql = dbConn.GetExecFilter().SqlExpression(dbConn); @@ -78,6 +80,111 @@ public static SqlExpression From(this IDbConnection dbConn, string fromExp expr.From(fromExpression); return expr; } + + public static SqlExpression From(this IDbConnection dbConn, TableOptions tableOptions) + { + var expr = dbConn.GetExecFilter().SqlExpression(dbConn); + if (!string.IsNullOrEmpty(tableOptions.Expression)) + expr.From(tableOptions.Expression); + if (!string.IsNullOrEmpty(tableOptions.Alias)) + expr.SetTableAlias(tableOptions.Alias); + return expr; + } + + public static SqlExpression TagWith(this SqlExpression expression,string tag) + { + expression.AddTag(tag); + return expression; + } + + public static SqlExpression TagWithCallSite(this SqlExpression expression, + [CallerFilePath] string filePath = null, + [CallerLineNumber] int lineNumber = 0) + { + expression.AddTag($"File: {filePath}:{lineNumber.ToString()}"); + return expression; + } + + public static SqlExpression From(this IDbConnection dbConn, TableOptions tableOptions, + Action> options) + { + var q = dbConn.From(tableOptions); + options(q); + return q; + } + + [Obsolete("Use TableAlias")] + public static JoinFormatDelegate JoinAlias(this IDbConnection db, string alias) => OrmLiteUtils.JoinAlias(alias); + + public static TableOptions TableAlias(this IDbConnection db, string alias) => new TableOptions { Alias = alias }; + + public static string GetTableName(this IDbConnection db) => db.GetDialectProvider().GetTableName(ModelDefinition.Definition); + + public static List GetTableNames(this IDbConnection db) => GetTableNames(db, null); + public static List GetTableNames(this IDbConnection db, string schema) => db.Column(db.GetDialectProvider().ToTableNamesStatement(schema)); + + public static Task> GetTableNamesAsync(this IDbConnection db) => GetTableNamesAsync(db, null); + public static Task> GetTableNamesAsync(this IDbConnection db, string schema) => db.ColumnAsync(db.GetDialectProvider().ToTableNamesStatement(schema)); + + public static List> GetTableNamesWithRowCounts(this IDbConnection db, bool live=false, string schema=null) + { + List> GetResults() + { + var sql = db.GetDialectProvider().ToTableNamesWithRowCountsStatement(live, schema); + if (sql != null) + return db.KeyValuePairs(sql); + + sql = CreateTableRowCountUnionSql(db, schema); + return db.KeyValuePairs(sql); + } + + var results = GetResults(); + results.Sort((x,y) => y.Value.CompareTo(x.Value)); //sort desc + return results; + } + + public static async Task>> GetTableNamesWithRowCountsAsync(this IDbConnection db, bool live = false, string schema = null) + { + Task>> GetResultsAsync() + { + var sql = db.GetDialectProvider().ToTableNamesWithRowCountsStatement(live, schema); + if (sql != null) + return db.KeyValuePairsAsync(sql); + + sql = CreateTableRowCountUnionSql(db, schema); + return db.KeyValuePairsAsync(sql); + } + + var results = await GetResultsAsync().ConfigAwait(); + results.Sort((x,y) => y.Value.CompareTo(x.Value)); //sort desc + return results; + } + + private static string CreateTableRowCountUnionSql(IDbConnection db, string schema) + { + var sb = StringBuilderCache.Allocate(); + + var dialect = db.GetDialectProvider(); + + var tableNames = GetTableNames(db, schema); + var schemaName = dialect.NamingStrategy.GetSchemaName(schema); + foreach (var tableName in tableNames) + { + if (sb.Length > 0) + sb.Append(" UNION "); + + // retain *real* table names and skip using naming strategy + sb.AppendLine($"SELECT {OrmLiteUtils.QuotedLiteral(tableName)}, COUNT(*) FROM {dialect.GetQuotedTableName(tableName, schemaName, useStrategy:false)}"); + } + + var sql = StringBuilderCache.ReturnAndFree(sb); + return sql; + } + + public static string GetQuotedTableName(this IDbConnection db) + { + return db.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition); + } /// /// Open a Transaction in OrmLite @@ -87,6 +194,16 @@ public static IDbTransaction OpenTransaction(this IDbConnection dbConn) return new OrmLiteTransaction(dbConn, dbConn.BeginTransaction()); } + /// + /// Returns a new transaction if not yet exists, otherwise null + /// + public static IDbTransaction OpenTransactionIfNotExists(this IDbConnection dbConn) + { + return !dbConn.InTransaction() + ? new OrmLiteTransaction(dbConn, dbConn.BeginTransaction()) + : null; + } + /// /// Open a Transaction in OrmLite /// @@ -95,6 +212,16 @@ public static IDbTransaction OpenTransaction(this IDbConnection dbConn, Isolatio return new OrmLiteTransaction(dbConn, dbConn.BeginTransaction(isolationLevel)); } + /// + /// Returns a new transaction if not yet exists, otherwise null + /// + public static IDbTransaction OpenTransactionIfNotExists(this IDbConnection dbConn, IsolationLevel isolationLevel) + { + return !dbConn.InTransaction() + ? new OrmLiteTransaction(dbConn, dbConn.BeginTransaction(isolationLevel)) + : null; + } + /// /// Create a managed OrmLite IDbCommand /// @@ -112,15 +239,6 @@ public static List Select(this IDbConnection dbConn, Expression dbCmd.Select(predicate)); } - /// - /// Returns results from using an SqlExpression lambda. E.g: - /// db.Select<Person>(q => q.Where(x => x.Age > 40)) - /// - public static List Select(this IDbConnection dbConn, Func, SqlExpression> expression) - { - return dbConn.Exec(dbCmd => dbCmd.Select(expression)); - } - /// /// Returns results from using an SqlExpression lambda. E.g: /// db.Select(db.From<Person>().Where(x => x.Age > 40)) @@ -130,31 +248,38 @@ public static List Select(this IDbConnection dbConn, SqlExpression expr return dbConn.Exec(dbCmd => dbCmd.Select(expression)); } - /// - /// Project results from a number of joined tables into a different model - /// - public static List Select(this IDbConnection dbConn, SqlExpression expression) - { - return dbConn.Exec(dbCmd => dbCmd.Select(expression)); - } - - /// - /// Project results from a number of joined tables into a different model - /// - public static List Select(this IDbConnection dbConn, Func, SqlExpression> expression) - { - return dbConn.Exec(dbCmd => dbCmd.Select(expression)); - } - /// /// Returns results from using an SqlExpression lambda. E.g: /// db.Select(db.From<Person>().Where(x => x.Age > 40)) /// public static List Select(this IDbConnection dbConn, ISqlExpression expression, object anonType = null) { - return dbConn.Exec(dbCmd => dbCmd.SqlList(expression.SelectInto(), anonType)); + if (anonType != null) + return dbConn.Exec(dbCmd => dbCmd.SqlList(expression.SelectInto(QueryType.Select), anonType)); + + if (expression.Params != null && expression.Params.Any()) + return dbConn.Exec(dbCmd => dbCmd.SqlList(expression.SelectInto(QueryType.Select), expression.Params.ToDictionary(param => param.ParameterName, param => param.Value))); + + return dbConn.Exec(dbCmd => dbCmd.SqlList(expression.SelectInto(QueryType.Select), expression.Params)); } + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression)); + + + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression, tableSelects)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression, tableSelects)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression, tableSelects)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression, tableSelects)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression, tableSelects)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression, tableSelects)); + public static List> SelectMulti(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects) => dbConn.Exec(dbCmd => dbCmd.SelectMulti(expression, tableSelects)); + /// /// Returns a single result from using a LINQ Expression. E.g: /// db.Single<Person>(x => x.Age == 42) @@ -165,30 +290,30 @@ public static T Single(this IDbConnection dbConn, Expression> p } /// - /// Returns a single result from using an SqlExpression lambda. E.g: - /// db.Single<Person>(q => q.Where(x => x.Age == 42)) + /// Returns results from using an SqlExpression lambda. E.g: + /// db.Select<Person>(x => x.Age > 40) /// - public static T Single(this IDbConnection dbConn, Func, SqlExpression> expression) + public static T Single(this IDbConnection dbConn, SqlExpression expression) { return dbConn.Exec(dbCmd => dbCmd.Single(expression)); } /// /// Returns results from using an SqlExpression lambda. E.g: - /// db.Select<Person>(x => x.Age > 40) + /// db.Single(db.From<Person>().Where(x => x.Age > 40)) /// - public static T Single(this IDbConnection dbConn, SqlExpression expression) + public static T Single(this IDbConnection dbConn, ISqlExpression expression) { - return dbConn.Exec(dbCmd => dbCmd.Single(expression)); + return dbConn.Exec(dbCmd => dbCmd.Single(expression.SelectInto(QueryType.Single), expression.Params)); } /// /// Returns a scalar result from using an SqlExpression lambda. E.g: /// db.Scalar<Person, int>(x => Sql.Max(x.Age)) /// - public static TKey Scalar(this IDbConnection dbConn, Expression> field) + public static TKey Scalar(this IDbConnection dbConn, Expression> field) { - return dbConn.Exec(dbCmd => dbCmd.Scalar(field)); + return dbConn.Exec(dbCmd => dbCmd.Scalar(field)); } /// @@ -196,9 +321,9 @@ public static TKey Scalar(this IDbConnection dbConn, Expressiondb.Scalar<Person, int>(x => Sql.Max(x.Age), , x => x.Age < 50) /// public static TKey Scalar(this IDbConnection dbConn, - Expression> field, Expression> predicate) + Expression> field, Expression> predicate) { - return dbConn.Exec(dbCmd => dbCmd.Scalar(field, predicate)); + return dbConn.Exec(dbCmd => dbCmd.Scalar(field, predicate)); } /// @@ -210,15 +335,6 @@ public static long Count(this IDbConnection dbConn, Expression> return dbConn.Exec(dbCmd => dbCmd.Count(expression)); } - /// - /// Returns the count of rows that match the SqlExpression lambda, E.g: - /// db.Count<Person>(q => q.Where(x => x.Age < 50)) - /// - public static long Count(this IDbConnection dbConn, Func, SqlExpression> expression) - { - return dbConn.Exec(dbCmd => dbCmd.Count(expression)); - } - /// /// Returns the count of rows that match the supplied SqlExpression, E.g: /// db.Count(db.From<Person>().Where(x => x.Age < 50)) @@ -245,44 +361,110 @@ public static long RowCount(this IDbConnection dbConn, SqlExpression expre /// /// Return the number of rows returned by the supplied sql /// - public static long RowCount(this IDbConnection dbConn, string sql) + public static long RowCount(this IDbConnection dbConn, string sql, object anonType = null) + { + return dbConn.Exec(dbCmd => dbCmd.RowCount(sql, anonType)); + } + + /// + /// Return the number of rows returned by the supplied sql and db params + /// + public static long RowCount(this IDbConnection dbConn, string sql, IEnumerable sqlParams) { - return dbConn.Exec(dbCmd => dbCmd.RowCount(sql)); + return dbConn.Exec(dbCmd => dbCmd.RowCount(sql, sqlParams)); } /// /// Returns results with references from using a LINQ Expression. E.g: /// db.LoadSelect<Person>(x => x.Age > 40) /// - public static List LoadSelect(this IDbConnection dbConn, Expression> predicate) + public static List LoadSelect(this IDbConnection dbConn, Expression> predicate, string[] include = null) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelect(predicate)); + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(predicate, include)); } /// - /// Returns results with references from using an SqlExpression lambda. E.g: - /// db.LoadSelect<Person>(q => q.Where(x => x.Age > 40)) + /// Returns results with references from using a LINQ Expression. E.g: + /// db.LoadSelect<Person>(x => x.Age > 40, include: x => new { x.PrimaryAddress }) /// - public static List LoadSelect(this IDbConnection dbConn, Func, SqlExpression> expression) + public static List LoadSelect(this IDbConnection dbConn, Expression> predicate, Expression> include) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression)); + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(predicate, include.GetFieldNames())); } /// /// Returns results with references from using an SqlExpression lambda. E.g: /// db.LoadSelect(db.From<Person>().Where(x => x.Age > 40)) /// - public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression = null) + public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression = null, string[] include = null) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression)); + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include)); + } + + /// + /// Returns results with references from using an SqlExpression lambda. E.g: + /// db.LoadSelect(db.From<Person>().Where(x => x.Age > 40), include:q.OnlyFields) + /// + public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression, IEnumerable include) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include)); + } + + /// + /// Returns results with references from using an SqlExpression lambda. E.g: + /// db.LoadSelect(db.From<Person>().Where(x => x.Age > 40), include: x => new { x.PrimaryAddress }) + /// + public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression, Expression> include) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include.GetFieldNames())); } /// /// Project results with references from a number of joined tables into a different model /// - public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression) + public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression, string[] include = null) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression)); + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include)); } + + /// + /// Project results with references from a number of joined tables into a different model + /// + public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression, IEnumerable include) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include)); + } + + /// + /// Project results with references from a number of joined tables into a different model + /// + public static List LoadSelect(this IDbConnection dbConn, SqlExpression expression, Expression> include) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelect(expression, include.GetFieldNames())); + } + + /// + /// Return ADO.NET reader.GetSchemaTable() in a DataTable + /// + /// + /// + /// + public static DataTable GetSchemaTable(this IDbConnection dbConn, string sql) => dbConn.Exec(dbCmd => dbCmd.GetSchemaTable(sql)); + + /// + /// Get Table Column Schemas for specified table + /// + public static ColumnSchema[] GetTableColumns(this IDbConnection dbConn) => dbConn.Exec(dbCmd => dbCmd.GetTableColumns(typeof(T))); + /// + /// Get Table Column Schemas for specified table + /// + public static ColumnSchema[] GetTableColumns(this IDbConnection dbConn, Type type) => dbConn.Exec(dbCmd => dbCmd.GetTableColumns(type)); + /// + /// Get Table Column Schemas for result-set return from specified sql + /// + public static ColumnSchema[] GetTableColumns(this IDbConnection dbConn, string sql) => dbConn.Exec(dbCmd => dbCmd.GetTableColumns(sql)); + + public static void EnableForeignKeysCheck(this IDbConnection dbConn) => dbConn.Exec(dbConn.GetDialectProvider().EnableForeignKeysCheck); + public static void DisableForeignKeysCheck(this IDbConnection dbConn) => dbConn.Exec(dbConn.GetDialectProvider().DisableForeignKeysCheck); } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApiAsync.cs b/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApiAsync.cs index 877ca97b3..95316487b 100644 --- a/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApiAsync.cs +++ b/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApiAsync.cs @@ -1,5 +1,5 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; @@ -17,25 +17,16 @@ public static class OrmLiteReadExpressionsApiAsync /// Returns results from using a LINQ Expression. E.g: /// db.Select<Person>(x => x.Age > 40) /// - public static Task> SelectAsync(this IDbConnection dbConn, Expression> predicate, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, Expression> predicate, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectAsync(predicate, token)); } - /// - /// Returns results from using an SqlExpression lambda. E.g: - /// db.Select<Person>(q => q.Where(x => x.Age > 40)) - /// - public static Task> SelectAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default(CancellationToken)) - { - return dbConn.Exec(dbCmd => dbCmd.SelectAsync(expression, token)); - } - /// /// Returns results from using an SqlExpression lambda. E.g: /// db.Select(db.From<Person>().Where(x => x.Age > 40)) /// - public static Task> SelectAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectAsync(expression, token)); } @@ -43,62 +34,72 @@ public static class OrmLiteReadExpressionsApiAsync /// /// Project results from a number of joined tables into a different model /// - public static Task> SelectAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) - { - return dbConn.Exec(dbCmd => dbCmd.SelectAsync(expression, token)); - } - - /// - /// Project results from a number of joined tables into a different model - /// - public static Task> SelectAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default(CancellationToken)) + public static Task> SelectAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SelectAsync(expression, token)); } /// /// Returns results from using an SqlExpression lambda. E.g: - /// db.Select(db.From<Person>().Where(x => x.Age > 40)) + /// db.SelectAsync(db.From<Person>().Where(x => x.Age > 40)) /// - //public static Task> SelectAsync(this IDbConnection dbConn, ISqlExpression expression, object anonType, CancellationToken token) - //{ - // return dbConn.Exec(dbCmd => dbCmd.SqlList(expression.SelectInto(), anonType)); - //} + public static Task> SelectAsync(this IDbConnection dbConn, ISqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SqlListAsync(expression.SelectInto(QueryType.Select), expression.Params, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, token)); + + + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, tableSelects, token)); + + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, tableSelects, token)); + + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, tableSelects, token)); + + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, tableSelects, token)); + + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, tableSelects, token)); + + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, tableSelects, token)); + public static Task>> SelectMultiAsync(this IDbConnection dbConn, SqlExpression expression, string[] tableSelects, CancellationToken token = default) => dbConn.Exec(dbCmd => dbCmd.SelectMultiAsync(expression, tableSelects, token)); /// /// Returns a single result from using a LINQ Expression. E.g: /// db.Single<Person>(x => x.Age == 42) /// - public static Task SingleAsync(this IDbConnection dbConn, Expression> predicate, CancellationToken token = default(CancellationToken)) + public static Task SingleAsync(this IDbConnection dbConn, Expression> predicate, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SingleAsync(predicate, token)); } /// - /// Returns a single result from using an SqlExpression lambda. E.g: - /// db.Single<Person>(q => q.Where(x => x.Age == 42)) + /// Returns results from using an SqlExpression lambda. E.g: + /// db.SingleAsync<Person>(x => x.Age > 40) /// - public static Task SingleAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default(CancellationToken)) + public static Task SingleAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SingleAsync(expression, token)); } /// /// Returns results from using an SqlExpression lambda. E.g: - /// db.Select<Person>(x => x.Age > 40) + /// db.SingleAsync(db.From<Person>().Where(x => x.Age > 40)) /// - public static Task SingleAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) + public static Task SingleAsync(this IDbConnection dbConn, ISqlExpression expression, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.SingleAsync(expression, token)); + return dbConn.Exec(dbCmd => dbCmd.SingleAsync(expression.SelectInto(QueryType.Single), expression.Params, token)); } /// /// Returns a scalar result from using an SqlExpression lambda. E.g: /// db.Scalar<Person, int>(x => Sql.Max(x.Age)) /// - public static Task ScalarAsync(this IDbConnection dbConn, Expression> field, CancellationToken token = default(CancellationToken)) + public static Task ScalarAsync(this IDbConnection dbConn, Expression> field, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(field, token)); + return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(field, token)); } /// @@ -106,25 +107,16 @@ public static class OrmLiteReadExpressionsApiAsync /// db.Scalar<Person, int>(x => Sql.Max(x.Age), , x => x.Age < 50) /// public static Task ScalarAsync(this IDbConnection dbConn, - Expression> field, Expression> predicate, CancellationToken token = default(CancellationToken)) + Expression> field, Expression> predicate, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(field, predicate, token)); + return dbConn.Exec(dbCmd => dbCmd.ScalarAsync(field, predicate, token)); } /// /// Returns the count of rows that match the LINQ expression, E.g: /// db.Count<Person>(x => x.Age < 50) /// - public static Task CountAsync(this IDbConnection dbConn, Expression> expression, CancellationToken token = default(CancellationToken)) - { - return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token)); - } - - /// - /// Returns the count of rows that match the SqlExpression lambda, E.g: - /// db.Count<Person>(q => q.Where(x => x.Age < 50)) - /// - public static Task CountAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default(CancellationToken)) + public static Task CountAsync(this IDbConnection dbConn, Expression> expression, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token)); } @@ -133,12 +125,12 @@ public static Task ScalarAsync(this IDbConnection dbConn, /// Returns the count of rows that match the supplied SqlExpression, E.g: /// db.Count(db.From<Person>().Where(x => x.Age < 50)) /// - public static Task CountAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) + public static Task CountAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token)); } - public static Task CountAsync(this IDbConnection dbConn, CancellationToken token = default(CancellationToken)) + public static Task CountAsync(this IDbConnection dbConn, CancellationToken token = default) { var expression = dbConn.GetDialectProvider().SqlExpression(); return dbConn.Exec(dbCmd => dbCmd.CountAsync(expression, token)); @@ -147,7 +139,7 @@ public static Task ScalarAsync(this IDbConnection dbConn, /// /// Return the number of rows returned by the supplied expression /// - public static Task RowCountAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) + public static Task RowCountAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.RowCountAsync(expression, token)); } @@ -155,45 +147,100 @@ public static Task ScalarAsync(this IDbConnection dbConn, /// /// Return the number of rows returned by the supplied sql /// - public static Task RowCountAsync(this IDbConnection dbConn, string sql, CancellationToken token = default(CancellationToken)) + public static Task RowCountAsync(this IDbConnection dbConn, string sql, object anonType = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.RowCountAsync(sql, token)); + return dbConn.Exec(dbCmd => dbCmd.RowCountAsync(sql, anonType, token)); } /// /// Returns results with references from using a LINQ Expression. E.g: /// db.LoadSelectAsync<Person>(x => x.Age > 40) /// - public static Task> LoadSelectAsync(this IDbConnection dbConn, Expression> predicate, CancellationToken token = default(CancellationToken)) + public static Task> LoadSelectAsync(this IDbConnection dbConn, Expression> predicate, string[] include = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(predicate)); + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(predicate, include, token)); } /// - /// Returns results with references from using an SqlExpression lambda. E.g: - /// db.LoadSelectAsync<Person>(q => q.Where(x => x.Age > 40)) + /// Returns results with references from using a LINQ Expression. E.g: + /// db.LoadSelectAsync<Person>(x => x.Age > 40, include: x => new { x.PrimaryAddress }) /// - public static Task> LoadSelectAsync(this IDbConnection dbConn, Func, SqlExpression> expression, CancellationToken token = default(CancellationToken)) + public static Task> LoadSelectAsync(this IDbConnection dbConn, Expression> predicate, Expression> include) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression)); + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(predicate, include.GetFieldNames())); } /// /// Returns results with references from using an SqlExpression lambda. E.g: /// db.LoadSelectAsync(db.From<Person>().Where(x => x.Age > 40)) /// - public static Task> LoadSelectAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) + public static Task> LoadSelectAsync(this IDbConnection dbConn, SqlExpression expression, string[] include = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression, include, token)); + } + + /// + /// Returns results with references from using an SqlExpression lambda. E.g: + /// db.LoadSelectAsync(db.From<Person>().Where(x => x.Age > 40), include:q.OnlyFields) + /// + public static Task> LoadSelectAsync(this IDbConnection dbConn, SqlExpression expression, IEnumerable include, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression, include, token)); + } + + /// + /// Project results with references from a number of joined tables into a different model + /// + public static Task> LoadSelectAsync(this IDbConnection dbConn, SqlExpression expression, string[] include = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression, include, token)); + } + + /// + /// Project results with references from a number of joined tables into a different model + /// + public static Task> LoadSelectAsync(this IDbConnection dbConn, SqlExpression expression, IEnumerable include, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression)); + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression, include, token)); } /// /// Project results with references from a number of joined tables into a different model /// - public static Task> LoadSelectAsync(this IDbConnection dbConn, SqlExpression expression, CancellationToken token = default(CancellationToken)) + public static Task> LoadSelectAsync(this IDbConnection dbConn, SqlExpression expression, Expression> include) { - return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression)); - } + return dbConn.Exec(dbCmd => dbCmd.LoadSelectAsync(expression, include.GetFieldNames())); + } + + /// + /// Return ADO.NET reader.GetSchemaTable() in a DataTable + /// + /// + /// + /// + public static Task GetSchemaTableAsync(this IDbConnection dbConn, string sql, CancellationToken token=default) => + dbConn.Exec(dbCmd => dbCmd.GetSchemaTableAsync(sql, token)); + + /// + /// Get Table Column Schemas for specified table + /// + public static Task GetTableColumnsAsync(this IDbConnection dbConn, CancellationToken token=default) => + dbConn.Exec(dbCmd => dbCmd.GetTableColumnsAsync(typeof(T), token)); + /// + /// Get Table Column Schemas for specified table + /// + public static Task GetTableColumnsAsync(this IDbConnection dbConn, Type type, CancellationToken token=default) => + dbConn.Exec(dbCmd => dbCmd.GetTableColumnsAsync(type, token)); + /// + /// Get Table Column Schemas for result-set return from specified sql + /// + public static Task GetTableColumnsAsync(this IDbConnection dbConn, string sql, CancellationToken token=default) => + dbConn.Exec(dbCmd => dbCmd.GetTableColumnsAsync(sql, token)); + + public static Task EnableForeignKeysCheckAsync(this IDbConnection dbConn, CancellationToken token=default) => + dbConn.Exec(dbCmd => dbConn.GetDialectProvider().EnableForeignKeysCheckAsync(dbCmd, token)); + public static Task DisableForeignKeysCheckAsync(this IDbConnection dbConn, CancellationToken token=default) => + dbConn.Exec(dbCmd => dbConn.GetDialectProvider().DisableForeignKeysCheckAsync(dbCmd, token)); } } diff --git a/src/ServiceStack.OrmLite/OrmLiteResultsFilter.cs b/src/ServiceStack.OrmLite/OrmLiteResultsFilter.cs index e551a09de..9eb7a996a 100644 --- a/src/ServiceStack.OrmLite/OrmLiteResultsFilter.cs +++ b/src/ServiceStack.OrmLite/OrmLiteResultsFilter.cs @@ -1,4 +1,4 @@ -//Copyright (c) Service Stack LLC. All Rights Reserved. +//Copyright (c) ServiceStack, Inc. All Rights Reserved. //License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt @@ -33,6 +33,8 @@ public interface IOrmLiteResultsFilter HashSet GetColumnDistinct(IDbCommand dbCmd); Dictionary GetDictionary(IDbCommand dbCmd); + + List> GetKeyValuePairs(IDbCommand dbCmd); Dictionary> GetLookup(IDbCommand dbCmd); @@ -68,6 +70,8 @@ public class OrmLiteResultsFilter : IOrmLiteResultsFilter, IDisposable public Func LastInsertIdFn { get; set; } public Action SqlFilter { get; set; } + public Action SqlCommandFilter { get; set; } + public bool PrintSql { get; set; } private readonly IOrmLiteResultsFilter previousFilter; @@ -82,10 +86,9 @@ public OrmLiteResultsFilter(IEnumerable results = null) private void Filter(IDbCommand dbCmd) { - if (SqlFilter != null) - { - SqlFilter(dbCmd.CommandText); - } + SqlFilter?.Invoke(dbCmd.CommandText); + + SqlCommandFilter?.Invoke(dbCmd); if (PrintSql) { @@ -140,12 +143,12 @@ private object GetScalarResult(IDbCommand dbCmd) private long GetLongScalarResult(IDbCommand dbCmd) { - return LongScalarResultFn != null ? LongScalarResultFn(dbCmd) : LongScalarResult; + return LongScalarResultFn?.Invoke(dbCmd) ?? LongScalarResult; } public long GetLastInsertId(IDbCommand dbCmd) { - return LastInsertIdFn != null ? LastInsertIdFn(dbCmd) : LastInsertId; + return LastInsertIdFn?.Invoke(dbCmd) ?? LastInsertId; } public List GetList(IDbCommand dbCmd) @@ -157,8 +160,8 @@ public List GetList(IDbCommand dbCmd) public IList GetRefList(IDbCommand dbCmd, Type refType) { Filter(dbCmd); - var list = (IList)typeof(List<>).MakeGenericType(refType).CreateInstance(); - foreach (object result in GetRefResults(dbCmd, refType)) + var list = (IList)typeof(List<>).GetCachedGenericType(refType).CreateInstance(); + foreach (object result in GetRefResults(dbCmd, refType).Safe()) { list.Add(result); } @@ -184,7 +187,7 @@ public object GetRefSingle(IDbCommand dbCmd, Type refType) if (RefSingleResult != null || RefSingleResultFn != null) return GetRefSingleResult(dbCmd, refType); - foreach (var result in GetRefResults(dbCmd, refType)) + foreach (var result in GetRefResults(dbCmd, refType).Safe()) { return result; } @@ -245,14 +248,14 @@ public object GetScalar(IDbCommand dbCmd) public List GetColumn(IDbCommand dbCmd) { Filter(dbCmd); - return (from object result in (GetColumnResults(dbCmd) ?? new T[0]) select (T)result).ToList(); + return (from object result in GetColumnResults(dbCmd).Safe() select (T)result).ToList(); } public HashSet GetColumnDistinct(IDbCommand dbCmd) { Filter(dbCmd); var results = GetColumnDistinctResults(dbCmd) ?? GetColumnResults(dbCmd); - return (from object result in results select (T)result).ToHashSet(); + return (from object result in results select (T)result).ToSet(); } public Dictionary GetDictionary(IDbCommand dbCmd) @@ -271,6 +274,8 @@ public Dictionary GetDictionary(IDbCommand dbCmd) return to; } + public List> GetKeyValuePairs(IDbCommand dbCmd) => GetDictionary(dbCmd).ToList(); + public Dictionary> GetLookup(IDbCommand dbCmd) { Filter(dbCmd); @@ -283,8 +288,7 @@ public Dictionary> GetLookup(IDbCommand dbCmd) { var key = (K)entry.Key; - List list; - if (!to.TryGetValue(key, out list)) + if (!to.TryGetValue(key, out var list)) { to[key] = list = new List(); } @@ -298,11 +302,8 @@ public Dictionary> GetLookup(IDbCommand dbCmd) public int ExecuteSql(IDbCommand dbCmd) { Filter(dbCmd); - if (ExecuteSqlFn != null) - { - return ExecuteSqlFn(dbCmd); - } - return ExecuteSqlResult; + return ExecuteSqlFn?.Invoke(dbCmd) + ?? ExecuteSqlResult; } public void Dispose() @@ -315,15 +316,44 @@ public class CaptureSqlFilter : OrmLiteResultsFilter { public CaptureSqlFilter() { - SqlFilter = CaptureSql; - SqlStatements = new List(); + SqlCommandFilter = CaptureSqlCommand; + SqlCommandHistory = new List(); } - private void CaptureSql(string sql) + private void CaptureSqlCommand(IDbCommand command) + { + SqlCommandHistory.Add(new SqlCommandDetails(command)); + } + + public List SqlCommandHistory { get; set; } + + public List SqlStatements { - SqlStatements.Add(sql); + get { return SqlCommandHistory.Map(x => x.Sql); } + } + } + + public class SqlCommandDetails + { + public SqlCommandDetails(IDbCommand command) + { + if (command == null) + return; + + Sql = command.CommandText; + if (command.Parameters.Count <= 0) + return; + + Parameters = new Dictionary(); + + foreach (IDataParameter parameter in command.Parameters) + { + if (!Parameters.ContainsKey(parameter.ParameterName)) + Parameters.Add(parameter.ParameterName, parameter.Value); + } } - public List SqlStatements { get; set; } + public string Sql { get; set; } + public Dictionary Parameters { get; set; } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteResultsFilterExtensions.cs b/src/ServiceStack.OrmLite/OrmLiteResultsFilterExtensions.cs index e08de3151..af6a548c6 100644 --- a/src/ServiceStack.OrmLite/OrmLiteResultsFilterExtensions.cs +++ b/src/ServiceStack.OrmLite/OrmLiteResultsFilterExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Service Stack LLC. All Rights Reserved. +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt @@ -6,47 +6,77 @@ using System.Collections; using System.Collections.Generic; using System.Data; +using ServiceStack.Logging; namespace ServiceStack.OrmLite { public static class OrmLiteResultsFilterExtensions { - internal static int ExecNonQuery(this IDbCommand dbCmd, string sql, object anonType = null) + internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteResultsFilterExtensions)); + + public static int ExecNonQuery(this IDbCommand dbCmd, string sql, object anonType = null) { if (anonType != null) - dbCmd.SetParameters(anonType, (bool)false); + dbCmd.SetParameters(anonType.ToObjectDictionary(), (bool)false, sql:ref sql); dbCmd.CommandText = sql; + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd); - } return dbCmd.ExecuteNonQuery(); } - internal static int ExecNonQuery(this IDbCommand dbCmd, string sql, IDictionary dict) + public static int ExecNonQuery(this IDbCommand dbCmd, string sql, Dictionary dict) { + if (dict != null) - dbCmd.SetParameters(dict, (bool)false); + dbCmd.SetParameters(dict, (bool)false, sql:ref sql); dbCmd.CommandText = sql; + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd); - } return dbCmd.ExecuteNonQuery(); } - internal static int ExecNonQuery(this IDbCommand dbCmd) + public static int ExecNonQuery(this IDbCommand dbCmd) { + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd); - } + + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + return dbCmd.ExecuteNonQuery(); + } + + public static int ExecNonQuery(this IDbCommand dbCmd, string sql, Action dbCmdFilter) + { + dbCmdFilter?.Invoke(dbCmd); + + dbCmd.CommandText = sql; + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd); + + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); return dbCmd.ExecuteNonQuery(); } @@ -65,12 +95,10 @@ public static List ConvertToList(this IDbCommand dbCmd, string sql = null) : OrmLiteConfig.ResultsFilter.GetList(dbCmd); } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return isScalar - ? reader.Column(dbCmd.GetDialectProvider()) - : reader.ConvertToList(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return isScalar + ? reader.Column(dbCmd.GetDialectProvider()) + : reader.ConvertToList(dbCmd.GetDialectProvider()); } public static IList ConvertToList(this IDbCommand dbCmd, Type refType, string sql = null) @@ -79,30 +107,40 @@ public static IList ConvertToList(this IDbCommand dbCmd, Type refType, string sq dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetRefList(dbCmd, refType); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.ConvertToList(dbCmd.GetDialectProvider(), refType); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.ConvertToList(dbCmd.GetDialectProvider(), refType); + } + + public static IDbDataParameter PopulateWith(this IDbDataParameter to, IDbDataParameter from) + { + to.ParameterName = from.ParameterName; + to.DbType = from.DbType; + to.Value = from.Value; + + if (from.Precision != default(byte)) + to.Precision = from.Precision; + if (from.Scale != default(byte)) + to.Scale = from.Scale; + if (from.Size != default(int)) + to.Size = from.Size; + + return to; } - internal static List ExprConvertToList(this IDbCommand dbCmd, string sql = null) + internal static List ExprConvertToList(this IDbCommand dbCmd, string sql = null, IEnumerable sqlParams = null, HashSet onlyFields=null) { if (sql != null) dbCmd.CommandText = sql; + dbCmd.SetParameters(sqlParams); + if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetList(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.ConvertToList(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.ConvertToList(dbCmd.GetDialectProvider(), onlyFields:onlyFields); } public static T ConvertTo(this IDbCommand dbCmd, string sql = null) @@ -111,14 +149,10 @@ public static T ConvertTo(this IDbCommand dbCmd, string sql = null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetSingle(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.ConvertTo(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.ConvertTo(dbCmd.GetDialectProvider()); } internal static object ConvertTo(this IDbCommand dbCmd, Type refType, string sql = null) @@ -127,30 +161,37 @@ internal static object ConvertTo(this IDbCommand dbCmd, Type refType, string sql dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetRefSingle(dbCmd, refType); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.ConvertTo(dbCmd.GetDialectProvider(), refType); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.ConvertTo(dbCmd.GetDialectProvider(), refType); + } + + internal static T Scalar(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + return dbCmd.SetParameters(sqlParams).Scalar(sql); } - public static T Scalar(this IDbCommand dbCmd, string sql = null) + internal static T Scalar(this IDbCommand dbCmd, string sql = null) { if (sql != null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetScalar(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.Scalar(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.Scalar(dbCmd.GetDialectProvider()); + } + + public static object Scalar(this IDbCommand dbCmd, ISqlExpression sqlExpression) + { + dbCmd.PopulateWith(sqlExpression, QueryType.Scalar); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.GetScalar(dbCmd); + + return dbCmd.ExecuteScalar(); } public static object Scalar(this IDbCommand dbCmd, string sql = null) @@ -159,9 +200,7 @@ public static object Scalar(this IDbCommand dbCmd, string sql = null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetScalar(dbCmd); - } return dbCmd.ExecuteScalar(); } @@ -171,28 +210,29 @@ public static long ExecLongScalar(this IDbCommand dbCmd, string sql = null) if (sql != null) dbCmd.CommandText = sql; + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetLongScalar(dbCmd); - } return dbCmd.LongScalar(); } - internal static T ExprConvertTo(this IDbCommand dbCmd, string sql = null) + internal static T ExprConvertTo(this IDbCommand dbCmd, string sql = null, IEnumerable sqlParams = null, HashSet onlyFields = null) { if (sql != null) dbCmd.CommandText = sql; + dbCmd.SetParameters(sqlParams); + if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetSingle(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.ConvertTo(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.ConvertTo(dbCmd.GetDialectProvider(), onlyFields: onlyFields); } internal static List Column(this IDbCommand dbCmd, string sql = null) @@ -201,14 +241,15 @@ internal static List Column(this IDbCommand dbCmd, string sql = null) dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetColumn(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.Column(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.Column(dbCmd.GetDialectProvider()); + } + + internal static List Column(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + return dbCmd.SetParameters(sqlParams).Column(sql); } internal static HashSet ColumnDistinct(this IDbCommand dbCmd, string sql = null) @@ -217,14 +258,21 @@ internal static HashSet ColumnDistinct(this IDbCommand dbCmd, string sql = dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetColumnDistinct(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.ColumnDistinct(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.ColumnDistinct(dbCmd.GetDialectProvider()); + } + + internal static HashSet ColumnDistinct(this IDbCommand dbCmd, ISqlExpression expression) + { + dbCmd.PopulateWith(expression, QueryType.Select); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.GetColumnDistinct(dbCmd); + + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.ColumnDistinct(dbCmd.GetDialectProvider()); } internal static Dictionary Dictionary(this IDbCommand dbCmd, string sql = null) @@ -233,14 +281,49 @@ internal static Dictionary Dictionary(this IDbCommand dbCmd, string dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetDictionary(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.Dictionary(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.Dictionary(dbCmd.GetDialectProvider()); + } + + internal static Dictionary Dictionary(this IDbCommand dbCmd, ISqlExpression expression) + { + dbCmd.PopulateWith(expression, QueryType.Select); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.GetDictionary(dbCmd); + + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.Dictionary(dbCmd.GetDialectProvider()); + } + + internal static List> KeyValuePairs(this IDbCommand dbCmd, string sql = null) + { + if (sql != null) + dbCmd.CommandText = sql; + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.GetKeyValuePairs(dbCmd); + + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.KeyValuePairs(dbCmd.GetDialectProvider()); + } + + internal static List> KeyValuePairs(this IDbCommand dbCmd, ISqlExpression expression) + { + dbCmd.PopulateWith(expression, QueryType.Select); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.GetKeyValuePairs(dbCmd); + + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.KeyValuePairs(dbCmd.GetDialectProvider()); + } + + internal static Dictionary> Lookup(this IDbCommand dbCmd, string sql, IEnumerable sqlParams) + { + return dbCmd.SetParameters(sqlParams).Lookup(sql); } internal static Dictionary> Lookup(this IDbCommand dbCmd, string sql = null) @@ -249,14 +332,10 @@ internal static Dictionary> Lookup(this IDbCommand dbCmd, strin dbCmd.CommandText = sql; if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.GetLookup(dbCmd); - } - using (var reader = dbCmd.ExecReader(dbCmd.CommandText)) - { - return reader.Lookup(dbCmd.GetDialectProvider()); - } + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.Lookup(dbCmd.GetDialectProvider()); } } -} \ No newline at end of file +} diff --git a/src/ServiceStack.OrmLite/OrmLiteSPStatement.cs b/src/ServiceStack.OrmLite/OrmLiteSPStatement.cs index 0f399ad50..de1a5d5b2 100644 --- a/src/ServiceStack.OrmLite/OrmLiteSPStatement.cs +++ b/src/ServiceStack.OrmLite/OrmLiteSPStatement.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data; +using ServiceStack.OrmLite.Dapper; namespace ServiceStack.OrmLite { @@ -10,6 +11,29 @@ public class OrmLiteSPStatement : IDisposable private readonly IDbCommand dbCmd; private readonly IOrmLiteDialectProvider dialectProvider; + public bool TryGetParameterValue(string parameterName, out object value) + { + try + { + value = ((IDataParameter)dbCmd.Parameters[parameterName]).Value; + return true; + } + catch(Exception) + { + value = null; + return false; + } + } + + public int ReturnValue + { + get + { + var returnValue = ((IDataParameter)dbCmd.Parameters["__ReturnValue"]).Value; + return (int)returnValue; + } + } + public OrmLiteSPStatement(IDbCommand dbCmd) : this(null, dbCmd) {} @@ -33,14 +57,13 @@ public List ConvertToList() } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } } public List ConvertToScalarList() { - if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))) + if (!((typeof(T).IsPrimitive) || typeof(T).IsValueType || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))) throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Use ConvertToList function."); IDataReader reader = null; @@ -51,8 +74,7 @@ public List ConvertToScalarList() } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } } @@ -69,14 +91,13 @@ public T ConvertTo() } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } } public T ConvertToScalar() { - if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))) + if (!((typeof(T).IsPrimitive) || typeof(T).IsValueType || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))) throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Use ConvertTo function."); IDataReader reader = null; @@ -87,14 +108,13 @@ public T ConvertToScalar() } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } } public List ConvertFirstColumnToList() { - if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))) + if (!((typeof(T).IsPrimitive) || typeof(T).IsValueType || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))) throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Only primitive type can be used."); IDataReader reader = null; @@ -105,14 +125,13 @@ public List ConvertFirstColumnToList() } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } } public HashSet ConvertFirstColumnToListDistinct() { - if (!((typeof(T).IsPrimitive) || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String)))) + if (!(typeof(T).IsPrimitive) || typeof(T).IsValueType || (typeof(T) == typeof(string)) || (typeof(T) == typeof(String))) throw new Exception("Type " + typeof(T).Name + " is a non primitive type. Only primitive type can be used."); IDataReader reader = null; @@ -123,8 +142,7 @@ public HashSet ConvertFirstColumnToListDistinct() } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } } @@ -139,15 +157,11 @@ public bool HasResult() try { reader = dbCmd.ExecuteReader(); - if (reader.Read()) - return true; - else - return false; + return reader.Read(); } finally { - if (reader != null) - reader.Close(); + reader?.Close(); } } diff --git a/src/ServiceStack.OrmLite/OrmLiteSchemaApi.cs b/src/ServiceStack.OrmLite/OrmLiteSchemaApi.cs index b60d7081a..fb26cd604 100644 --- a/src/ServiceStack.OrmLite/OrmLiteSchemaApi.cs +++ b/src/ServiceStack.OrmLite/OrmLiteSchemaApi.cs @@ -1,5 +1,8 @@ using System; using System.Data; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; namespace ServiceStack.OrmLite { @@ -9,11 +12,20 @@ public static class OrmLiteSchemaApi /// Checks whether a Table Exists. E.g: /// db.TableExists("Person") /// - public static bool TableExists(this IDbConnection dbConn, string tableName, string schema=null) + public static bool TableExists(this IDbConnection dbConn, string tableName, string schema = null) { return dbConn.GetDialectProvider().DoesTableExist(dbConn, tableName, schema); } + /// + /// Checks whether a Table Exists. E.g: + /// db.TableExistsAsync("Person") + /// + public static Task TableExistsAsync(this IDbConnection dbConn, string tableName, string schema = null, CancellationToken token=default) + { + return dbConn.GetDialectProvider().DoesTableExistAsync(dbConn, tableName, schema, token); + } + /// /// Checks whether a Table Exists. E.g: /// db.TableExists<Person>() @@ -22,8 +34,88 @@ public static bool TableExists(this IDbConnection dbConn) { var dialectProvider = dbConn.GetDialectProvider(); var modelDef = typeof(T).GetModelDefinition(); + var schema = modelDef.Schema == null ? null : dialectProvider.NamingStrategy.GetSchemaName(modelDef.Schema); + var tableName = dialectProvider.NamingStrategy.GetTableName(modelDef); + return dialectProvider.DoesTableExist(dbConn, tableName, schema); + } + + /// + /// Checks whether a Table Exists. E.g: + /// db.TableExistsAsync<Person>() + /// + public static Task TableExistsAsync(this IDbConnection dbConn, CancellationToken token=default) + { + var dialectProvider = dbConn.GetDialectProvider(); + var modelDef = typeof(T).GetModelDefinition(); + var schema = modelDef.Schema == null ? null : dialectProvider.NamingStrategy.GetSchemaName(modelDef.Schema); var tableName = dialectProvider.NamingStrategy.GetTableName(modelDef); - return dialectProvider.DoesTableExist(dbConn, tableName, modelDef.Schema); + return dialectProvider.DoesTableExistAsync(dbConn, tableName, schema, token); + } + + /// + /// Checks whether a Table Column Exists. E.g: + /// db.ColumnExists("Age", "Person") + /// + public static bool ColumnExists(this IDbConnection dbConn, string columnName, string tableName, string schema = null) + { + return dbConn.GetDialectProvider().DoesColumnExist(dbConn, columnName, tableName, schema); + } + + /// + /// Checks whether a Table Column Exists. E.g: + /// db.ColumnExistsAsync("Age", "Person") + /// + public static Task ColumnExistsAsync(this IDbConnection dbConn, string columnName, string tableName, string schema = null, CancellationToken token=default) + { + return dbConn.GetDialectProvider().DoesColumnExistAsync(dbConn, columnName, tableName, schema, token); + } + + /// + /// Checks whether a Table Column Exists. E.g: + /// db.ColumnExists<Person>(x => x.Age) + /// + public static bool ColumnExists(this IDbConnection dbConn, Expression> field) + { + var dialectProvider = dbConn.GetDialectProvider(); + var modelDef = typeof(T).GetModelDefinition(); + var schema = modelDef.Schema == null ? null : dialectProvider.NamingStrategy.GetSchemaName(modelDef.Schema); + var tableName = dialectProvider.NamingStrategy.GetTableName(modelDef); + var fieldDef = modelDef.GetFieldDefinition(field); + var fieldName = dialectProvider.NamingStrategy.GetColumnName(fieldDef.FieldName); + return dialectProvider.DoesColumnExist(dbConn, fieldName, tableName, schema); + } + + /// + /// Checks whether a Table Column Exists. E.g: + /// db.ColumnExistsAsync<Person>(x => x.Age) + /// + public static Task ColumnExistsAsync(this IDbConnection dbConn, Expression> field, CancellationToken token=default) + { + var dialectProvider = dbConn.GetDialectProvider(); + var modelDef = typeof(T).GetModelDefinition(); + var schema = modelDef.Schema == null ? null : dialectProvider.NamingStrategy.GetSchemaName(modelDef.Schema); + var tableName = dialectProvider.NamingStrategy.GetTableName(modelDef); + var fieldDef = modelDef.GetFieldDefinition(field); + var fieldName = dialectProvider.NamingStrategy.GetColumnName(fieldDef.FieldName); + return dialectProvider.DoesColumnExistAsync(dbConn, fieldName, tableName, schema, token); + } + + /// + /// Create a DB Schema from the Schema attribute on the generic type. E.g: + /// db.CreateSchema<Person>() //default + /// + public static void CreateSchema(this IDbConnection dbConn) + { + dbConn.Exec(dbCmd => dbCmd.CreateSchema()); + } + + /// + /// Create a DB Schema. E.g: + /// db.CreateSchema("schemaName") + /// + public static bool CreateSchema(this IDbConnection dbConn, string schemaName) + { + return dbConn.Exec(dbCmd => dbCmd.CreateSchema(schemaName)); } /// @@ -76,18 +168,18 @@ public static void CreateTable(this IDbConnection dbConn, bool overwrite = fa /// Only create a DB Table from the generic type if it doesn't already exist. E.g: /// db.CreateTableIfNotExists<Person>() /// - public static void CreateTableIfNotExists(this IDbConnection dbConn) + public static bool CreateTableIfNotExists(this IDbConnection dbConn) { - dbConn.Exec(dbCmd => dbCmd.CreateTable(false)); + return dbConn.Exec(dbCmd => dbCmd.CreateTable(overwrite:false)); } /// /// Only create a DB Table from the runtime type if it doesn't already exist. E.g: /// db.CreateTableIfNotExists(typeof(Person)) /// - public static void CreateTableIfNotExists(this IDbConnection dbConn, Type modelType) + public static bool CreateTableIfNotExists(this IDbConnection dbConn, Type modelType) { - dbConn.Exec(dbCmd => dbCmd.CreateTable(false, modelType)); + return dbConn.Exec(dbCmd => dbCmd.CreateTable(false, modelType)); } /// @@ -134,7 +226,5 @@ public static void DropTable(this IDbConnection dbConn) { dbConn.Exec(dbCmd => dbCmd.DropTable()); } - - } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteSchemaModifyApi.cs b/src/ServiceStack.OrmLite/OrmLiteSchemaModifyApi.cs index d0e6ae6bf..baee8e4fa 100644 --- a/src/ServiceStack.OrmLite/OrmLiteSchemaModifyApi.cs +++ b/src/ServiceStack.OrmLite/OrmLiteSchemaModifyApi.cs @@ -15,6 +15,14 @@ public enum OnFkOption public static class OrmLiteSchemaModifyApi { + private static void InitUserFieldDefinition(Type modelType, FieldDefinition fieldDef) + { + if (fieldDef.PropertyInfo == null) + { + fieldDef.PropertyInfo = TypeProperties.Get(modelType).GetPublicProperty(fieldDef.Name); + } + } + public static void AlterTable(this IDbConnection dbConn, string command) { AlterTable(dbConn, typeof(T), command); @@ -22,28 +30,25 @@ public static void AlterTable(this IDbConnection dbConn, string command) public static void AlterTable(this IDbConnection dbConn, Type modelType, string command) { - string sql = string.Format("ALTER TABLE {0} {1};", - dbConn.GetDialectProvider().GetQuotedTableName(modelType.GetModelDefinition()), - command); + var sql = $"ALTER TABLE {dbConn.GetDialectProvider().GetQuotedTableName(modelType.GetModelDefinition())} {command};"; dbConn.ExecuteSql(sql); } - public static void AddColumn(this IDbConnection dbConn, - Expression> field) + public static void AddColumn(this IDbConnection dbConn, Expression> field) { var modelDef = ModelDefinition.Definition; - var fieldDef = modelDef.GetFieldDefinition(field); + var fieldDef = modelDef.GetFieldDefinition(field); dbConn.AddColumn(typeof(T), fieldDef); } - public static void AddColumn(this IDbConnection dbConn, Type modelType, FieldDefinition fieldDef) { + InitUserFieldDefinition(modelType, fieldDef); + var command = dbConn.GetDialectProvider().ToAddColumnStatement(modelType, fieldDef); dbConn.ExecuteSql(command); } - public static void AlterColumn(this IDbConnection dbConn, Expression> field) { var modelDef = ModelDefinition.Definition; @@ -53,14 +58,15 @@ public static void AlterColumn(this IDbConnection dbConn, Expression(this IDbConnection dbConn, - Expression> field, - string oldColumnName) + Expression> field, + string oldColumnName) { var modelDef = ModelDefinition.Definition; var fieldDef = modelDef.GetFieldDefinition(field); @@ -68,58 +74,59 @@ public static void ChangeColumnName(this IDbConnection dbConn, } public static void ChangeColumnName(this IDbConnection dbConn, - Type modelType, - FieldDefinition fieldDef, - string oldColumnName) + Type modelType, + FieldDefinition fieldDef, + string oldColumnName) { var command = dbConn.GetDialectProvider().ToChangeColumnNameStatement(modelType, fieldDef, oldColumnName); dbConn.ExecuteSql(command); } + public static void DropColumn(this IDbConnection dbConn, Expression> field) + { + var modelDef = ModelDefinition.Definition; + var fieldDef = modelDef.GetFieldDefinition(field); + dbConn.DropColumn(typeof(T), fieldDef.FieldName); + } + public static void DropColumn(this IDbConnection dbConn, string columnName) { dbConn.DropColumn(typeof(T), columnName); } - public static void DropColumn(this IDbConnection dbConn, Type modelType, string columnName) { - string command = string.Format("ALTER TABLE {0} DROP {1};", - dbConn.GetDialectProvider().GetQuotedTableName(modelType.GetModelDefinition().ModelName), - dbConn.GetDialectProvider().GetQuotedName(columnName)); - - dbConn.ExecuteSql(command); + dbConn.GetDialectProvider().DropColumn(dbConn, modelType, columnName); } - - public static void AddForeignKey(this IDbConnection dbConn, - Expression> field, - Expression> foreignField, - OnFkOption onUpdate, - OnFkOption onDelete, - string foreignKeyName = null) - { - string command = dbConn.GetDialectProvider().ToAddForeignKeyStatement(field, - foreignField, - onUpdate, - onDelete, - foreignKeyName); + Expression> field, + Expression> foreignField, + OnFkOption onUpdate, + OnFkOption onDelete, + string foreignKeyName = null) + { + var command = dbConn.GetDialectProvider().ToAddForeignKeyStatement( + field, foreignField, onUpdate, onDelete, foreignKeyName); + dbConn.ExecuteSql(command); } public static void DropForeignKey(this IDbConnection dbConn, string foreignKeyName) { - string command = string.Format("ALTER TABLE {0} DROP FOREIGN KEY {1};", - dbConn.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition.ModelName), - dbConn.GetDialectProvider().GetQuotedName(foreignKeyName)); + var provider = dbConn.GetDialectProvider(); + var modelDef = ModelDefinition.Definition; + var command = string.Format(provider.GetDropForeignKeyConstraints(modelDef), + provider.GetQuotedTableName(modelDef.ModelName), + provider.GetQuotedName(foreignKeyName)); + dbConn.ExecuteSql(command); } public static void CreateIndex(this IDbConnection dbConn, Expression> field, - string indexName = null, bool unique = false) + string indexName = null, bool unique = false) { var command = dbConn.GetDialectProvider().ToCreateIndexStatement(field, indexName, unique); dbConn.ExecuteSql(command); @@ -128,9 +135,9 @@ public static void CreateIndex(this IDbConnection dbConn, Expression(this IDbConnection dbConn, string indexName) { - string command = string.Format("ALTER TABLE {0} DROP INDEX {1};", - dbConn.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition.ModelName), - dbConn.GetDialectProvider().GetQuotedName(indexName)); + var provider = dbConn.GetDialectProvider(); + var command = $"ALTER TABLE {provider.GetQuotedTableName(ModelDefinition.Definition.ModelName)} " + + $"DROP INDEX {provider.GetQuotedName(indexName)};"; dbConn.ExecuteSql(command); } diff --git a/src/ServiceStack.OrmLite/OrmLiteTransaction.cs b/src/ServiceStack.OrmLite/OrmLiteTransaction.cs index 6ebf759d7..50ffcaf56 100644 --- a/src/ServiceStack.OrmLite/OrmLiteTransaction.cs +++ b/src/ServiceStack.OrmLite/OrmLiteTransaction.cs @@ -1,11 +1,14 @@ using System; using System.Data; +using ServiceStack.Data; namespace ServiceStack.OrmLite { public class OrmLiteTransaction : IDbTransaction, IHasDbTransaction { public IDbTransaction Transaction { get; set; } + public IDbTransaction DbTransaction => Transaction; + private readonly IDbConnection db; public OrmLiteTransaction(IDbConnection db, IDbTransaction transaction) @@ -14,8 +17,7 @@ public OrmLiteTransaction(IDbConnection db, IDbTransaction transaction) this.Transaction = transaction; //If OrmLite managed connection assign to connection, otherwise use OrmLiteContext - var ormLiteConn = this.db as IHasDbTransaction; - if (ormLiteConn != null) + if (this.db is ISetDbTransaction ormLiteConn) { ormLiteConn.Transaction = this.Transaction = transaction; } @@ -33,8 +35,7 @@ public void Dispose() } finally { - var ormLiteConn = this.db as IHasDbTransaction; - if (ormLiteConn != null) + if (this.db is ISetDbTransaction ormLiteConn) { ormLiteConn.Transaction = null; } @@ -55,14 +56,8 @@ public void Rollback() Transaction.Rollback(); } - public IDbConnection Connection - { - get { return Transaction.Connection; } - } + public IDbConnection Connection => Transaction.Connection; - public IsolationLevel IsolationLevel - { - get { return Transaction.IsolationLevel; } - } + public IsolationLevel IsolationLevel => Transaction.IsolationLevel; } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteUtils.cs b/src/ServiceStack.OrmLite/OrmLiteUtils.cs index 677f33ce4..dca293176 100644 --- a/src/ServiceStack.OrmLite/OrmLiteUtils.cs +++ b/src/ServiceStack.OrmLite/OrmLiteUtils.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // @@ -13,92 +13,352 @@ using System.Collections; using System.Collections.Generic; using System.Data; +using System.Diagnostics; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using System.Text; +using System.Text.RegularExpressions; +using ServiceStack.Logging; using ServiceStack.Text; +using ServiceStack.OrmLite.Dapper; +using ServiceStack.Reflection; namespace ServiceStack.OrmLite { + internal class EOT {} + public static class OrmLiteUtils { internal const string AsyncRequiresNet45Error = "Async support is only available in .NET 4.5 builds"; + const int maxCachedIndexFields = 10000; + private static readonly Dictionary[]> indexFieldsCache + = new Dictionary[]>(maxCachedIndexFields); + + internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteUtils)); + + public static void HandleException(Exception ex, string message = null) + { + if (OrmLiteConfig.ThrowOnError) + throw ex; + + Log.Error(message ?? ex.Message, ex); + } + + public static void DebugCommand(this ILog log, IDbCommand cmd) + { + log.Debug(GetDebugString(cmd)); + } + + public static string GetDebugString(this IDbCommand cmd) + { + var sb = StringBuilderCache.Allocate(); + + sb.Append("SQL: ").Append(cmd.CommandText); + + if (cmd.Parameters.Count > 0) + { + sb.AppendLine() + .Append("PARAMS: "); + + for (var i = 0; i < cmd.Parameters.Count; i++) + { + var p = (IDataParameter) cmd.Parameters[i]; + if (i > 0) + sb.Append(", "); + sb.Append($"{p.ParameterName}={p.Value}"); + } + } + + return StringBuilderCache.ReturnAndFree(sb); + } + public static T CreateInstance() { return (T)ReflectionExtensions.CreateInstance(); } + internal static bool IsTuple(this Type type) => type.Name.StartsWith("Tuple`", StringComparison.Ordinal); + + internal static bool IsValueTuple(this Type type) => type.Name.StartsWith("ValueTuple`", StringComparison.Ordinal); + public static bool IsScalar() { - return typeof(T).IsValueType || typeof(T) == typeof(string); + var isScalar = typeof(T).IsValueType && !typeof(T).IsValueTuple() || typeof(T) == typeof(string); + return isScalar; } - public static T ConvertTo(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider) + public static T ConvertTo(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, HashSet onlyFields=null) { - var fieldDefs = ModelDefinition.Definition.AllFieldDefinitionsArray; - - using (dataReader) + using (reader) { - if (dataReader.Read()) + if (reader.Read()) { + if (typeof(T) == typeof (List)) + return (T)(object)reader.ConvertToListObjects(); + + if (typeof(T) == typeof(Dictionary)) + return (T)(object)reader.ConvertToDictionaryObjects(); + + var values = new object[reader.FieldCount]; + + if (typeof(T).IsValueTuple()) + return reader.ConvertToValueTuple(values, dialectProvider); + var row = CreateInstance(); - var indexCache = dataReader.GetIndexFieldsCache(ModelDefinition.Definition); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider, onlyFields: onlyFields); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); return row; } return default(T); } } - public static List ConvertToList(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider) + public static List ConvertToListObjects(this IDataReader dataReader) + { + var row = new List(); + for (var i = 0; i < dataReader.FieldCount; i++) + { + var dbValue = dataReader.GetValue(i); + row.Add(dbValue is DBNull ? null : dbValue); + } + return row; + } + + public static Dictionary ConvertToDictionaryObjects(this IDataReader dataReader) + { + var row = new Dictionary(); + for (var i = 0; i < dataReader.FieldCount; i++) + { + var dbValue = dataReader.GetValue(i); + row[dataReader.GetName(i).Trim()] = dbValue is DBNull ? null : dbValue; + } + return row; + } + + public static IDictionary ConvertToExpandoObject(this IDataReader dataReader) { - var fieldDefs = ModelDefinition.Definition.AllFieldDefinitionsArray; + var row = (IDictionary)new ExpandoObject(); + for (var i = 0; i < dataReader.FieldCount; i++) + { + var dbValue = dataReader.GetValue(i); + row[dataReader.GetName(i).Trim()] = dbValue is DBNull ? null : dbValue; + } + return row; + } + + public static T ConvertToValueTuple(this IDataReader reader, object[] values, IOrmLiteDialectProvider dialectProvider) + { + var row = typeof(T).CreateInstance(); + var typeFields = TypeFields.Get(typeof(T)); - var to = new List(); - using (dataReader) + values = reader.PopulateValues(values, dialectProvider); + + for (var i = 0; i < reader.FieldCount; i++) { - var indexCache = dataReader.GetIndexFieldsCache(ModelDefinition.Definition); - while (dataReader.Read()) + var itemName = "Item" + (i + 1); + var field = typeFields.GetAccessor(itemName); + if (field == null) break; + + var fieldType = field.FieldInfo.FieldType; + var converter = dialectProvider.GetConverterBestMatch(fieldType); + + var dbValue = converter.GetValue(reader, i, values); + if (dbValue == null) + continue; + + if (dbValue.GetType() == fieldType) { - var row = CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); - to.Add(row); + field.PublicSetterRef(ref row, dbValue); + } + else + { + var fieldValue = converter.FromDbValue(fieldType, dbValue); + field.PublicSetterRef(ref row, fieldValue); } } - return to; + return (T)row; } - public static object ConvertTo(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, Type type) + public static List ConvertToList(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, HashSet onlyFields=null) { - var modelDef = type.GetModelDefinition(); - var fieldDefs = modelDef.AllFieldDefinitionsArray; + if (typeof(T) == typeof(List)) + { + var to = new List>(); + using (reader) + { + while (reader.Read()) + { + var row = reader.ConvertToListObjects(); + to.Add(row); + } + } + return (List)(object)to; + } + if (typeof(T) == typeof(Dictionary)) + { + var to = new List>(); + using (reader) + { + while (reader.Read()) + { + var row = reader.ConvertToDictionaryObjects(); + to.Add(row); + } + } + return (List)(object)to; + } + if (typeof(T) == typeof(object)) + { + var to = new List(); + using (reader) + { + while (reader.Read()) + { + var row = reader.ConvertToExpandoObject(); + to.Add(row); + } + } + return (List)(object)to.ToList(); + } + if (typeof(T).IsValueTuple()) + { + var to = new List(); + var values = new object[reader.FieldCount]; + using (reader) + { + while (reader.Read()) + { + var row = reader.ConvertToValueTuple(values, dialectProvider); + to.Add(row); + } + } + return to; + } + if (typeof(T).IsTuple()) + { + var to = new List(); + using (reader) + { + var genericArgs = typeof(T).GetGenericArguments(); + var modelIndexCaches = reader.GetMultiIndexCaches(dialectProvider, onlyFields, genericArgs); + + var values = new object[reader.FieldCount]; + var genericTupleMi = typeof(T).GetGenericTypeDefinition().GetCachedGenericType(genericArgs); + var activator = genericTupleMi.GetConstructor(genericArgs).GetActivator(); + + while (reader.Read()) + { + var tupleArgs = reader.ToMultiTuple(dialectProvider, modelIndexCaches, genericArgs, values); + var tuple = activator(tupleArgs.ToArray()); + to.Add((T)tuple); + } + } + return to; + } + else + { + var to = new List(); + using (reader) + { + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider, onlyFields:onlyFields); + var values = new object[reader.FieldCount]; + while (reader.Read()) + { + var row = CreateInstance(); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); + to.Add(row); + } + } + return to; + } + } + + internal static List ToMultiTuple(this IDataReader reader, + IOrmLiteDialectProvider dialectProvider, + List[]> modelIndexCaches, + Type[] genericArgs, + object[] values) + { + var tupleArgs = new List(); + for (var i = 0; i < modelIndexCaches.Count; i++) + { + var indexCache = modelIndexCaches[i]; + var partialRow = genericArgs[i].CreateInstance(); + partialRow.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); + tupleArgs.Add(partialRow); + } + return tupleArgs; + } - using (dataReader) + internal static List[]> GetMultiIndexCaches( + this IDataReader reader, + IOrmLiteDialectProvider dialectProvider, + HashSet onlyFields, + Type[] genericArgs) + { + var modelIndexCaches = new List[]>(); + var startPos = 0; + + foreach (var modelType in genericArgs) { - if (dataReader.Read()) + var modelDef = modelType.GetModelDefinition(); + if (modelDef == null) + throw new Exception($"'{modelType.Name}' is not a table type"); + + var endPos = startPos; + for (; endPos < reader.FieldCount; endPos++) + { + if (string.Equals("EOT", reader.GetName(endPos), StringComparison.OrdinalIgnoreCase)) + break; + } + + var noEOT = endPos == reader.FieldCount; // If no explicit EOT delimiter, split by field count + if (genericArgs.Length > 0 && noEOT) + endPos = startPos + modelDef.FieldDefinitionsArray.Length; + + var indexCache = reader.GetIndexFieldsCache(modelDef, dialectProvider, onlyFields, + startPos: startPos, endPos: endPos); + + modelIndexCaches.Add(indexCache); + + startPos = noEOT ? endPos : endPos + 1; + } + return modelIndexCaches; + } + + public static object ConvertTo(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, Type type) + { + var modelDef = type.GetModelDefinition(); + using (reader) + { + if (reader.Read()) { var row = type.CreateInstance(); - var indexCache = dataReader.GetIndexFieldsCache(modelDef); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); + var indexCache = reader.GetIndexFieldsCache(modelDef, dialectProvider); + var values = new object[reader.FieldCount]; + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); return row; } return type.GetDefaultValue(); } } - public static IList ConvertToList(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, Type type) + public static IList ConvertToList(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, Type type) { var modelDef = type.GetModelDefinition(); - var fieldDefs = modelDef.AllFieldDefinitionsArray; - - var listInstance = typeof(List<>).MakeGenericType(type).CreateInstance(); + var listInstance = typeof(List<>).GetCachedGenericType(type).CreateInstance(); var to = (IList)listInstance; - using (dataReader) + using (reader) { - var indexCache = dataReader.GetIndexFieldsCache(modelDef); - while (dataReader.Read()) + var indexCache = reader.GetIndexFieldsCache(modelDef, dialectProvider); + var values = new object[reader.FieldCount]; + while (reader.Read()) { var row = type.CreateInstance(); - row.PopulateWithSqlReader(dialectProvider, dataReader, fieldDefs, indexCache); + row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values); to.Add(row); } } @@ -115,15 +375,33 @@ public static string GetColumnNames(this ModelDefinition modelDef, IOrmLiteDiale return dialect.GetColumnNames(modelDef); } - internal static string GetIdsInSql(this IEnumerable idValues) + public static string ToSelectString(this IEnumerable items) { - var sql = new StringBuilder(); - foreach (var idValue in idValues) + var sb = StringBuilderCache.Allocate(); + + foreach (var item in items) { - if (sql.Length > 0) sql.Append(","); - sql.AppendFormat("{0}".SqlFmt(idValue)); + if (sb.Length > 0) + sb.Append(", "); + sb.Append(item); } - return sql.Length == 0 ? null : sql.ToString(); + + return StringBuilderCache.ReturnAndFree(sb); + } + + internal static string SetIdsInSqlParams(this IDbCommand dbCmd, IEnumerable idValues) + { + var inArgs = Sql.Flatten(idValues); + var sbParams = StringBuilderCache.Allocate(); + foreach (var item in inArgs) + { + if (sbParams.Length > 0) + sbParams.Append(","); + + sbParams.Append(dbCmd.AddParam(dbCmd.Parameters.Count.ToString(), item).ParameterName); + } + var sqlIn = StringBuilderCache.ReturnAndFree(sbParams); + return sqlIn; } public static string SqlFmt(this string sqlText, params object[] sqlParams) @@ -133,6 +411,9 @@ public static string SqlFmt(this string sqlText, params object[] sqlParams) public static string SqlFmt(this string sqlText, IOrmLiteDialectProvider dialect, params object[] sqlParams) { + if (sqlParams.Length == 0) + return sqlText; + var escapedParams = new List(); foreach (var sqlParam in sqlParams) { @@ -142,8 +423,7 @@ public static string SqlFmt(this string sqlText, IOrmLiteDialectProvider dialect } else { - var sqlInValues = sqlParam as SqlInValues; - if (sqlInValues != null) + if (sqlParam is SqlInValues sqlInValues) { escapedParams.Add(sqlInValues.ToSqlInString()); } @@ -153,7 +433,7 @@ public static string SqlFmt(this string sqlText, IOrmLiteDialectProvider dialect } } } - return String.Format(sqlText, escapedParams.ToArray()); + return string.Format(sqlText, escapedParams.ToArray()); } public static string SqlColumn(this string columnName, IOrmLiteDialectProvider dialect = null) @@ -171,7 +451,7 @@ public static string SqlTable(this string tableName, IOrmLiteDialectProvider dia return (dialect ?? OrmLiteConfig.DialectProvider).GetQuotedTableName(tableName); } - public static string SqlTableRaw(this string tableName, IOrmLiteDialectProvider dialect=null) + public static string SqlTableRaw(this string tableName, IOrmLiteDialectProvider dialect = null) { return (dialect ?? OrmLiteConfig.DialectProvider).NamingStrategy.GetTableName(tableName); } @@ -181,20 +461,55 @@ public static string SqlValue(this object value) return "{0}".SqlFmt(value); } - public static string[] IllegalSqlFragmentTokens = { - "--", ";--", ";", "%", "/*", "*/", "@@", "@", - "char", "nchar", "varchar", "nvarchar", - "alter", "begin", "cast", "create", "cursor", "declare", "delete", - "drop", "end", "exec", "execute", "fetch", "insert", "kill", - "open", "select", "sys", "sysobjects", "syscolumns", "table", "update" }; + public static Regex VerifyFragmentRegEx = new Regex("([^\\w]|^)+(--|;--|;|%|/\\*|\\*/|@@|@|char|nchar|varchar|nvarchar|alter|begin|cast|create|cursor|declare|delete|drop|end|exec|execute|fetch|insert|kill|open|select|sys|sysobjects|syscolumns|table|update)([^\\w]|$)+", + RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public static Regex VerifySqlRegEx = new Regex("([^\\w]|^)+(--|;--|;|%|/\\*|\\*/|@@|@|char|nchar|varchar|nvarchar|alter|begin|cast|create|cursor|declare|delete|drop|end|exec|execute|fetch|insert|kill|open|table|update)([^\\w]|$)+", + RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public static Func SqlVerifyFragmentFn { get; set; } + + public static bool isUnsafeSql(string sql, Regex verifySql) + { + if (sql == null) + return false; + + if (SqlVerifyFragmentFn != null) + { + SqlVerifyFragmentFn(sql); + return false; + } + + var fragmentToVerify = sql + .StripQuotedStrings('\'') + .StripQuotedStrings('"') + .StripQuotedStrings('`') + .ToLower(); + + var match = verifySql.Match(fragmentToVerify); + return match.Success; + } public static string SqlVerifyFragment(this string sqlFragment) { - return SqlVerifyFragment(sqlFragment, IllegalSqlFragmentTokens); + if (isUnsafeSql(sqlFragment, VerifyFragmentRegEx)) + throw new ArgumentException("Potential illegal fragment detected: " + sqlFragment); + + return sqlFragment; } + public static string[] IllegalSqlFragmentTokens = { + "--", ";--", ";", "%", "/*", "*/", "@@", "@", + "char", "nchar", "varchar", "nvarchar", + "alter", "begin", "cast", "create", "cursor", "declare", "delete", + "drop", "end", "exec", "execute", "fetch", "insert", "kill", + "open", "select", "sys", "sysobjects", "syscolumns", "table", "update" }; + public static string SqlVerifyFragment(this string sqlFragment, IEnumerable illegalFragments) { + if (sqlFragment == null) + return null; + var fragmentToVerify = sqlFragment .StripQuotedStrings('\'') .StripQuotedStrings('"') @@ -203,7 +518,7 @@ public static string SqlVerifyFragment(this string sqlFragment, IEnumerable= 0)) + if (fragmentToVerify.IndexOf(illegalFragment, StringComparison.Ordinal) >= 0) throw new ArgumentException("Potential illegal fragment detected: " + sqlFragment); } @@ -217,11 +532,10 @@ public static string SqlParam(this string paramValue) public static string StripQuotedStrings(this string text, char quote = '\'') { - var sb = new StringBuilder(); - bool inQuotes = false; - for (int i = 0; i < text.Length; i++) + var sb = StringBuilderCache.Allocate(); + var inQuotes = false; + foreach (var c in text) { - var c = text[i]; if (c == quote) { inQuotes = !inQuotes; @@ -232,64 +546,250 @@ public static string StripQuotedStrings(this string text, char quote = '\'') sb.Append(c); } - return sb.ToString(); + return StringBuilderCache.ReturnAndFree(sb); } public static string SqlJoin(this List values, IOrmLiteDialectProvider dialect = null) { - dialect = (dialect ?? OrmLiteConfig.DialectProvider); + if (values == null) + return string.Empty; + + dialect ??= OrmLiteConfig.DialectProvider; - var sb = new StringBuilder(); + var sb = StringBuilderCache.Allocate(); foreach (var value in values) { if (sb.Length > 0) sb.Append(","); sb.Append(dialect.GetQuotedValue(value, value.GetType())); } - return sb.ToString(); + return StringBuilderCache.ReturnAndFree(sb); } public static string SqlJoin(IEnumerable values, IOrmLiteDialectProvider dialect = null) { - dialect = (dialect ?? OrmLiteConfig.DialectProvider); + if (values == null) + return string.Empty; + + dialect ??= OrmLiteConfig.DialectProvider; - var sb = new StringBuilder(); + var sb = StringBuilderCache.Allocate(); foreach (var value in values) { - if (sb.Length > 0) sb.Append(","); + if (sb.Length > 0) + sb.Append(","); sb.Append(dialect.GetQuotedValue(value, value.GetType())); } - return sb.ToString(); + return StringBuilderCache.ReturnAndFree(sb); } - public static SqlInValues SqlInValues(this T[] values, IOrmLiteDialectProvider dialect=null) + public static SqlInValues SqlInValues(this T[] values, IOrmLiteDialectProvider dialect = null) { return new SqlInValues(values, dialect); } - public static Dictionary GetIndexFieldsCache(this IDataReader reader, ModelDefinition modelDefinition = null) + public static string SqlInParams(this T[] values, IOrmLiteDialectProvider dialect = null) { - var cache = new Dictionary(); - if (modelDefinition != null) + var sb = StringBuilderCache.Allocate(); + if (dialect == null) + dialect = OrmLiteConfig.DialectProvider; + + for (var i = 0; i < values.Length; i++) + { + if (sb.Length > 0) + sb.Append(','); + var paramName = dialect.ParamString + "v" + i; + sb.Append(paramName); + } + + return StringBuilderCache.ReturnAndFree(sb); + } + + public static Tuple[] GetIndexFieldsCache(this IDataReader reader, + ModelDefinition modelDefinition, + IOrmLiteDialectProvider dialect, + HashSet onlyFields = null, + int startPos=0, + int? endPos = null) + { + var end = endPos.GetValueOrDefault(reader.FieldCount); + var cacheKey = (startPos == 0 && end == reader.FieldCount && onlyFields == null) + ? new IndexFieldsCacheKey(reader, modelDefinition, dialect) + : null; + + Tuple[] value; + if (cacheKey != null) { - foreach (var field in modelDefinition.IgnoredFieldDefinitions) + lock (indexFieldsCache) { - cache[field.FieldName] = -1; + if (indexFieldsCache.TryGetValue(cacheKey, out value)) + return value; } } - for (var i = 0; i < reader.FieldCount; i++) + + var cache = new List>(); + var ignoredFields = modelDefinition.IgnoredFieldDefinitions; + var remainingFieldDefs = modelDefinition.FieldDefinitionsArray + .Where(x => !ignoredFields.Contains(x) && x.SetValueFn != null).ToList(); + + var mappedReaderColumns = new bool[end]; + + for (var i = startPos; i < end; i++) { - cache[reader.GetName(i)] = i; + var columnName = reader.GetName(i); + var fieldDef = modelDefinition.GetFieldDefinition(columnName); + if (fieldDef == null) + { + foreach (var def in modelDefinition.FieldDefinitionsArray) + { + if (string.Equals(dialect.NamingStrategy.GetColumnName(def.FieldName), columnName, + StringComparison.OrdinalIgnoreCase)) + { + fieldDef = def; + break; + } + } + } + + if (fieldDef != null && !ignoredFields.Contains(fieldDef) && fieldDef.SetValueFn != null) + { + remainingFieldDefs.Remove(fieldDef); + mappedReaderColumns[i] = true; + cache.Add(Tuple.Create(fieldDef, i, dialect.GetConverterBestMatch(fieldDef))); + } } - return cache; + + if (remainingFieldDefs.Count > 0 && onlyFields == null) + { + var dbFieldMap = new Dictionary(StringComparer.OrdinalIgnoreCase); + for (var i = startPos; i < end; i++) + { + if (!mappedReaderColumns[i]) + { + var fieldName = reader.GetName(i); + dbFieldMap[fieldName] = i; + } + } + + if (dbFieldMap.Count > 0) + { + foreach (var fieldDef in remainingFieldDefs) + { + var index = FindColumnIndex(dialect, fieldDef, dbFieldMap); + if (index != NotFound) + { + cache.Add(Tuple.Create(fieldDef, index, dialect.GetConverterBestMatch(fieldDef))); + } + } + } + } + + var result = cache.ToArray(); + + if (cacheKey != null) + { + lock (indexFieldsCache) + { + if (indexFieldsCache.TryGetValue(cacheKey, out value)) + return value; + if (indexFieldsCache.Count < maxCachedIndexFields) + indexFieldsCache.Add(cacheKey, result); + } + } + + return result; + } + + private const int NotFound = -1; + internal static int FindColumnIndex(IOrmLiteDialectProvider dialectProvider, FieldDefinition fieldDef, Dictionary dbFieldMap) + { + var fieldName = dialectProvider.NamingStrategy.GetColumnName(fieldDef.FieldName); + if (dbFieldMap.TryGetValue(fieldName, out var index)) + return index; + + index = TryGuessColumnIndex(fieldName, dbFieldMap); + if (index != NotFound) + return index; + + // Try fallback to original field name when overriden by alias + if (fieldDef.Alias != null && !OrmLiteConfig.DisableColumnGuessFallback) + { + var alias = dialectProvider.NamingStrategy.GetColumnName(fieldDef.Name); + if (dbFieldMap.TryGetValue(alias, out index)) + return index; + + index = TryGuessColumnIndex(alias, dbFieldMap); + if (index != NotFound) + return index; + } + + return NotFound; + } + + private static readonly Regex AllowedPropertyCharsRegex = new Regex(@"[^0-9a-zA-Z_]", + RegexOptions.Compiled | RegexOptions.CultureInvariant); + + private static int TryGuessColumnIndex(string fieldName, Dictionary dbFieldMap) + { + if (OrmLiteConfig.DisableColumnGuessFallback) + return NotFound; + + foreach (var entry in dbFieldMap) + { + var dbFieldName = entry.Key; + var i = entry.Value; + + // First guess: Maybe the DB field has underscores? (most common) + // e.g. CustomerId (C#) vs customer_id (DB) + var dbFieldNameWithNoUnderscores = dbFieldName.Replace("_", ""); + if (string.Compare(fieldName, dbFieldNameWithNoUnderscores, StringComparison.OrdinalIgnoreCase) == 0) + return i; + + // Next guess: Maybe the DB field has special characters? + // e.g. Quantity (C#) vs quantity% (DB) + var dbFieldNameSanitized = AllowedPropertyCharsRegex.Replace(dbFieldName, string.Empty); + if (string.Compare(fieldName, dbFieldNameSanitized, StringComparison.OrdinalIgnoreCase) == 0) + return i; + + // Next guess: Maybe the DB field has special characters *and* has underscores? + // e.g. Quantity (C#) vs quantity_% (DB) + if (string.Compare(fieldName, dbFieldNameSanitized.Replace("_", string.Empty), StringComparison.OrdinalIgnoreCase) == 0) + return i; + + // Next guess: Maybe the DB field has some prefix that we don't have in our C# field? + // e.g. CustomerId (C#) vs t130CustomerId (DB) + if (dbFieldName.EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) + return i; + + // Next guess: Maybe the DB field has some prefix that we don't have in our C# field *and* has underscores? + // e.g. CustomerId (C#) vs t130_CustomerId (DB) + if (dbFieldNameWithNoUnderscores.EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) + return i; + + // Next guess: Maybe the DB field has some prefix that we don't have in our C# field *and* has special characters? + // e.g. CustomerId (C#) vs t130#CustomerId (DB) + if (dbFieldNameSanitized.EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) + return i; + + // Next guess: Maybe the DB field has some prefix that we don't have in our C# field *and* has underscores *and* has special characters? + // e.g. CustomerId (C#) vs t130#Customer_I#d (DB) + if (dbFieldNameSanitized.Replace("_", "").EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) + return i; + + // Cater for Naming Strategies like PostgreSQL that has lower_underscore names + if (dbFieldNameSanitized.Replace("_", "").EndsWith(fieldName.Replace("_", ""), StringComparison.OrdinalIgnoreCase)) + return i; + } + + return NotFound; } public static bool IsRefType(this Type fieldType) { return (!fieldType.UnderlyingSystemType.IsValueType - || JsConfig.TreatValueAsRefTypes.Contains(fieldType.IsGeneric() - ? fieldType.GenericTypeDefinition() + || JsConfig.TreatValueAsRefTypes.Contains(fieldType.IsGenericType + ? fieldType.GetGenericTypeDefinition() : fieldType)) && fieldType != typeof(string); } @@ -299,7 +799,7 @@ public static string StripTablePrefixes(this string selectExpression) if (selectExpression.IndexOf('.') < 0) return selectExpression; - var sb = new StringBuilder(); + var sb = StringBuilderCache.Allocate(); var tokens = selectExpression.Split(' '); foreach (var token in tokens) { @@ -314,39 +814,357 @@ public static string StripTablePrefixes(this string selectExpression) } } - return sb.ToString().Trim(); + return StringBuilderCache.ReturnAndFree(sb).Trim(); } - private const int NotFound = -1; + private static readonly char[] QuotedChars = { '"', '`', '[', ']' }; + + public static string AliasOrColumn(this string quotedExpr) + { + var ret = quotedExpr.LastRightPart(" AS ").Trim(); + return ret; + } + + public static string StripDbQuotes(this string quotedExpr) + { + return quotedExpr.Trim(QuotedChars); + } + + public static void PrintSql() => OrmLiteConfig.BeforeExecFilter = cmd => Console.WriteLine(cmd.GetDebugString()); + + public static void UnPrintSql() => OrmLiteConfig.BeforeExecFilter = null; + + public static StringBuilder CaptureSql() + { + var sb = StringBuilderCache.Allocate(); + CaptureSql(sb); + return sb; + } + + public static void CaptureSql(StringBuilder sb) => + OrmLiteConfig.BeforeExecFilter = cmd => sb.AppendLine(cmd.GetDebugString()); + + public static void UnCaptureSql() => OrmLiteConfig.BeforeExecFilter = null; + + public static string UnCaptureSqlAndFree(StringBuilder sb) + { + OrmLiteConfig.BeforeExecFilter = null; + return StringBuilderCache.ReturnAndFree(sb); + } public static ModelDefinition GetModelDefinition(Type modelType) { return modelType.GetModelDefinition(); } - public static bool HandledDbNullValue(FieldDefinition fieldDef, IDataReader dataReader, int colIndex, object instance) + public static ulong ConvertToULong(byte[] bytes) + { + Array.Reverse(bytes); //Correct Endianness + var ulongValue = BitConverter.ToUInt64(bytes, 0); + return ulongValue; + } + + public static List Merge(this Parent parent, List children) { - if (fieldDef == null || fieldDef.SetValueFn == null || colIndex == NotFound) return true; - if (dataReader.IsDBNull(colIndex)) + return new List { parent }.Merge(children); + } + + public static List Merge(this List parents, List children) + { + var modelDef = ModelDefinition.Definition; + + var hasChildRef = false; + + foreach (var fieldDef in modelDef.AllFieldDefinitionsArray) { - if (fieldDef.IsNullable) + if ((fieldDef.FieldType != typeof (Child) && fieldDef.FieldType != typeof (List)) || !fieldDef.IsReference) + continue; + + hasChildRef = true; + + var listInterface = fieldDef.FieldType.GetTypeWithGenericInterfaceOf(typeof(IList<>)); + if (listInterface != null) { - fieldDef.SetValueFn(instance, null); + var refType = listInterface.GetGenericArguments()[0]; + var refModelDef = refType.GetModelDefinition(); + var refField = modelDef.GetRefFieldDef(refModelDef, refType); + + SetListChildResults(parents, modelDef, fieldDef, refType, children, refField); } else { - fieldDef.SetValueFn(instance, fieldDef.FieldType.GetDefaultValue()); + var refType = fieldDef.FieldType; + + var refModelDef = refType.GetModelDefinition(); + + var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, fieldDef); + var refField = refSelf == null + ? modelDef.GetRefFieldDef(refModelDef, refType) + : modelDef.GetRefFieldDefIfExists(refModelDef); + + if (refSelf != null) + { + SetRefSelfChildResults(parents, fieldDef, refModelDef, refSelf, children); + } + else if (refField != null) + { + SetRefFieldChildResults(parents, modelDef, fieldDef, refField, children); + } } - return true; } - return false; + + if (!hasChildRef) + throw new Exception($"Could not find Child Reference for '{typeof(Child).Name}' on Parent '{typeof(Parent).Name}'"); + + return parents; } - public static ulong ConvertToULong(byte[] bytes) + internal static void SetListChildResults(List parents, ModelDefinition modelDef, + FieldDefinition fieldDef, Type refType, IList childResults, FieldDefinition refField) { - Array.Reverse(bytes); //Correct Endianness - var ulongValue = BitConverter.ToUInt64(bytes, 0); - return ulongValue; + var map = new Dictionary>(); + List refValues; + + foreach (var result in childResults) + { + var refValue = refField.GetValue(result); + if (!map.TryGetValue(refValue, out refValues)) + { + map[refValue] = refValues = new List(); + } + refValues.Add(result); + } + + var untypedApi = refType.CreateTypedApi(); + foreach (var result in parents) + { + var pkValue = modelDef.PrimaryKey.GetValue(result); + if (map.TryGetValue(pkValue, out refValues)) + { + var castResults = untypedApi.Cast(refValues); + fieldDef.SetValue(result, castResults); + } + } + } + + internal static void SetRefSelfChildResults(List parents, FieldDefinition fieldDef, ModelDefinition refModelDef, FieldDefinition refSelf, IList childResults) + { + var map = new Dictionary(); + foreach (var result in childResults) + { + var pkValue = refModelDef.PrimaryKey.GetValue(result); + map[pkValue] = result; + } + + foreach (var result in parents) + { + var fkValue = refSelf.GetValue(result); + if (fkValue != null && map.TryGetValue(fkValue, out var childResult)) + { + fieldDef.SetValue(result, childResult); + } + } + } + + internal static void SetRefFieldChildResults(List parents, ModelDefinition modelDef, + FieldDefinition fieldDef, FieldDefinition refField, IList childResults) + { + var map = new Dictionary(); + + foreach (var result in childResults) + { + var refValue = refField.GetValue(result); + map[refValue] = result; + } + + foreach (var result in parents) + { + var pkValue = modelDef.PrimaryKey.GetValue(result); + if (map.TryGetValue(pkValue, out var childResult)) + { + fieldDef.SetValue(result, childResult); + } + } + } + + [Obsolete("Use dialectProvider.GetNonDefaultValueInsertFields()")] + public static List GetNonDefaultValueInsertFields(T obj) + { + return OrmLiteConfig.DialectProvider.GetNonDefaultValueInsertFields(obj); + } + + public static void AssertNotAnonType() + { + if (typeof(T) == typeof(object)) + throw new ArgumentException("T generic argument should be a Table but was typeof(object)"); + + if (typeof(T) == typeof(Dictionary)) + throw new ArgumentException("T generic argument should be a Table but was typeof(Dictionary)"); + + if (typeof(ISqlExpression).IsAssignableFrom(typeof(T))) + throw new ArgumentException("T generic argument should be a Table but was an ISqlExpression"); + } + + public static List GetNonDefaultValueInsertFields(this IOrmLiteDialectProvider dialectProvider, object obj) + { + AssertNotAnonType(); + + var insertFields = new List(); + var modelDef = typeof(T).GetModelDefinition(); + foreach (var fieldDef in modelDef.FieldDefinitionsArray) + { + if (!string.IsNullOrEmpty(dialectProvider.GetDefaultValue(fieldDef))) + { + var value = fieldDef.GetValue(obj); + if (value == null || value.Equals(fieldDef.FieldTypeDefaultValue)) + continue; + } + insertFields.Add(fieldDef.Name); + } + + return insertFields.Count == modelDef.FieldDefinitionsArray.Length + ? null + : insertFields; + } + + public static List ParseTokens(this string expr) + { + var to = new List(); + + if (string.IsNullOrEmpty(expr)) + return to; + + var inDoubleQuotes = false; + var inSingleQuotes = false; + int inBracesCount = 0; + + var pos = 0; + + for (var i = 0; i < expr.Length; i++) + { + var c = expr[i]; + if (inDoubleQuotes) + { + if (c == '"') + inDoubleQuotes = false; + continue; + } + if (inSingleQuotes) + { + if (c == '\'') + inSingleQuotes = false; + continue; + } + if (c == '"') + { + inDoubleQuotes = true; + continue; + } + if (c == '\'') + { + inSingleQuotes = true; + continue; + } + if (c == '(') + { + inBracesCount++; + continue; + } + if (c == ')') + { + inBracesCount--; + if(inBracesCount > 0) + continue; + + var endPos = expr.IndexOf(',', i); + if (endPos == -1) + endPos = expr.Length; + + var arg = expr.Substring(pos, endPos - pos).Trim(); + if (!string.IsNullOrEmpty(arg)) + to.Add(arg); + + pos = endPos; + continue; + } + + if (c == ',') + { + if (inBracesCount == 0) + { + var arg = expr.Substring(pos, i - pos).Trim(); + if (!string.IsNullOrEmpty(arg)) + to.Add(arg); + pos = i + 1; + } + } + } + + var remaining = expr.Substring(pos, expr.Length - pos); + if (!string.IsNullOrEmpty(remaining)) + remaining = remaining.Trim(); + + if (!string.IsNullOrEmpty(remaining)) + to.Add(remaining); + + return to; + } + + public static string[] AllAnonFields(this Type type) + { + return type.GetPublicProperties().Select(x => x.Name).ToArray(); + } + + public static T EvalFactoryFn(this Expression> expr) + { + var factoryFn = (Func)CachedExpressionCompiler.Evaluate(expr); + var model = factoryFn(); + return model; + } + + public static JoinFormatDelegate JoinAlias(string alias) + { + return (dialect, tableDef, expr) => + $"{dialect.GetQuotedTableName(tableDef)} {alias} {expr.Replace(dialect.GetQuotedTableName(tableDef), dialect.GetQuotedTableName(alias))}"; + } + + /// + /// RDBMS Quoted string 'literal' + /// + /// + public static string QuotedLiteral(string text) => text == null || text.IndexOf('\'') >= 0 + ? text + : "'" + text + "'"; + + public static string UnquotedColumnName(string columnExpr) => columnExpr.LastRightPart('.').StripDbQuotes(); + + public static string OrderByFields(IOrmLiteDialectProvider dialect, string orderBy) + { + if (string.IsNullOrEmpty(orderBy)) + return string.Empty; + + var sb = StringBuilderCache.Allocate(); + + var fields = orderBy.Split(','); + const string Asc = ""; + const string Desc = " DESC"; + + var orderBySuffix = Asc; + foreach (var fieldName in fields) + { + if (sb.Length > 0) + sb.Append(", "); + + var reverse = fieldName.StartsWith("-"); + var useSuffix = reverse + ? orderBySuffix == Asc ? Desc : Asc + : orderBySuffix; + var useName = reverse ? fieldName.Substring(1) : fieldName; + var quotedName = dialect.GetQuotedColumnName(useName); + + sb.Append(quotedName + useSuffix); + } + return StringBuilderCache.ReturnAndFree(sb); } } -} \ No newline at end of file +} diff --git a/src/ServiceStack.OrmLite/OrmLiteVariables.cs b/src/ServiceStack.OrmLite/OrmLiteVariables.cs new file mode 100644 index 000000000..fbefa4c62 --- /dev/null +++ b/src/ServiceStack.OrmLite/OrmLiteVariables.cs @@ -0,0 +1,16 @@ +namespace ServiceStack.OrmLite +{ + public static class OrmLiteVariables + { + public const string SystemUtc = "{SYSTEM_UTC}"; + public const string MaxText = "{MAX_TEXT}"; + public const string MaxTextUnicode = "{NMAX_TEXT}"; + public const string True = "{TRUE}"; + public const string False = "{FALSE}"; + } + + public static class Messages + { + public const string LegacyApi = "API is deprecated and will move to ServiceStack.OrmLite.Legacy namespace in future release"; + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteWriteApi.cs b/src/ServiceStack.OrmLite/OrmLiteWriteApi.cs index 1206cceac..cfd82ac56 100644 --- a/src/ServiceStack.OrmLite/OrmLiteWriteApi.cs +++ b/src/ServiceStack.OrmLite/OrmLiteWriteApi.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Data; using System.Linq; +using System.Text; using ServiceStack.Data; +using ServiceStack.Text; namespace ServiceStack.OrmLite { @@ -14,8 +16,24 @@ public static class OrmLiteWriteApi /// public static string GetLastSql(this IDbConnection dbConn) { - var ormLiteConn = dbConn as OrmLiteConnection; - return ormLiteConn != null ? ormLiteConn.LastCommandText : null; + return dbConn is OrmLiteConnection ormLiteConn ? ormLiteConn.LastCommandText : null; + } + + public static string GetLastSqlAndParams(this IDbCommand dbCmd) + { + var sb = StringBuilderCache.Allocate(); + sb.AppendLine(dbCmd.CommandText) + .AppendLine("PARAMS: "); + + foreach (IDataParameter parameter in dbCmd.Parameters) + { + sb.Append(parameter.ParameterName).Append(": ") + .Append(parameter.Value.ToJsv()) + .Append(" : ").AppendLine((parameter.Value ?? DBNull.Value).GetType().Name); + } + sb.AppendLine(); + + return StringBuilderCache.ReturnAndFree(sb); } /// @@ -27,13 +45,105 @@ public static int ExecuteSql(this IDbConnection dbConn, string sql) return dbConn.Exec(dbCmd => dbCmd.ExecuteSql(sql)); } + /// + /// Execute any arbitrary raw SQL with db params. + /// + /// number of rows affected + public static int ExecuteSql(this IDbConnection dbConn, string sql, object dbParams) + { + return dbConn.Exec(dbCmd => dbCmd.ExecuteSql(sql, dbParams)); + } + + /// + /// Execute any arbitrary raw SQL with db params. + /// + /// number of rows affected + public static int ExecuteSql(this IDbConnection dbConn, string sql, Dictionary dbParams) + { + return dbConn.Exec(dbCmd => dbCmd.ExecuteSql(sql, dbParams)); + } + /// /// Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: /// var id = db.Insert(new Person { Id = 1, FirstName = "Jimi }, selectIdentity:true) /// - public static long Insert(this IDbConnection dbConn, T obj, bool selectIdentity = false) + public static long Insert(this IDbConnection dbConn, T obj, bool selectIdentity = false,bool enableIdentityInsert = false) + { + return dbConn.Exec(dbCmd => dbCmd.Insert(obj, commandFilter: null, selectIdentity: selectIdentity, enableIdentityInsert)); + } + + /// + /// Insert 1 POCO and modify populated IDbCommand with a commandFilter. E.g: + /// var id = db.Insert(new Person { Id = 1, FirstName = "Jimi }, dbCmd => applyFilter(dbCmd)) + /// + public static long Insert(this IDbConnection dbConn, T obj, Action commandFilter, bool selectIdentity = false) + { + return dbConn.Exec(dbCmd => dbCmd.Insert(obj, commandFilter: commandFilter, selectIdentity: selectIdentity)); + } + + /// + /// Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// var id = db.Insert(new Dictionary<string,object> { ["Id"] = 1, ["FirstName"] = "Jimi }, selectIdentity:true) + /// + public static long Insert(this IDbConnection dbConn, Dictionary obj, bool selectIdentity = false) + { + return dbConn.Exec(dbCmd => dbCmd.Insert(obj, commandFilter: null, selectIdentity: selectIdentity)); + } + + /// + /// Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// var id = db.Insert(new Dictionary<string,object> { ["Id"] = 1, ["FirstName"] = "Jimi }, dbCmd => applyFilter(dbCmd)) + /// + public static long Insert(this IDbConnection dbConn, Action commandFilter, Dictionary obj, bool selectIdentity = false) + { + return dbConn.Exec(dbCmd => dbCmd.Insert(obj, commandFilter: commandFilter, selectIdentity: selectIdentity)); + } + + /// + /// Insert 1 or more POCOs in a transaction using Table default values when defined. E.g: + /// db.InsertUsingDefaults(new Person { FirstName = "Tupac", LastName = "Shakur" }, + /// new Person { FirstName = "Biggie", LastName = "Smalls" }) + /// + public static void InsertUsingDefaults(this IDbConnection dbConn, params T[] objs) + { + dbConn.Exec(dbCmd => dbCmd.InsertUsingDefaults(objs)); + } + + /// + /// Insert results from SELECT SqlExpression, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// db.InsertIntoSelect<Contact>(db.From<Person>().Select(x => new { x.Id, Surname == x.LastName })) + /// + public static long InsertIntoSelect(this IDbConnection dbConn, ISqlExpression query) + { + return dbConn.Exec(dbCmd => dbCmd.InsertIntoSelect(query, commandFilter: null)); + } + + /// + /// Insert results from SELECT SqlExpression, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// db.InsertIntoSelect<Contact>(db.From<Person>().Select(x => new { x.Id, Surname == x.LastName })) + /// + public static long InsertIntoSelect(this IDbConnection dbConn, ISqlExpression query, Action commandFilter) + { + return dbConn.Exec(dbCmd => dbCmd.InsertIntoSelect(query, commandFilter: commandFilter)); + } + + /// + /// Insert a collection of POCOs in a transaction. E.g: + /// db.InsertAll(new[] { new Person { Id = 9, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }) + /// + public static void InsertAll(this IDbConnection dbConn, IEnumerable objs) { - return dbConn.Exec(dbCmd => dbCmd.Insert(obj, selectIdentity)); + dbConn.Exec(dbCmd => dbCmd.InsertAll(objs, commandFilter:null)); + } + + /// + /// Insert a collection of POCOs in a transaction and modify populated IDbCommand with a commandFilter. E.g: + /// db.InsertAll(new[] { new Person { Id = 9, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }, + /// dbCmd => applyFilter(dbCmd)) + /// + public static void InsertAll(this IDbConnection dbConn, IEnumerable objs, Action commandFilter) + { + dbConn.Exec(dbCmd => dbCmd.InsertAll(objs, commandFilter: commandFilter)); } /// @@ -43,25 +153,36 @@ public static long Insert(this IDbConnection dbConn, T obj, bool selectIdenti /// public static void Insert(this IDbConnection dbConn, params T[] objs) { - dbConn.Exec(dbCmd => dbCmd.Insert(objs)); + dbConn.Exec(dbCmd => dbCmd.Insert(commandFilter: null, objs: objs)); } /// - /// Insert a collection of POCOs in a transaction. E.g: - /// db.InsertAll(new[] { new Person { Id = 9, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }) + /// Insert 1 or more POCOs in a transaction and modify populated IDbCommand with a commandFilter. E.g: + /// db.Insert(dbCmd => applyFilter(dbCmd), + /// new Person { Id = 1, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, + /// new Person { Id = 2, FirstName = "Biggie", LastName = "Smalls", Age = 24 }) /// - public static void InsertAll(this IDbConnection dbConn, IEnumerable objs) + public static void Insert(this IDbConnection dbConn, Action commandFilter, params T[] objs) { - dbConn.Exec(dbCmd => dbCmd.InsertAll(objs)); + dbConn.Exec(dbCmd => dbCmd.Insert(commandFilter: commandFilter, objs: objs)); } /// /// Updates 1 POCO. All fields are updated except for the PrimaryKey which is used as the identity selector. E.g: /// db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) /// - public static int Update(this IDbConnection dbConn, T obj) + public static int Update(this IDbConnection dbConn, T obj, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.Update(obj)); + return dbConn.Exec(dbCmd => dbCmd.Update(obj, commandFilter)); + } + + /// + /// Updates 1 POCO. All fields are updated except for the PrimaryKey which is used as the identity selector. E.g: + /// db.Update(new Dictionary<string,object> { ["Id"] = 1, ["FirstName"] = "Jimi" }) + /// + public static int Update(this IDbConnection dbConn, Dictionary obj, Action commandFilter = null) + { + return dbConn.Exec(dbCmd => dbCmd.Update(obj, commandFilter)); } /// @@ -71,16 +192,20 @@ public static int Update(this IDbConnection dbConn, T obj) /// public static int Update(this IDbConnection dbConn, params T[] objs) { - return dbConn.Exec(dbCmd => dbCmd.Update(objs)); + return dbConn.Exec(dbCmd => dbCmd.Update(objs, commandFilter:null)); + } + public static int Update(this IDbConnection dbConn, Action commandFilter, params T[] objs) + { + return dbConn.Exec(dbCmd => dbCmd.Update(objs, commandFilter)); } /// /// Updates 1 or more POCOs in a transaction. E.g: /// db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }) /// - public static int UpdateAll(this IDbConnection dbConn, IEnumerable objs) + public static int UpdateAll(this IDbConnection dbConn, IEnumerable objs, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.UpdateAll(objs)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAll(objs, commandFilter)); } /// @@ -88,9 +213,19 @@ public static int UpdateAll(this IDbConnection dbConn, IEnumerable objs) /// db.Delete<Person>(new { FirstName = "Jimi", Age = 27 }) /// /// number of rows deleted - public static int Delete(this IDbConnection dbConn, object anonFilter) + public static int Delete(this IDbConnection dbConn, object anonFilter, Action commandFilter = null) + { + return dbConn.Exec(dbCmd => dbCmd.Delete(anonFilter, commandFilter)); + } + + /// + /// Delete rows using an Object Dictionary filters. E.g: + /// db.Delete<Person>(new Dictionary<string,object> { ["FirstName"] = "Jimi", ["Age"] = 27 }) + /// + /// number of rows deleted + public static int Delete(this IDbConnection dbConn, Dictionary filters) { - return dbConn.Exec(dbCmd => dbCmd.Delete(anonFilter)); + return dbConn.Exec(dbCmd => dbCmd.Delete(filters)); } /// @@ -98,9 +233,9 @@ public static int Delete(this IDbConnection dbConn, object anonFilter) /// db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) /// /// number of rows deleted - public static int Delete(this IDbConnection dbConn, T allFieldsFilter) + public static int Delete(this IDbConnection dbConn, T allFieldsFilter, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.Delete(allFieldsFilter)); + return dbConn.Exec(dbCmd => dbCmd.Delete(allFieldsFilter, commandFilter)); } /// @@ -138,20 +273,20 @@ public static int DeleteNonDefaults(this IDbConnection dbConn, params T[] non /// db.DeleteById<Person>(1) /// /// number of rows deleted - public static int DeleteById(this IDbConnection dbConn, object id) + public static int DeleteById(this IDbConnection dbConn, object id, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.DeleteById(id)); + return dbConn.Exec(dbCmd => dbCmd.DeleteById(id, commandFilter)); } /// /// Delete 1 row by the PrimaryKey where the rowVersion matches the optimistic concurrency field. - /// Will throw RowModefiedExeption if the + /// Will throw RowModifiedException if the /// row does not exist or has a different row version. /// E.g: db.DeleteById<Person>(1) /// - public static void DeleteById(this IDbConnection dbConn, object id, ulong rowVersion) + public static void DeleteById(this IDbConnection dbConn, object id, ulong rowVersion, Action commandFilter = null) { - dbConn.Exec(dbCmd => dbCmd.DeleteById(id, rowVersion)); + dbConn.Exec(dbCmd => dbCmd.DeleteById(id, rowVersion, commandFilter)); } /// @@ -174,6 +309,16 @@ public static int DeleteAll(this IDbConnection dbConn) return dbConn.Exec(dbCmd => dbCmd.DeleteAll()); } + /// + /// Delete all rows provided. E.g: + /// db.DeleteAll<Person>(people) + /// + /// number of rows deleted + public static int DeleteAll(this IDbConnection dbConn, IEnumerable rows) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteAll(rows)); + } + /// /// Delete all rows in the runtime table type. E.g: /// db.DeleteAll(typeof(Person)) @@ -186,21 +331,22 @@ public static int DeleteAll(this IDbConnection dbConn, Type tableType) /// /// Delete rows using a SqlFormat filter. E.g: + /// db.Delete<Person>("Age > @age", new { age = 42 }) /// /// number of rows deleted - public static int DeleteFmt(this IDbConnection dbConn, string sqlFilter, params object[] filterParams) + public static int Delete(this IDbConnection dbConn, string sqlFilter, object anonType) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(sqlFilter, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.Delete(sqlFilter, anonType)); } /// - /// Delete rows from the runtime table type using a SqlFormat filter. E.g: + /// Delete rows using a SqlFormat filter. E.g: + /// db.Delete(typeof(Person), "Age > @age", new { age = 42 }) /// - /// db.DeleteFmt(typeof(Person), "Age = {0}", 27) /// number of rows deleted - public static int DeleteFmt(this IDbConnection dbConn, Type tableType, string sqlFilter, params object[] filterParams) + public static int Delete(this IDbConnection dbConn, Type tableType, string sqlFilter, object anonType) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(tableType, sqlFilter, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.Delete(tableType, sqlFilter, anonType)); } /// @@ -214,11 +360,16 @@ public static bool Save(this IDbConnection dbConn, T obj, bool references = f if (!references) return dbConn.Exec(dbCmd => dbCmd.Save(obj)); + var trans = dbConn.OpenTransactionIfNotExists(); return dbConn.Exec(dbCmd => { - var ret = dbCmd.Save(obj); - dbCmd.SaveAllReferences(obj); - return ret; + using (trans) + { + var ret = dbCmd.Save(obj); + dbCmd.SaveAllReferences(obj); + trans?.Commit(); + return ret; + } }); } @@ -278,10 +429,36 @@ public static void SaveReferences(this IDbConnection dbConn, T instance dbConn.Exec(dbCmd => dbCmd.SaveReferences(instance, refs.ToArray())); } + public static object GetRowVersion(this IDbConnection dbConn, object id) + { + return dbConn.Exec(dbCmd => dbCmd.GetRowVersion(typeof(T).GetModelDefinition(), id)); + } + + public static object GetRowVersion(this IDbConnection dbConn, Type modelType, object id) + { + return dbConn.Exec(dbCmd => dbCmd.GetRowVersion(modelType.GetModelDefinition(), id)); + } + // Procedures public static void ExecuteProcedure(this IDbConnection dbConn, T obj) { dbConn.Exec(dbCmd => dbCmd.ExecuteProcedure(obj)); } + + /// + /// Generates inline UPDATE SQL Statement + /// + public static string ToUpdateStatement(this IDbConnection dbConn, T item, ICollection updateFields = null) + { + return dbConn.Exec(dbCmd => dbCmd.GetDialectProvider().ToUpdateStatement(dbCmd, item, updateFields)); + } + + /// + /// Generates inline INSERT SQL Statement + /// + public static string ToInsertStatement(this IDbConnection dbConn, T item, ICollection insertFields = null) + { + return dbConn.Exec(dbCmd => dbCmd.GetDialectProvider().ToInsertStatement(dbCmd, item, insertFields)); + } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteWriteApiAsync.cs b/src/ServiceStack.OrmLite/OrmLiteWriteApiAsync.cs index ee887ebf7..97051fde0 100644 --- a/src/ServiceStack.OrmLite/OrmLiteWriteApiAsync.cs +++ b/src/ServiceStack.OrmLite/OrmLiteWriteApiAsync.cs @@ -1,5 +1,5 @@ -#if NET45 -// Copyright (c) Service Stack LLC. All Rights Reserved. +#if ASYNC +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using ServiceStack.Data; +using ServiceStack.Text; namespace ServiceStack.OrmLite { @@ -19,50 +20,146 @@ public static class OrmLiteWriteApiAsync /// Execute any arbitrary raw SQL. /// /// number of rows affected - public static Task ExecuteSqlAsync(this IDbConnection dbConn, string sql, CancellationToken token = default(CancellationToken)) + public static Task ExecuteSqlAsync(this IDbConnection dbConn, string sql, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.ExecuteSqlAsync(sql, token)); } + /// + /// Execute any arbitrary raw SQL with db params. + /// + /// number of rows affected + public static Task ExecuteSqlAsync(this IDbConnection dbConn, string sql, object dbParams, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.ExecuteSqlAsync(sql, dbParams, token)); + } + + /// + /// Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// var id = db.Insert(new Person { Id = 1, FirstName = "Jimi }, selectIdentity:true) + /// + public static Task InsertAsync(this IDbConnection dbConn, T obj, bool selectIdentity = false, + bool enableIdentityInsert =false,CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.InsertAsync(obj, commandFilter: null, selectIdentity: selectIdentity, enableIdentityInsert,token: token)); + } + /// /// Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: /// var id = db.Insert(new Person { Id = 1, FirstName = "Jimi }, selectIdentity:true) /// - public static Task InsertAsync(this IDbConnection dbConn, T obj, bool selectIdentity = false, CancellationToken token = default(CancellationToken)) + public static Task InsertAsync(this IDbConnection dbConn, T obj, Action commandFilter, bool selectIdentity = false, bool enableIdentityInsert = false, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.InsertAsync(obj, commandFilter: commandFilter, selectIdentity: selectIdentity, enableIdentityInsert, token: token)); + } + + /// + /// Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// var id = db.Insert(new Dictionary<string,object> { ["Id"] = 1, ["FirstName"] = "Jimi }, selectIdentity:true) + /// + public static Task InsertAsync(this IDbConnection dbConn, Dictionary obj, bool selectIdentity = false, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.InsertAsync(obj, selectIdentity, token)); + return dbConn.Exec(dbCmd => dbCmd.InsertAsync(obj, commandFilter: null, selectIdentity: selectIdentity, token)); + } + + /// + /// Insert 1 POCO, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// var id = db.Insert(new Dictionary<string,object> { ["Id"] = 1, ["FirstName"] = "Jimi }, dbCmd => applyFilter(dbCmd)) + /// + public static Task InsertAsync(this IDbConnection dbConn, Action commandFilter, Dictionary obj, bool selectIdentity = false, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.InsertAsync(obj, commandFilter: commandFilter, selectIdentity: selectIdentity, token)); } /// /// Insert 1 or more POCOs in a transaction. E.g: - /// db.Insert(new Person { Id = 1, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, - /// new Person { Id = 2, FirstName = "Biggie", LastName = "Smalls", Age = 24 }) + /// db.InsertAsync(new Person { Id = 1, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, + /// new Person { Id = 2, FirstName = "Biggie", LastName = "Smalls", Age = 24 }) /// public static Task InsertAsync(this IDbConnection dbConn, CancellationToken token, params T[] objs) { - return dbConn.Exec(dbCmd => dbCmd.InsertAsync(token, objs)); + return dbConn.Exec(dbCmd => dbCmd.InsertAsync(commandFilter:null, token:token, objs:objs)); } public static Task InsertAsync(this IDbConnection dbConn, params T[] objs) { - return dbConn.Exec(dbCmd => dbCmd.InsertAsync(default(CancellationToken), objs)); + return dbConn.Exec(dbCmd => dbCmd.InsertAsync(commandFilter:null, token:default(CancellationToken), objs:objs)); + } + + /// + /// Insert 1 or more POCOs in a transaction and modify populated IDbCommand with a commandFilter. E.g: + /// db.InsertAsync(dbCmd => applyFilter(dbCmd), token, + /// new Person { Id = 1, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, + /// new Person { Id = 2, FirstName = "Biggie", LastName = "Smalls", Age = 24 }) + /// + public static Task InsertAsync(this IDbConnection dbConn, Action commandFilter, CancellationToken token, params T[] objs) + { + return dbConn.Exec(dbCmd => dbCmd.InsertAsync(commandFilter:commandFilter, token:token, objs:objs)); + } + + /// + /// Insert 1 or more POCOs in a transaction using Table default values when defined. E.g: + /// db.InsertUsingDefaultsAsync(new Person { FirstName = "Tupac", LastName = "Shakur" }, + /// new Person { FirstName = "Biggie", LastName = "Smalls" }) + /// + public static Task InsertUsingDefaultsAsync(this IDbConnection dbConn, T[] objs, CancellationToken token=default(CancellationToken)) + { + return dbConn.Exec(dbCmd => dbCmd.InsertUsingDefaultsAsync(objs, token)); + } + + /// + /// Insert results from SELECT SqlExpression, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// db.InsertIntoSelectAsync<Contact>(db.From<Person>().Select(x => new { x.Id, Surname == x.LastName })) + /// + public static Task InsertIntoSelectAsync(this IDbConnection dbConn, ISqlExpression query, CancellationToken token=default(CancellationToken)) + { + return dbConn.Exec(dbCmd => dbCmd.InsertIntoSelectAsync(query, commandFilter: null, token:token)); + } + + /// + /// Insert results from SELECT SqlExpression, use selectIdentity to retrieve the last insert AutoIncrement id (if any). E.g: + /// db.InsertIntoSelectAsync<Contact>(db.From<Person>().Select(x => new { x.Id, Surname == x.LastName })) + /// + public static Task InsertIntoSelectAsync(this IDbConnection dbConn, ISqlExpression query, Action commandFilter, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.InsertIntoSelectAsync(query, commandFilter: commandFilter, token:token)); } + /// /// Insert a collection of POCOs in a transaction. E.g: - /// db.InsertAll(new[] { new Person { Id = 9, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }) + /// db.InsertAllAsync(new[] { new Person { Id = 9, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }) + /// + public static Task InsertAllAsync(this IDbConnection dbConn, IEnumerable objs, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.InsertAllAsync(objs, commandFilter:null, token:token)); + } + + /// + /// Insert a collection of POCOs in a transaction and modify populated IDbCommand with a commandFilter. E.g: + /// db.InsertAllAsync(new[] { new Person { Id = 9, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }, + /// dbCmd => applyFilter(dbCmd)) /// - public static Task InsertAllAsync(this IDbConnection dbConn, IEnumerable objs, CancellationToken token = default(CancellationToken)) + public static Task InsertAllAsync(this IDbConnection dbConn, IEnumerable objs, Action commandFilter, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.InsertAllAsync(objs, token)); + return dbConn.Exec(dbCmd => dbCmd.InsertAllAsync(objs, commandFilter:commandFilter, token:token)); } /// /// Updates 1 POCO. All fields are updated except for the PrimaryKey which is used as the identity selector. E.g: /// db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) /// - public static Task UpdateAsync(this IDbConnection dbConn, T obj, CancellationToken token = default(CancellationToken)) + public static Task UpdateAsync(this IDbConnection dbConn, T obj, Action commandFilter = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(obj, token, commandFilter)); + } + + /// + /// Updates 1 POCO. All fields are updated except for the PrimaryKey which is used as the identity selector. E.g: + /// db.Update(new Dictionary<string,object> { ["Id"] = 1, ["FirstName"] = "Jimi", ["Age"] = 27 }) + /// + public static Task UpdateAsync(this IDbConnection dbConn, Dictionary obj, Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(obj, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(obj, token, commandFilter)); } /// @@ -72,68 +169,91 @@ public static Task InsertAsync(this IDbConnection dbConn, params T[] objs) /// public static Task UpdateAsync(this IDbConnection dbConn, CancellationToken token, params T[] objs) { - return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(objs, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(commandFilter:null, token: token, objs: objs)); } public static Task UpdateAsync(this IDbConnection dbConn, params T[] objs) { - return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(default(CancellationToken), objs)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(commandFilter: null, token:default, objs: objs)); + } + public static Task UpdateAsync(this IDbConnection dbConn, Action commandFilter, CancellationToken token, params T[] objs) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(commandFilter: commandFilter, token: token, objs: objs)); + } + public static Task UpdateAsync(this IDbConnection dbConn, Action commandFilter, params T[] objs) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(commandFilter: commandFilter, token:default, objs: objs)); } /// /// Updates 1 or more POCOs in a transaction. E.g: - /// db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }) + /// db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }) /// - public static Task UpdateAllAsync(this IDbConnection dbConn, IEnumerable objs, CancellationToken token = default(CancellationToken)) + public static Task UpdateAllAsync(this IDbConnection dbConn, IEnumerable objs, Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateAllAsync(objs, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAllAsync(objs, commandFilter, token)); } /// /// Delete rows using an anonymous type filter. E.g: - /// db.Delete<Person>(new { FirstName = "Jimi", Age = 27 }) + /// db.DeleteAsync<Person>(new { FirstName = "Jimi", Age = 27 }) /// /// number of rows deleted - public static Task DeleteAsync(this IDbConnection dbConn, object anonFilter, CancellationToken token = default(CancellationToken)) + public static Task DeleteAsync(this IDbConnection dbConn, object anonFilter, + Action commandFilter = null, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(anonFilter, token)); } /// - /// Delete 1 row using all fields in the filter. E.g: - /// db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) + /// Delete rows using an Object Dictionary filters. E.g: + /// db.DeleteAsync<Person>(new Dictionary<string,object> { ["FirstName"] = "Jimi", ["Age"] = 27 }) + /// + /// number of rows deleted + public static Task DeleteAsync(this IDbConnection dbConn, Dictionary filters, + Action commandFilter = null, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(filters, token)); + } + + /// + /// Delete 1 row using all fields in the commandFilter. E.g: + /// db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) /// /// number of rows deleted - public static Task DeleteAsync(this IDbConnection dbConn, T allFieldsFilter, CancellationToken token = default(CancellationToken)) + public static Task DeleteAsync(this IDbConnection dbConn, T allFieldsFilter, + Action commandFilter = null, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(allFieldsFilter, token)); } /// - /// Delete 1 or more rows in a transaction using all fields in the filter. E.g: - /// db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) + /// Delete 1 or more rows in a transaction using all fields in the commandFilter. E.g: + /// db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }) /// - public static Task DeleteAsync(this IDbConnection dbConn, CancellationToken token = default(CancellationToken), params T[] allFieldsFilters) + public static Task DeleteAsync(this IDbConnection dbConn, + Action commandFilter = null, CancellationToken token = default, params T[] allFieldsFilters) { return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(token, allFieldsFilters)); } - public static Task DeleteAsync(this IDbConnection dbConn, params T[] allFieldsFilters) + public static Task DeleteAsync(this IDbConnection dbConn, + Action commandFilter = null, params T[] allFieldsFilters) { - return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(default(CancellationToken), allFieldsFilters)); + return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(default, allFieldsFilters)); } /// - /// Delete 1 or more rows using only field with non-default values in the filter. E.g: - /// db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }) + /// Delete 1 or more rows using only field with non-default values in the commandFilter. E.g: + /// db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }) /// /// number of rows deleted - public static Task DeleteNonDefaultsAsync(this IDbConnection dbConn, T nonDefaultsFilter, CancellationToken token = default(CancellationToken)) + public static Task DeleteNonDefaultsAsync(this IDbConnection dbConn, T nonDefaultsFilter, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.DeleteNonDefaultsAsync(nonDefaultsFilter, token)); } /// - /// Delete 1 or more rows in a transaction using only field with non-default values in the filter. E.g: - /// db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }, + /// Delete 1 or more rows in a transaction using only field with non-default values in the commandFilter. E.g: + /// db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, /// new Person { FirstName = "Janis", Age = 27 }) /// /// number of rows deleted @@ -143,85 +263,79 @@ public static Task DeleteNonDefaultsAsync(this IDbConnection dbConn, Can } public static Task DeleteNonDefaultsAsync(this IDbConnection dbConn, params T[] nonDefaultsFilters) { - return dbConn.Exec(dbCmd => dbCmd.DeleteNonDefaultsAsync(default(CancellationToken), nonDefaultsFilters)); + return dbConn.Exec(dbCmd => dbCmd.DeleteNonDefaultsAsync(default, nonDefaultsFilters)); } /// /// Delete 1 row by the PrimaryKey. E.g: - /// db.DeleteById<Person>(1) + /// db.DeleteByIdAsync<Person>(1) /// /// number of rows deleted - public static Task DeleteByIdAsync(this IDbConnection dbConn, object id, CancellationToken token = default(CancellationToken)) + public static Task DeleteByIdAsync(this IDbConnection dbConn, object id, + Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync(id, token)); + return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync(id, commandFilter, token)); } /// /// Delete 1 row by the PrimaryKey where the rowVersion matches the optimistic concurrency field. - /// Will throw RowModefiedExeption if the + /// Will throw RowModifiedException if the /// row does not exist or has a different row version. - /// E.g: db.DeleteById<Person>(1) + /// E.g: db.DeleteByIdAsync<Person>(1) /// - public static Task DeleteByIdAsync(this IDbConnection dbConn, object id, ulong rowVersion, CancellationToken token = default(CancellationToken)) + public static Task DeleteByIdAsync(this IDbConnection dbConn, object id, ulong rowVersion, + Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync(id, rowVersion, token)); + return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync(id, rowVersion, commandFilter, token)); } /// /// Delete all rows identified by the PrimaryKeys. E.g: - /// db.DeleteById<Person>(new[] { 1, 2, 3 }) + /// db.DeleteByIdsAsync<Person>(new[] { 1, 2, 3 }) /// /// number of rows deleted - public static Task DeleteByIdsAsync(this IDbConnection dbConn, IEnumerable idValues, CancellationToken token = default(CancellationToken)) + public static Task DeleteByIdsAsync(this IDbConnection dbConn, IEnumerable idValues, + Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteByIdsAsync(idValues, token)); + return dbConn.Exec(dbCmd => dbCmd.DeleteByIdsAsync(idValues, commandFilter, token)); } /// /// Delete all rows in the generic table type. E.g: - /// db.DeleteAll<Person>() + /// db.DeleteAllAsync<Person>() /// /// number of rows deleted - public static Task DeleteAllAsync(this IDbConnection dbConn, CancellationToken token = default(CancellationToken)) + public static Task DeleteAllAsync(this IDbConnection dbConn, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.DeleteAllAsync(token)); } /// /// Delete all rows in the runtime table type. E.g: - /// db.DeleteAll(typeof(Person)) + /// db.DeleteAllAsync(typeof(Person)) /// /// number of rows deleted - public static Task DeleteAll(this IDbConnection dbConn, Type tableType, CancellationToken token = default(CancellationToken)) + public static Task DeleteAllAsync(this IDbConnection dbConn, Type tableType, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.DeleteAllAsync(tableType, token)); } /// - /// Delete rows using a SqlFormat filter. E.g: + /// Delete rows using sqlfilter, e.g: + /// db.DeleteAsync<Person>("FirstName = @FirstName AND Age = @Age", new { FirstName = "Jimi", Age = 27 }) /// - /// number of rows deleted - public static Task DeleteFmtAsync(this IDbConnection dbConn, CancellationToken token, string sqlFilter, params object[] filterParams) - { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(token, sqlFilter, filterParams)); - } - public static Task DeleteFmtAsync(this IDbConnection dbConn, string sqlFilter, params object[] filterParams) + public static Task DeleteAsync(this IDbConnection dbConn, string sqlFilter, object anonType, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(default(CancellationToken), sqlFilter, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(sqlFilter, anonType, token)); } /// - /// Delete rows from the runtime table type using a SqlFormat filter. E.g: + /// Delete rows using sqlfilter and Runtime Type, e.g: + /// db.DeleteAsync(typeof(Person), "FirstName = @FirstName AND Age = @Age", new { FirstName = "Jimi", Age = 27 }) /// - /// db.DeleteFmt(typeof(Person), "Age = {0}", 27) - /// number of rows deleted - public static Task DeleteFmtAsync(this IDbConnection dbConn, CancellationToken token, Type tableType, string sqlFilter, params object[] filterParams) - { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(token, tableType, sqlFilter, filterParams)); - } - public static Task DeleteFmtAsync(this IDbConnection dbConn, Type tableType, string sqlFilter, params object[] filterParams) + public static Task DeleteAsync(this IDbConnection dbConn, Type tableType, string sqlFilter, object anonType, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(default(CancellationToken), tableType, sqlFilter, filterParams)); + return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(tableType, sqlFilter, anonType, token)); } /// @@ -230,15 +344,22 @@ public static Task DeleteFmtAsync(this IDbConnection dbConn, Type tableType /// db.SaveAsync(customer, references:true) /// /// true if a row was inserted; false if it was updated - public static Task SaveAsync(this IDbConnection dbConn, T obj, bool references = false, CancellationToken token = default(CancellationToken)) + public static async Task SaveAsync(this IDbConnection dbConn, T obj, bool references = false, CancellationToken token = default) { if (!references) - return dbConn.Exec(dbCmd => dbCmd.SaveAsync(obj, token)); + return await dbConn.Exec(dbCmd => dbCmd.SaveAsync(obj, token)).ConfigAwait(); - return dbConn.Exec(dbCmd => - dbCmd.SaveAsync(obj, token).Then(ret => - dbCmd.SaveAllReferencesAsync(obj, token).Then(t => - ret))) as Task; + var trans = dbConn.OpenTransactionIfNotExists(); + return await dbConn.Exec(async dbCmd => + { + using (trans) + { + var ret = await dbCmd.SaveAsync(obj, token).ConfigAwait(); + await dbCmd.SaveAllReferencesAsync(obj, token).ConfigAwait(); + trans?.Commit(); + return ret; + } + }).ConfigAwait(); } /// @@ -260,7 +381,7 @@ public static Task SaveAsync(this IDbConnection dbConn, params T[] objs) /// db.SaveAllAsync(new [] { new Person { Id = 10, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }) /// /// number of rows added - public static Task SaveAllAsync(this IDbConnection dbConn, IEnumerable objs, CancellationToken token = default(CancellationToken)) + public static Task SaveAllAsync(this IDbConnection dbConn, IEnumerable objs, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.SaveAllAsync(objs, token)); } @@ -305,8 +426,18 @@ public static Task SaveReferencesAsync(this IDbConnection dbConn, T ins return dbConn.Exec(dbCmd => dbCmd.SaveReferencesAsync(token, instance, refs.ToArray())); } + public static Task GetRowVersionAsync(this IDbConnection dbConn, object id, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.GetRowVersionAsync(typeof(T).GetModelDefinition(), id, token)); + } + + public static Task GetRowVersionAsync(this IDbConnection dbConn, Type modelType, object id, CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.GetRowVersionAsync(modelType.GetModelDefinition(), id, token)); + } + // Procedures - public static Task ExecuteProcedureAsync(this IDbConnection dbConn, T obj, CancellationToken token = default(CancellationToken)) + public static Task ExecuteProcedureAsync(this IDbConnection dbConn, T obj, CancellationToken token = default) { return dbConn.Exec(dbCmd => dbCmd.ExecuteProcedureAsync(obj, token)); } diff --git a/src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs b/src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs index f3fc19787..dc04b20f6 100644 --- a/src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs +++ b/src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs @@ -4,7 +4,7 @@ // Authors: // Demis Bellot (demis.bellot@gmail.com) // -// Copyright 2013 Service Stack LLC. All Rights Reserved. +// Copyright 2013 ServiceStack, Inc. All Rights Reserved. // // Licensed under the same terms of ServiceStack. // @@ -14,20 +14,50 @@ using System.Collections.Generic; using System.Data; using System.Linq; -using System.Text; -using System.Text.RegularExpressions; using ServiceStack.Data; +using ServiceStack.DataAnnotations; using ServiceStack.Logging; +using ServiceStack.OrmLite.Converters; +using ServiceStack.Text; namespace ServiceStack.OrmLite { public static class OrmLiteWriteCommandExtensions { - private static readonly ILog Log = LogManager.GetLogger(typeof(OrmLiteWriteCommandExtensions)); + internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteWriteCommandExtensions)); - private static void LogDebug(string fmt) + internal static bool CreateSchema(this IDbCommand dbCmd) { - Log.Debug(fmt); + var schemaName = typeof(T).FirstAttribute()?.Name; + if(schemaName == null) throw new InvalidOperationException($"Type {typeof(T).Name} does not have a schema attribute, just CreateSchema(string schemaName) instead"); + return CreateSchema(dbCmd, schemaName); + } + + internal static bool CreateSchema(this IDbCommand dbCmd, string schemaName) + { + schemaName.ThrowIfNullOrEmpty(nameof(schemaName)); + var dialectProvider = dbCmd.GetDialectProvider(); + var schema = dialectProvider.NamingStrategy.GetSchemaName(schemaName); + var schemaExists = dialectProvider.DoesSchemaExist(dbCmd, schema); + if (schemaExists) + { + return true; + } + + try + { + ExecuteSql(dbCmd, dialectProvider.ToCreateSchemaStatement(schema)); + return true; + } + catch (Exception ex) + { + if (IgnoreAlreadyExistsError(ex)) + { + Log.DebugFormat("Ignoring existing schema '{0}': {1}", schema, ex.Message); + return false; + } + throw; + } } internal static void CreateTables(this IDbCommand dbCmd, bool overwrite, params Type[] tableTypes) @@ -38,13 +68,13 @@ internal static void CreateTables(this IDbCommand dbCmd, bool overwrite, params } } - internal static void CreateTable(this IDbCommand dbCmd, bool overwrite = false) + internal static bool CreateTable(this IDbCommand dbCmd, bool overwrite = false) { var tableType = typeof(T); - CreateTable(dbCmd, overwrite, tableType); + return CreateTable(dbCmd, overwrite, tableType); } - internal static void CreateTable(this IDbCommand dbCmd, bool overwrite, Type modelType) + internal static bool CreateTable(this IDbCommand dbCmd, bool overwrite, Type modelType) { var modelDef = modelType.GetModelDefinition(); @@ -54,11 +84,6 @@ internal static void CreateTable(this IDbCommand dbCmd, bool overwrite, Type mod var tableExists = dialectProvider.DoesTableExist(dbCmd, tableName, schema); if (overwrite && tableExists) { - if (modelDef.PreDropTableSql != null) - { - ExecuteSql(dbCmd, modelDef.PreDropTableSql); - } - DropTable(dbCmd, modelDef); var postDropTableSql = dialectProvider.ToPostDropTableStatement(modelDef); @@ -67,11 +92,6 @@ internal static void CreateTable(this IDbCommand dbCmd, bool overwrite, Type mod ExecuteSql(dbCmd, postDropTableSql); } - if (modelDef.PostDropTableSql != null) - { - ExecuteSql(dbCmd, modelDef.PostDropTableSql); - } - tableExists = false; } @@ -84,37 +104,7 @@ internal static void CreateTable(this IDbCommand dbCmd, bool overwrite, Type mod ExecuteSql(dbCmd, modelDef.PreCreateTableSql); } - ExecuteSql(dbCmd, dialectProvider.ToCreateTableStatement(modelType)); - - var postCreateTableSql = dialectProvider.ToPostCreateTableStatement(modelDef); - if (postCreateTableSql != null) - { - ExecuteSql(dbCmd, postCreateTableSql); - } - - if (modelDef.PostCreateTableSql != null) - { - ExecuteSql(dbCmd, modelDef.PostCreateTableSql); - } - - var sqlIndexes = dialectProvider.ToCreateIndexStatements(modelType); - foreach (var sqlIndex in sqlIndexes) - { - try - { - dbCmd.ExecuteSql(sqlIndex); - } - catch (Exception exIndex) - { - if (IgnoreAlreadyExistsError(exIndex)) - { - Log.DebugFormat("Ignoring existing index '{0}': {1}", sqlIndex, exIndex.Message); - continue; - } - throw; - } - } - + // sequences must be created before tables var sequenceList = dialectProvider.SequenceList(modelType); if (sequenceList.Count > 0) { @@ -132,7 +122,6 @@ internal static void CreateTable(this IDbCommand dbCmd, bool overwrite, Type mod var sequences = dialectProvider.ToCreateSequenceStatements(modelType); foreach (var seq in sequences) { - try { dbCmd.ExecuteSql(seq); @@ -144,10 +133,46 @@ internal static void CreateTable(this IDbCommand dbCmd, bool overwrite, Type mod Log.DebugFormat("Ignoring existing generator '{0}': {1}", seq, ex.Message); continue; } + throw; } } } + + var createTableSql = dialectProvider.ToCreateTableStatement(modelType); + ExecuteSql(dbCmd, createTableSql); + + var postCreateTableSql = dialectProvider.ToPostCreateTableStatement(modelDef); + if (postCreateTableSql != null) + { + ExecuteSql(dbCmd, postCreateTableSql); + } + + if (modelDef.PostCreateTableSql != null) + { + ExecuteSql(dbCmd, modelDef.PostCreateTableSql); + } + + var sqlIndexes = dialectProvider.ToCreateIndexStatements(modelType); + foreach (var sqlIndex in sqlIndexes) + { + try + { + dbCmd.ExecuteSql(sqlIndex); + } + catch (Exception exIndex) + { + if (IgnoreAlreadyExistsError(exIndex)) + { + Log.DebugFormat("Ignoring existing index '{0}': {1}", sqlIndex, exIndex.Message); + continue; + } + + throw; + } + } + + return true; } } catch (Exception ex) @@ -155,10 +180,13 @@ internal static void CreateTable(this IDbCommand dbCmd, bool overwrite, Type mod if (IgnoreAlreadyExistsError(ex)) { Log.DebugFormat("Ignoring existing table '{0}': {1}", modelDef.ModelName, ex.Message); - return; + return false; } + throw; } + + return false; } internal static void DropTable(this IDbCommand dbCmd) @@ -219,17 +247,41 @@ internal static string LastSql(this IDbCommand dbCmd) return dbCmd.CommandText; } - internal static int ExecuteSql(this IDbCommand dbCmd, string sql) + internal static int ExecuteSql(this IDbCommand dbCmd, string sql, IEnumerable sqlParams = null, Action commandFilter = null) { + dbCmd.CommandText = sql; + + dbCmd.SetParameters(sqlParams); + + commandFilter?.Invoke(dbCmd); + if (Log.IsDebugEnabled) - LogDebug(sql); + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + + if (OrmLiteConfig.ResultsFilter != null) + return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd); + + return dbCmd.ExecuteNonQuery(); + } + + internal static int ExecuteSql(this IDbCommand dbCmd, string sql, object anonType, Action commandFilter = null) + { + if (anonType != null) + dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql); dbCmd.CommandText = sql; + commandFilter?.Invoke(dbCmd); + + if (Log.IsDebugEnabled) + Log.DebugCommand(dbCmd); + + OrmLiteConfig.BeforeExecFilter?.Invoke(dbCmd); + if (OrmLiteConfig.ResultsFilter != null) - { return OrmLiteConfig.ResultsFilter.ExecuteSql(dbCmd); - } return dbCmd.ExecuteNonQuery(); } @@ -246,159 +298,133 @@ private static bool IgnoreAlreadyExistsError(Exception ex) private static bool IgnoreAlreadyExistsGeneratorError(Exception ex) { const string fbError = "attempt to store duplicate value"; - return ex.Message.Contains(fbError); + const string fbAlreadyExistsError = "already exists"; + return ex.Message.Contains(fbError) || ex.Message.Contains(fbAlreadyExistsError); } - public static T PopulateWithSqlReader(this T objWithProperties, IOrmLiteDialectProvider dialectProvider, IDataReader dataReader) + public static T PopulateWithSqlReader(this T objWithProperties, IOrmLiteDialectProvider dialectProvider, IDataReader reader) { - var fieldDefs = ModelDefinition.Definition.AllFieldDefinitionsArray; - - return PopulateWithSqlReader(objWithProperties, dialectProvider, dataReader, fieldDefs, null); + var indexCache = reader.GetIndexFieldsCache(ModelDefinition.Definition, dialectProvider); + var values = new object[reader.FieldCount]; + return PopulateWithSqlReader(objWithProperties, dialectProvider, reader, indexCache, values); } - public static int GetColumnIndex(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, string fieldName) + public static int GetColumnIndex(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, string fieldName) { try { - return dataReader.GetOrdinal(dialectProvider.NamingStrategy.GetColumnName(fieldName)); + return reader.GetOrdinal(dialectProvider.NamingStrategy.GetColumnName(fieldName)); } - catch (IndexOutOfRangeException ignoreNotFoundExInSomeProviders) + catch (IndexOutOfRangeException /*ignoreNotFoundExInSomeProviders*/) { return NotFound; } } - internal static int FindColumnIndex(this IDataReader dataReader, IOrmLiteDialectProvider dialectProvider, FieldDefinition fieldDef) - { - var index = NotFound; - index = dataReader.GetColumnIndex(dialectProvider, fieldDef.FieldName); - if (index == NotFound) - { - index = TryGuessColumnIndex(fieldDef.FieldName, dataReader); - } - // Try fallback to original field name when overriden by alias - if (index == NotFound && fieldDef.Alias != null && !OrmLiteConfig.DisableColumnGuessFallback) - { - index = dataReader.GetColumnIndex(dialectProvider, fieldDef.Name); - if (index == NotFound) - { - index = TryGuessColumnIndex(fieldDef.Name, dataReader); - } - } + private const int NotFound = -1; - return index; + public static T PopulateWithSqlReader(this T objWithProperties, + IOrmLiteDialectProvider dialectProvider, IDataReader reader, + Tuple[] indexCache, object[] values) + { + dialectProvider.PopulateObjectWithSqlReader(objWithProperties, reader, indexCache, values); + return objWithProperties; } - - private const int NotFound = -1; - public static T PopulateWithSqlReader(this T objWithProperties, IOrmLiteDialectProvider dialectProvider, IDataReader dataReader, FieldDefinition[] fieldDefs, Dictionary indexCache) + + public static void PopulateObjectWithSqlReader(this IOrmLiteDialectProvider dialectProvider, + object objWithProperties, IDataReader reader, + Tuple[] indexCache, object[] values) { - try + values = PopulateValues(reader, values, dialectProvider); + + var dbNullFilter = OrmLiteConfig.OnDbNullFilter; + + foreach (var fieldCache in indexCache) { - foreach (var fieldDef in fieldDefs) + try { - int index; - if (indexCache != null) + var fieldDef = fieldCache.Item1; + var index = fieldCache.Item2; + var converter = fieldCache.Item3; + + if (values != null && values[index] == DBNull.Value) { - if (!indexCache.TryGetValue(fieldDef.Name, out index)) - { - index = FindColumnIndex(dataReader, dialectProvider, fieldDef); + var value = fieldDef.IsNullable ? null : fieldDef.FieldTypeDefaultValue; + var useValue = dbNullFilter?.Invoke(fieldDef); + if (useValue != null) + value = useValue; - indexCache.Add(fieldDef.Name, index); - } + fieldDef.SetValue(objWithProperties, value); } else { - index = FindColumnIndex(dataReader, dialectProvider, fieldDef); + var value = converter.GetValue(reader, index, values); + if (value == null) + { + if (!fieldDef.IsNullable) + value = fieldDef.FieldTypeDefaultValue; + var useValue = dbNullFilter?.Invoke(fieldDef); + if (useValue != null) + value = useValue; + fieldDef.SetValue(objWithProperties, value); + } + else + { + var fieldValue = converter.FromDbValue(fieldDef.FieldType, value); + fieldDef.SetValue(objWithProperties, fieldValue); + } } - - dialectProvider.SetDbValue(fieldDef, dataReader, index, objWithProperties); + } + catch (Exception ex) + { + OrmLiteUtils.HandleException(ex); } } - catch (Exception ex) - { - Log.Error(ex); - } - return objWithProperties; + + OrmLiteConfig.PopulatedObjectFilter?.Invoke(objWithProperties); } - private static readonly Regex AllowedPropertyCharsRegex = new Regex(@"[^0-9a-zA-Z_]", - RegexOptions.Compiled | RegexOptions.CultureInvariant); - - private static int TryGuessColumnIndex(string fieldName, IDataReader dataReader) + internal static object[] PopulateValues(this IDataReader reader, object[] values, IOrmLiteDialectProvider dialectProvider) { - if (OrmLiteConfig.DisableColumnGuessFallback) - return NotFound; - - var fieldCount = dataReader.FieldCount; - for (var i = 0; i < fieldCount; i++) + if (!OrmLiteConfig.DeoptimizeReader) { - var dbFieldName = dataReader.GetName(i); + if (values == null) + values = new object[reader.FieldCount]; - // First guess: Maybe the DB field has underscores? (most common) - // e.g. CustomerId (C#) vs customer_id (DB) - var dbFieldNameWithNoUnderscores = dbFieldName.Replace("_", ""); - if (string.Compare(fieldName, dbFieldNameWithNoUnderscores, StringComparison.OrdinalIgnoreCase) == 0) + try { - return i; + dialectProvider.GetValues(reader, values); } - - // Next guess: Maybe the DB field has special characters? - // e.g. Quantity (C#) vs quantity% (DB) - var dbFieldNameSanitized = AllowedPropertyCharsRegex.Replace(dbFieldName, string.Empty); - if (string.Compare(fieldName, dbFieldNameSanitized, StringComparison.OrdinalIgnoreCase) == 0) + catch (Exception ex) { - return i; - } - - // Next guess: Maybe the DB field has special characters *and* has underscores? - // e.g. Quantity (C#) vs quantity_% (DB) - if (string.Compare(fieldName, dbFieldNameSanitized.Replace("_", string.Empty), StringComparison.OrdinalIgnoreCase) == 0) - { - return i; - } - - // Next guess: Maybe the DB field has some prefix that we don't have in our C# field? - // e.g. CustomerId (C#) vs t130CustomerId (DB) - if (dbFieldName.EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) - { - return i; - } - - // Next guess: Maybe the DB field has some prefix that we don't have in our C# field *and* has underscores? - // e.g. CustomerId (C#) vs t130_CustomerId (DB) - if (dbFieldNameWithNoUnderscores.EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) - { - return i; - } - - // Next guess: Maybe the DB field has some prefix that we don't have in our C# field *and* has special characters? - // e.g. CustomerId (C#) vs t130#CustomerId (DB) - if (dbFieldNameSanitized.EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) - { - return i; - } - - // Next guess: Maybe the DB field has some prefix that we don't have in our C# field *and* has underscores *and* has special characters? - // e.g. CustomerId (C#) vs t130#Customer_I#d (DB) - if (dbFieldNameSanitized.Replace("_", "").EndsWith(fieldName, StringComparison.OrdinalIgnoreCase)) - { - return i; - } - - // Cater for Naming Strategies like PostgreSQL that has lower_underscore names - if (dbFieldNameSanitized.Replace("_", "").EndsWith(fieldName.Replace("_", ""), StringComparison.OrdinalIgnoreCase)) - { - return i; + values = null; + Log.Warn("Error trying to use GetValues() from DataReader. Falling back to individual field reads...", ex); } } + else + { + //Calling GetValues() on System.Data.SQLite.Core ADO.NET Provider changes behavior of reader.GetGuid() + //So allow providers to by-pass reader.GetValues() optimization. + values = null; + } + return values; + } + + internal static int Update(this IDbCommand dbCmd, T obj, Action commandFilter = null) + { + return dbCmd.UpdateInternal(obj, commandFilter); + } - return NotFound; + internal static int Update(this IDbCommand dbCmd, Dictionary obj, Action commandFilter = null) + { + return dbCmd.UpdateInternal(obj, commandFilter); } - internal static int Update(this IDbCommand dbCmd, T obj) + internal static int UpdateInternal(this IDbCommand dbCmd, object obj, Action commandFilter = null) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, obj); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, obj.ToFilterType()); var dialectProvider = dbCmd.GetDialectProvider(); var hadRowVersion = dialectProvider.PrepareParameterizedUpdateStatement(dbCmd); @@ -407,6 +433,12 @@ internal static int Update(this IDbCommand dbCmd, T obj) dialectProvider.SetParameterValues(dbCmd, obj); + return dbCmd.UpdateAndVerify(commandFilter, hadRowVersion); + } + + internal static int UpdateAndVerify(this IDbCommand dbCmd, Action commandFilter, bool hadRowVersion) + { + commandFilter?.Invoke(dbCmd); var rowsUpdated = dbCmd.ExecNonQuery(); if (hadRowVersion && rowsUpdated == 0) @@ -415,13 +447,15 @@ internal static int Update(this IDbCommand dbCmd, T obj) return rowsUpdated; } - internal static int Update(this IDbCommand dbCmd, params T[] objs) + internal static int Update(this IDbCommand dbCmd, T[] objs, Action commandFilter = null) { - return dbCmd.UpdateAll(objs); + return dbCmd.UpdateAll(objs: objs, commandFilter: commandFilter); } - internal static int UpdateAll(this IDbCommand dbCmd, IEnumerable objs) + internal static int UpdateAll(this IDbCommand dbCmd, IEnumerable objs, Action commandFilter = null) { + OrmLiteUtils.AssertNotAnonType(); + IDbTransaction dbTrans = null; int count = 0; @@ -438,11 +472,13 @@ internal static int UpdateAll(this IDbCommand dbCmd, IEnumerable objs) foreach (var obj in objs) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, obj); + OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, obj); dialectProvider.SetParameterValues(dbCmd, obj); + commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once + commandFilter = null; + var rowsUpdated = dbCmd.ExecNonQuery(); if (hadRowVersion && rowsUpdated == 0) throw new OptimisticConcurrencyException(); @@ -450,13 +486,11 @@ internal static int UpdateAll(this IDbCommand dbCmd, IEnumerable objs) count += rowsUpdated; } - if (dbTrans != null) - dbTrans.Commit(); + dbTrans?.Commit(); } finally { - if (dbTrans != null) - dbTrans.Dispose(); + dbTrans?.Dispose(); } return count; @@ -471,12 +505,12 @@ private static int AssertRowsUpdated(IDbCommand dbCmd, bool hadRowVersion) return rowsUpdated; } - internal static int Delete(this IDbCommand dbCmd, T anonType) + internal static int Delete(this IDbCommand dbCmd, T anonType, Action commandFilter = null) { - return dbCmd.Delete((object)anonType); + return dbCmd.Delete((object)anonType, commandFilter); } - internal static int Delete(this IDbCommand dbCmd, object anonType) + internal static int Delete(this IDbCommand dbCmd, object anonType, Action commandFilter = null) { var dialectProvider = dbCmd.GetDialectProvider(); @@ -485,6 +519,8 @@ internal static int Delete(this IDbCommand dbCmd, object anonType) dialectProvider.SetParameterValues(dbCmd, anonType); + commandFilter?.Invoke(dbCmd); + return AssertRowsUpdated(dbCmd, hadRowVersion); } @@ -501,7 +537,8 @@ internal static int DeleteNonDefaults(this IDbCommand dbCmd, T filter) internal static int Delete(this IDbCommand dbCmd, T[] objs) { - if (objs.Length == 0) return 0; + if (objs.Length == 0) + return 0; return DeleteAll(dbCmd, objs); } @@ -513,8 +550,11 @@ internal static int DeleteNonDefaults(this IDbCommand dbCmd, T[] filters) return DeleteAll(dbCmd, filters, o => o.AllFieldsMap().NonDefaultsOnly()); } - private static int DeleteAll(IDbCommand dbCmd, IEnumerable objs, Func> fieldValuesFn=null) + private static int DeleteAll(IDbCommand dbCmd, IEnumerable objs, + Func> fieldValuesFn, Action commandFilter = null) { + OrmLiteUtils.AssertNotAnonType(); + IDbTransaction dbTrans = null; int count = 0; @@ -535,26 +575,27 @@ private static int DeleteAll(IDbCommand dbCmd, IEnumerable objs, Func(dbCmd, obj); + commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once + commandFilter = null; + count += dbCmd.ExecNonQuery(); } - if (dbTrans != null) - dbTrans.Commit(); + dbTrans?.Commit(); } finally { - if (dbTrans != null) - dbTrans.Dispose(); + dbTrans?.Dispose(); } return count; } - internal static int DeleteById(this IDbCommand dbCmd, object id) + internal static int DeleteById(this IDbCommand dbCmd, object id, Action commandFilter = null) { var sql = DeleteByIdSql(dbCmd, id); - return dbCmd.ExecuteSql(sql); + return dbCmd.ExecuteSql(sql, commandFilter: commandFilter); } internal static string DeleteByIdSql(this IDbCommand dbCmd, object id) @@ -563,10 +604,8 @@ internal static string DeleteByIdSql(this IDbCommand dbCmd, object id) var dialectProvider = dbCmd.GetDialectProvider(); var idParamString = dialectProvider.GetParam(); - var sql = string.Format("DELETE FROM {0} WHERE {1} = {2}", - dialectProvider.GetQuotedTableName(modelDef), - dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName), - idParamString); + var sql = $"DELETE FROM {dialectProvider.GetQuotedTableName(modelDef)} " + + $"WHERE {dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName)} = {idParamString}"; var idParam = dbCmd.CreateParameter(); idParam.ParameterName = idParamString; @@ -575,17 +614,19 @@ internal static string DeleteByIdSql(this IDbCommand dbCmd, object id) return sql; } - internal static void DeleteById(this IDbCommand dbCmd, object id, ulong rowVersion) + internal static void DeleteById(this IDbCommand dbCmd, object id, ulong rowVersion, Action commandFilter = null) { var sql = DeleteByIdSql(dbCmd, id, rowVersion); - var rowsAffected = dbCmd.ExecuteSql(sql); + var rowsAffected = dbCmd.ExecuteSql(sql, commandFilter: commandFilter); if (rowsAffected == 0) throw new OptimisticConcurrencyException("The row was modified or deleted since the last read"); } internal static string DeleteByIdSql(this IDbCommand dbCmd, object id, ulong rowVersion) { + OrmLiteUtils.AssertNotAnonType(); + var modelDef = ModelDefinition.Definition; var dialectProvider = dbCmd.GetDialectProvider(); @@ -603,23 +644,26 @@ internal static string DeleteByIdSql(this IDbCommand dbCmd, object id, ulong var rowVersionParam = dbCmd.CreateParameter(); rowVersionParam.ParameterName = dialectProvider.GetParam("rowVersion"); - rowVersionParam.Value = rowVersion; + var converter = dialectProvider.GetConverterBestMatch(typeof(RowVersionConverter)); + converter.InitDbParam(rowVersionParam, typeof(ulong)); + + rowVersionParam.Value = converter.ToDbValue(typeof(ulong), rowVersion); dbCmd.Parameters.Add(rowVersionParam); - var sql = string.Format("DELETE FROM {0} WHERE {1} = {2} AND {3} = {4}", - dialectProvider.GetQuotedTableName(modelDef), - dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName), - idParam.ParameterName, - dialectProvider.GetQuotedColumnName(rowVersionField.FieldName), - rowVersionParam.ParameterName); + var sql = $"DELETE FROM {dialectProvider.GetQuotedTableName(modelDef)} " + + $"WHERE {dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName)} = {idParam.ParameterName} " + + $"AND {dialectProvider.GetRowVersionColumn(rowVersionField)} = {rowVersionParam.ParameterName}"; return sql; } internal static int DeleteByIds(this IDbCommand dbCmd, IEnumerable idValues) { - var sqlIn = idValues.GetIdsInSql(); - if (sqlIn == null) return 0; + OrmLiteUtils.AssertNotAnonType(); + + var sqlIn = dbCmd.SetIdsInSqlParams(idValues); + if (string.IsNullOrEmpty(sqlIn)) + return 0; var sql = GetDeleteByIdsSql(sqlIn, dbCmd.GetDialectProvider()); @@ -630,55 +674,203 @@ internal static string GetDeleteByIdsSql(string sqlIn, IOrmLiteDialectProvide { var modelDef = ModelDefinition.Definition; - var sql = string.Format("DELETE FROM {0} WHERE {1} IN ({2})", - dialectProvider.GetQuotedTableName(modelDef), - dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName), - sqlIn); + var sql = $"DELETE FROM {dialectProvider.GetQuotedTableName(modelDef)} " + + $"WHERE {dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName)} IN ({sqlIn})"; return sql; } internal static int DeleteAll(this IDbCommand dbCmd) { + OrmLiteUtils.AssertNotAnonType(); + return DeleteAll(dbCmd, typeof(T)); } + internal static int DeleteAll(this IDbCommand dbCmd, IEnumerable rows) + { + var ids = rows.Map(x => x.GetId()); + return dbCmd.DeleteByIds(ids); + } + internal static int DeleteAll(this IDbCommand dbCmd, Type tableType) { return dbCmd.ExecuteSql(dbCmd.GetDialectProvider().ToDeleteStatement(tableType, null)); } - internal static int DeleteFmt(this IDbCommand dbCmd, string sqlFilter, params object[] filterParams) + internal static int Delete(this IDbCommand dbCmd, string sql, object anonType = null) { - return DeleteFmt(dbCmd, typeof(T), sqlFilter, filterParams); + OrmLiteUtils.AssertNotAnonType(); + + if (anonType != null) dbCmd.SetParameters(anonType, excludeDefaults: false, sql: ref sql); + return dbCmd.ExecuteSql(dbCmd.GetDialectProvider().ToDeleteStatement(typeof(T), sql)); } - internal static int DeleteFmt(this IDbCommand dbCmd, Type tableType, string sqlFilter, params object[] filterParams) + internal static int Delete(this IDbCommand dbCmd, Type tableType, string sql, object anonType = null) { - return dbCmd.ExecuteSql(dbCmd.GetDialectProvider().ToDeleteStatement(tableType, sqlFilter, filterParams)); + if (anonType != null) dbCmd.SetParameters(tableType, anonType, excludeDefaults: false, sql: ref sql); + return dbCmd.ExecuteSql(dbCmd.GetDialectProvider().ToDeleteStatement(tableType, sql)); } + + internal static long Insert(this IDbCommand dbCmd, T obj, Action commandFilter, bool selectIdentity = false, bool enableIdentityInsert=false) + { + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); + + var dialectProvider = dbCmd.GetDialectProvider(); + var pkField = ModelDefinition.Definition.FieldDefinitions.FirstOrDefault(f => f.IsPrimaryKey); + if (!enableIdentityInsert || pkField == null || !pkField.AutoIncrement) + { + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, + insertFields: dialectProvider.GetNonDefaultValueInsertFields(obj)); - internal static long Insert(this IDbCommand dbCmd, T obj, bool selectIdentity = false) + return InsertInternal(dialectProvider, dbCmd, obj, commandFilter, selectIdentity); + } + else + { + try + { + dialectProvider.EnableIdentityInsert(dbCmd); + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, + insertFields: dialectProvider.GetNonDefaultValueInsertFields(obj), + shouldInclude: f => f == pkField); + InsertInternal(dialectProvider, dbCmd, obj, commandFilter, selectIdentity); + if (selectIdentity) + { + var id = pkField.GetValue(obj); + return Convert.ToInt64(id); + } + return default; + } + finally + { + dialectProvider.DisableIdentityInsert(dbCmd); + } + } + } + + internal static long Insert(this IDbCommand dbCmd, Dictionary obj, Action commandFilter, bool selectIdentity = false) { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, obj); + OrmLiteUtils.AssertNotAnonType(); + + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj.ToFilterType()); var dialectProvider = dbCmd.GetDialectProvider(); - dialectProvider.PrepareParameterizedInsertStatement(dbCmd); + var pkField = ModelDefinition.Definition.PrimaryKey; + object id = null; + var enableIdentityInsert = pkField?.AutoIncrement == true && obj.TryGetValue(pkField.Name, out id); + + try + { + if (enableIdentityInsert) + dialectProvider.EnableIdentityInsert(dbCmd); + + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, + insertFields: dialectProvider.GetNonDefaultValueInsertFields(obj), + shouldInclude: f => obj.ContainsKey(f.Name)); + + var ret = InsertInternal(dialectProvider, dbCmd, obj, commandFilter, selectIdentity); + if (enableIdentityInsert) + return Convert.ToInt64(id); + return ret; + } + finally + { + if (enableIdentityInsert) + dialectProvider.DisableIdentityInsert(dbCmd); + } + } + + internal static void RemovePrimaryKeyWithDefaultValue(this Dictionary obj) + { + var pkField = typeof(T).GetModelDefinition().PrimaryKey; + if (pkField != null && (pkField.AutoIncrement || pkField.AutoId)) + { + // Don't insert Primary Key with Default Value + if (obj.TryGetValue(pkField.Name, out var idValue) && + idValue != null && !idValue.Equals(pkField.DefaultValue)) + { + obj.Remove(pkField.Name); + } + } + } + + private static long InsertInternal(IOrmLiteDialectProvider dialectProvider, IDbCommand dbCmd, object obj, Action commandFilter, bool selectIdentity) + { + OrmLiteUtils.AssertNotAnonType(); dialectProvider.SetParameterValues(dbCmd, obj); + commandFilter?.Invoke(dbCmd); //dbCmd.OnConflictInsert() needs to be applied before last insert id + + if (dialectProvider.HasInsertReturnValues(ModelDefinition.Definition)) + { + using var reader = dbCmd.ExecReader(dbCmd.CommandText); + return reader.PopulateReturnValues(dialectProvider, obj); + } + if (selectIdentity) - return dialectProvider.InsertAndGetLastInsertId(dbCmd); + { + dbCmd.CommandText += dialectProvider.GetLastInsertIdSqlSuffix(); + + return dbCmd.ExecLongScalar(); + } return dbCmd.ExecNonQuery(); } - internal static void Insert(this IDbCommand dbCmd, params T[] objs) + internal static long PopulateReturnValues(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, object obj) { - InsertAll(dbCmd, objs); + if (reader.Read()) + { + var modelDef = ModelDefinition.Definition; + var values = new object[reader.FieldCount]; + var indexCache = reader.GetIndexFieldsCache(modelDef, dialectProvider); + dialectProvider.PopulateObjectWithSqlReader(obj, reader, indexCache, values); + if ((modelDef.PrimaryKey != null) && (modelDef.PrimaryKey.AutoIncrement || modelDef.PrimaryKey.ReturnOnInsert)) + { + var id = modelDef.GetPrimaryKey(obj); + if (modelDef.PrimaryKey.AutoId) + return 1; + return Convert.ToInt64(id); + } + } + + return 0; + } + + internal static void Insert(this IDbCommand dbCmd, Action commandFilter, params T[] objs) + { + dbCmd.InsertAll(objs: objs, commandFilter: commandFilter); + } + + internal static long InsertIntoSelect(this IDbCommand dbCmd, ISqlExpression query, Action commandFilter) => + dbCmd.InsertIntoSelectInternal(query, commandFilter).ExecNonQuery(); + + internal static IDbCommand InsertIntoSelectInternal(this IDbCommand dbCmd, ISqlExpression query, Action commandFilter) + { + var dialectProvider = dbCmd.GetDialectProvider(); + + var sql = query.ToSelectStatement(QueryType.Select); + var selectFields = query.GetUntypedSqlExpression() + .SelectExpression + .Substring("SELECT ".Length) + .ParseCommands(); + + var fieldsOrAliases = selectFields + .Map(x => x.Original.ToString().AliasOrColumn()); + + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, insertFields: fieldsOrAliases); + + dbCmd.SetParameters(query.Params); + + dbCmd.CommandText = dbCmd.CommandText.LeftPart(")") + ")\n" + sql; + + commandFilter?.Invoke(dbCmd); //dbCmd.OnConflictInsert() needs to be applied before last insert id + return dbCmd; } - internal static void InsertAll(this IDbCommand dbCmd, IEnumerable objs) + internal static void InsertAll(this IDbCommand dbCmd, IEnumerable objs, Action commandFilter) { IDbTransaction dbTrans = null; @@ -693,21 +885,72 @@ internal static void InsertAll(this IDbCommand dbCmd, IEnumerable objs) foreach (var obj in objs) { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, obj); + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); + dialectProvider.SetParameterValues(dbCmd, obj); + + commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once + commandFilter = null; + try + { + dbCmd.ExecNonQuery(); + } + catch (Exception ex) + { + Log.Error($"SQL ERROR: {dbCmd.GetLastSqlAndParams()}", ex); + throw; + } + } + + dbTrans?.Commit(); + } + finally + { + dbTrans?.Dispose(); + } + } + + internal static void InsertUsingDefaults(this IDbCommand dbCmd, params T[] objs) + { + IDbTransaction dbTrans = null; + + try + { + if (dbCmd.Transaction == null) + dbCmd.Transaction = dbTrans = dbCmd.Connection.BeginTransaction(); + + var dialectProvider = dbCmd.GetDialectProvider(); + + var modelDef = typeof(T).GetModelDefinition(); + var fieldsWithoutDefaults = modelDef.FieldDefinitionsArray + .Where(x => x.DefaultValue == null) + .Select(x => x.Name) + .ToSet(); + + dialectProvider.PrepareParameterizedInsertStatement(dbCmd, + insertFields: fieldsWithoutDefaults); + + foreach (var obj in objs) + { + OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj); dialectProvider.SetParameterValues(dbCmd, obj); - dbCmd.ExecNonQuery(); + try + { + dbCmd.ExecNonQuery(); + } + catch (Exception ex) + { + Log.Error($"SQL ERROR: {dbCmd.GetLastSqlAndParams()}", ex); + throw; + } } - if (dbTrans != null) - dbTrans.Commit(); + dbTrans?.Commit(); } finally { - if (dbTrans != null) - dbTrans.Dispose(); + dbTrans?.Dispose(); } } @@ -718,35 +961,35 @@ internal static int Save(this IDbCommand dbCmd, params T[] objs) internal static bool Save(this IDbCommand dbCmd, T obj) { - var id = obj.GetId(); - var existingRow = id != null ? dbCmd.SingleById(id) : default(T); var modelDef = typeof(T).GetModelDefinition(); + var id = modelDef.GetPrimaryKey(obj); + var existingRow = id != null ? dbCmd.SingleById(id) : default(T); if (Equals(existingRow, default(T))) { if (modelDef.HasAutoIncrementId) { var dialectProvider = dbCmd.GetDialectProvider(); - var newId = dbCmd.Insert(obj, selectIdentity: true); - var safeId = dialectProvider.ConvertDbValue(newId, modelDef.PrimaryKey.FieldType); - modelDef.PrimaryKey.SetValueFn(obj, safeId); + var newId = dbCmd.Insert(obj, commandFilter:null, selectIdentity: true); + var safeId = dialectProvider.FromDbValue(newId, modelDef.PrimaryKey.FieldType); + modelDef.PrimaryKey.SetValue(obj, safeId); id = newId; } else { - dbCmd.Insert(obj); + dbCmd.Insert(obj, commandFilter:null); } - if (modelDef.RowVersion != null) - modelDef.RowVersion.SetValueFn(obj, dbCmd.GetRowVersion(modelDef, id)); - + modelDef.RowVersion?.SetValue(obj, dbCmd.GetRowVersion(modelDef, id)); + return true; } - dbCmd.Update(obj); - - if (modelDef.RowVersion != null) - modelDef.RowVersion.SetValueFn(obj, dbCmd.GetRowVersion(modelDef, id)); + var rowsUpdated = dbCmd.Update(obj); + if (rowsUpdated == 0 && Env.StrictMode) + throw new OptimisticConcurrencyException("No rows were inserted or updated"); + + modelDef.RowVersion?.SetValue(obj, dbCmd.GetRowVersion(modelDef, id)); return false; } @@ -758,16 +1001,16 @@ internal static int SaveAll(this IDbCommand dbCmd, IEnumerable objs) var firstRow = saveRows.FirstOrDefault(); if (Equals(firstRow, default(T))) return 0; - var firstRowId = firstRow.GetId(); - var defaultIdValue = firstRowId != null ? firstRowId.GetType().GetDefaultValue() : null; + var modelDef = typeof(T).GetModelDefinition(); - var idMap = defaultIdValue != null - ? saveRows.Where(x => !defaultIdValue.Equals(x.GetId())).ToSafeDictionary(x => x.GetId()) - : saveRows.Where(x => x.GetId() != null).ToSafeDictionary(x => x.GetId()); + var firstRowId = modelDef.GetPrimaryKey(firstRow); + var defaultIdValue = firstRowId?.GetType().GetDefaultValue(); - var existingRowsMap = dbCmd.SelectByIds(idMap.Keys).ToDictionary(x => x.GetId()); + var idMap = defaultIdValue != null + ? saveRows.Where(x => !defaultIdValue.Equals(modelDef.GetPrimaryKey(x))).ToSafeDictionary(x => modelDef.GetPrimaryKey(x)) + : saveRows.Where(x => modelDef.GetPrimaryKey(x) != null).ToSafeDictionary(x => modelDef.GetPrimaryKey(x)); - var modelDef = typeof(T).GetModelDefinition(); + var existingRowsMap = dbCmd.SelectByIds(idMap.Keys).ToDictionary(x => modelDef.GetPrimaryKey(x)); var rowsAdded = 0; @@ -778,48 +1021,41 @@ internal static int SaveAll(this IDbCommand dbCmd, IEnumerable objs) try { + var dialect = dbCmd.Dialect(); foreach (var row in saveRows) { - var id = row.GetId(); + var id = modelDef.GetPrimaryKey(row); if (id != defaultIdValue && existingRowsMap.ContainsKey(id)) { - if (OrmLiteConfig.UpdateFilter != null) - OrmLiteConfig.UpdateFilter(dbCmd, row); - dbCmd.Update(row); } else { if (modelDef.HasAutoIncrementId) { - var dialectProvider = dbCmd.GetDialectProvider(); - var newId = dbCmd.Insert(row, selectIdentity: true); - var safeId = dialectProvider.ConvertDbValue(newId, modelDef.PrimaryKey.FieldType); - modelDef.PrimaryKey.SetValueFn(row, safeId); + var newId = dbCmd.Insert(row, commandFilter: null, selectIdentity: true); + var safeId = dialect.FromDbValue(newId, modelDef.PrimaryKey.FieldType); + modelDef.PrimaryKey.SetValue(row, safeId); id = newId; } else { - if (OrmLiteConfig.InsertFilter != null) - OrmLiteConfig.InsertFilter(dbCmd, row); - - dbCmd.Insert(row); + dbCmd.Insert(row, commandFilter: null); } rowsAdded++; } - if (modelDef.RowVersion != null) - modelDef.RowVersion.SetValueFn(row, dbCmd.GetRowVersion(modelDef, id)); + modelDef.RowVersion?.SetValue(row, dbCmd.GetRowVersion(modelDef, id)); } - if (dbTrans != null) - dbTrans.Commit(); + dbTrans?.Commit(); } finally { - if (dbTrans != null) - dbTrans.Dispose(); + dbTrans?.Dispose(); + if (dbCmd.Transaction == dbTrans) + dbCmd.Transaction = null; } return rowsAdded; @@ -831,12 +1067,14 @@ internal static void SaveAllReferences(this IDbCommand dbCmd, T instance) var pkValue = modelDef.PrimaryKey.GetValue(instance); var fieldDefs = modelDef.AllFieldDefinitionsArray.Where(x => x.IsReference); + + bool updateInstance = false; foreach (var fieldDef in fieldDefs) { var listInterface = fieldDef.FieldType.GetTypeWithGenericInterfaceOf(typeof(IList<>)); if (listInterface != null) { - var refType = listInterface.GenericTypeArguments()[0]; + var refType = listInterface.GetGenericArguments()[0]; var refModelDef = refType.GetModelDefinition(); var refField = modelDef.GetRefFieldDef(refModelDef, refType); @@ -846,7 +1084,7 @@ internal static void SaveAllReferences(this IDbCommand dbCmd, T instance) { foreach (var oRef in results) { - refField.SetValueFn(oRef, pkValue); + refField.SetValue(oRef, pkValue); } dbCmd.CreateTypedApi(refType).SaveAll(results); @@ -866,8 +1104,8 @@ internal static void SaveAllReferences(this IDbCommand dbCmd, T instance) if (result != null) { - if (refField != null) - refField.SetValueFn(result, pkValue); + if (refField != null && refSelf == null) + refField.SetValue(result, pkValue); dbCmd.CreateTypedApi(refType).Save(result); @@ -875,12 +1113,17 @@ internal static void SaveAllReferences(this IDbCommand dbCmd, T instance) if (refSelf != null) { var refPkValue = refModelDef.PrimaryKey.GetValue(result); - refSelf.SetValueFn(instance, refPkValue); - dbCmd.Update(instance); + refSelf.SetValue(instance, refPkValue); + updateInstance = true; } } } } + + if (updateInstance) + { + dbCmd.Update(instance); + } } internal static void SaveReferences(this IDbCommand dbCmd, T instance, params TRef[] refs) @@ -899,8 +1142,7 @@ internal static void SaveReferences(this IDbCommand dbCmd, T instance, ? modelDef.GetRefFieldDef(refModelDef, refType) : modelDef.GetRefFieldDefIfExists(refModelDef); - if (refField != null) - refField.SetValueFn(oRef, pkValue); + refField?.SetValue(oRef, pkValue); } dbCmd.SaveAll(refs); @@ -911,7 +1153,7 @@ internal static void SaveReferences(this IDbCommand dbCmd, T instance, if (refSelf != null) { var refPkValue = refModelDef.PrimaryKey.GetValue(oRef); - refSelf.SetValueFn(instance, refPkValue); + refSelf.SetValue(instance, refPkValue); dbCmd.Update(instance); } } @@ -925,10 +1167,15 @@ internal static void ExecuteProcedure(this IDbCommand dbCmd, T obj) dbCmd.ExecuteNonQuery(); } - internal static ulong GetRowVersion(this IDbCommand dbCmd, ModelDefinition modelDef, object id) + internal static object GetRowVersion(this IDbCommand dbCmd, ModelDefinition modelDef, object id) { var sql = RowVersionSql(dbCmd, modelDef, id); - return dbCmd.Scalar(sql); + var to = dbCmd.GetDialectProvider().FromDbRowVersion(modelDef.RowVersion.FieldType, dbCmd.Scalar(sql)); + + if (to is ulong u && modelDef.RowVersion.ColumnType == typeof(byte[])) + return BitConverter.GetBytes(u); + + return to ?? modelDef.RowVersion.ColumnType.GetDefaultValue(); } internal static string RowVersionSql(this IDbCommand dbCmd, ModelDefinition modelDef, object id) @@ -936,16 +1183,17 @@ internal static string RowVersionSql(this IDbCommand dbCmd, ModelDefinition mode var dialectProvider = dbCmd.GetDialectProvider(); var idParamString = dialectProvider.GetParam(); - var sql = string.Format("SELECT {0} FROM {1} WHERE {2} = {3}", - dialectProvider.GetRowVersionColumnName(modelDef.RowVersion), - dialectProvider.GetQuotedTableName(modelDef), - dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName), - idParamString); + var sql = $"SELECT {dialectProvider.GetRowVersionSelectColumn(modelDef.RowVersion)} " + + $"FROM {dialectProvider.GetQuotedTableName(modelDef)} " + + $"WHERE {dialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName)} = {idParamString}"; dbCmd.Parameters.Clear(); var idParam = dbCmd.CreateParameter(); + idParam.Direction = ParameterDirection.Input; idParam.ParameterName = idParamString; - idParam.Value = id; + + dialectProvider.SetParamValue(idParam, id, modelDef.PrimaryKey.ColumnType, modelDef.PrimaryKey); + dbCmd.Parameters.Add(idParam); return sql; } diff --git a/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApi.cs b/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApi.cs index 346aebc89..9b0a7d412 100644 --- a/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApi.cs +++ b/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApi.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using System.Linq.Expressions; @@ -9,34 +10,35 @@ public static class OrmLiteWriteExpressionsApi /// /// Use an SqlExpression to select which fields to update and construct the where expression, E.g: /// - /// db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + /// var q = db.From>Person<()); + /// db.UpdateOnlyFields(new Person { FirstName = "JJ" }, q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') /// /// What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: /// - /// db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); + /// db.UpdateOnlyFields(new Person { FirstName = "JJ", LastName = "Hendo" }, ev.Update(p => p.FirstName)); /// UPDATE "Person" SET "FirstName" = 'JJ' /// - public static int UpdateOnly(this IDbConnection dbConn, T model, Func, SqlExpression> onlyFields) + public static int UpdateOnlyFields(this IDbConnection dbConn, + T model, SqlExpression onlyFields, + Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(model, onlyFields)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyFields(model, onlyFields, commandFilter)); } /// - /// Use an SqlExpression to select which fields to update and construct the where expression, E.g: - /// - /// var q = db.From>Person<()); - /// db.UpdateOnly(new Person { FirstName = "JJ" }, q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') - /// - /// What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: /// - /// db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev.Update(p => p.FirstName)); - /// UPDATE "Person" SET "FirstName" = 'JJ' + /// db.UpdateOnly(new Person { FirstName = "JJ" }, new[]{ "FirstName" }, p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') /// - public static int UpdateOnly(this IDbConnection dbConn, T model, SqlExpression onlyFields) + public static int UpdateOnlyFields(this IDbConnection dbConn, + T obj, + string[] onlyFields, + Expression> where = null, + Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(model, onlyFields)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyFields(obj, onlyFields, where, commandFilter)); } /// @@ -47,143 +49,235 @@ public static int UpdateOnly(this IDbConnection dbConn, T model, SqlExpressio /// /// db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName); /// UPDATE "Person" SET "FirstName" = 'JJ' + /// + /// db.UpdateOnly(new Person { FirstName = "JJ", Age = 27 }, p => new { p.FirstName, p.Age ); + /// UPDATE "Person" SET "FirstName" = 'JJ', "Age" = 27 + /// + public static int UpdateOnlyFields(this IDbConnection dbConn, + T obj, + Expression> onlyFields = null, + Expression> where = null, + Action commandFilter = null) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyFields(obj, onlyFields, where, commandFilter)); + } + + /// + /// Update only fields in the specified expression that matches the where condition (if any), E.g: + /// + /// db.UpdateOnly(() => new Person { FirstName = "JJ" }, where: p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + /// db.UpdateOnly(() => new Person { FirstName = "JJ" }); + /// UPDATE "Person" SET "FirstName" = 'JJ' /// - public static int UpdateOnly(this IDbConnection dbConn, T obj, - Expression> onlyFields = null, - Expression> where = null) + public static int UpdateOnly(this IDbConnection dbConn, + Expression> updateFields, + Expression> where = null, + Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(obj, onlyFields, where)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(updateFields, dbCmd.GetDialectProvider().SqlExpression().Where(where), commandFilter)); } /// - /// Updates all non-default values set on item matching the where condition (if any). E.g + /// Update only fields in the specified expression that matches the where condition (if any), E.g: /// - /// db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.FirstName == "Jimi"); + /// db.UpdateOnly(() => new Person { FirstName = "JJ" }, db.From>Person<().Where(p => p.LastName == "Hendrix")); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + public static int UpdateOnly(this IDbConnection dbConn, + Expression> updateFields, + SqlExpression q, + Action commandFilter = null) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(updateFields, q, commandFilter)); + } + + /// + /// Update only fields in the specified expression that matches the where condition (if any), E.g: + /// + /// var q = db.From>Person<().Where(p => p.LastName == "Hendrix"); + /// db.UpdateOnly(() => new Person { FirstName = "JJ" }, q.WhereExpression, q.Params); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + public static int UpdateOnly(this IDbConnection dbConn, + Expression> updateFields, + string whereExpression, + IEnumerable sqlParams, + Action commandFilter = null) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(updateFields, whereExpression, sqlParams, commandFilter)); + } + + /// + /// Updates all values from Object Dictionary matching the where condition. E.g + /// + /// db.UpdateOnly<Person>(new Dictionary<string,object< { {"FirstName", "JJ"} }, where:p => p.FirstName == "Jimi"); /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') /// - public static int UpdateNonDefaults(this IDbConnection dbConn, T item, Expression> obj) + public static int UpdateOnly(this IDbConnection dbConn, Dictionary updateFields, Expression> obj) { - return dbConn.Exec(dbCmd => dbCmd.UpdateNonDefaults(item, obj)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(updateFields, obj)); } /// - /// Updates all values set on item matching the where condition (if any). E.g + /// Updates all values from Object Dictionary, Requires Id which is used as a Primary Key Filter. E.g /// - /// db.Update(new Person { Id = 1, FirstName = "JJ" }, p => p.LastName == "Hendrix"); - /// UPDATE "Person" SET "Id" = 1,"FirstName" = 'JJ',"LastName" = NULL,"Age" = 0 WHERE ("LastName" = 'Hendrix') + /// db.UpdateOnly<Person>(new Dictionary<string,object< { {"Id", 1}, {"FirstName", "JJ"} }); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("Id" = 1) /// - public static int Update(this IDbConnection dbConn, T item, Expression> where) + public static int UpdateOnly(this IDbConnection dbConn, Dictionary updateFields, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.Update(item, where)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(updateFields, commandFilter)); } /// - /// Updates all matching fields populated on anonymousType that matches where condition (if any). E.g: + /// Updates all values from Object Dictionary matching the where condition. E.g /// - /// db.Update<Person>(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// db.UpdateOnly<Person>(new Dictionary<string,object< { {"FirstName", "JJ"} }, "FirstName == {0}", new[] { "Jimi" }); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') + /// + public static int UpdateOnly(this IDbConnection dbConn, Dictionary updateFields, string whereExpression, object[] whereParams, Action commandFilter = null) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnly(updateFields, whereExpression, whereParams, commandFilter)); + } + + /// + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: + /// Numeric fields generates an increment sql which is useful to increment counters, etc... + /// avoiding concurrency conflicts + /// + /// db.UpdateAdd(() => new Person { Age = 5 }, where: p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "Age" = "Age" + 5 WHERE ("LastName" = 'Hendrix') + /// + /// db.UpdateAdd(() => new Person { Age = 5 }); + /// UPDATE "Person" SET "Age" = "Age" + 5 + /// + public static int UpdateAdd(this IDbConnection dbConn, + Expression> updateFields, + Expression> where = null, + Action commandFilter = null) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateAdd(updateFields, dbCmd.GetDialectProvider().SqlExpression().Where(where), commandFilter)); + } + + /// + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: + /// Numeric fields generates an increment sql which is useful to increment counters, etc... + /// avoiding concurrency conflicts + /// + /// db.UpdateAdd(() => new Person { Age = 5 }, db.From<Person>().Where(p => p.LastName == "Hendrix")); + /// UPDATE "Person" SET "Age" = "Age" + 5 WHERE ("LastName" = 'Hendrix') /// - public static int Update(this IDbConnection dbConn, object updateOnly, Expression> where = null) + public static int UpdateAdd(this IDbConnection dbConn, + Expression> updateFields, + SqlExpression q, + Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.Update(updateOnly, where)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAdd(updateFields, q, commandFilter)); } /// - /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g: + /// Updates all non-default values set on item matching the where condition (if any). E.g /// - /// db.Update<Person>(set:"FirstName = {0}".Params("JJ"), where:"LastName = {0}".Params("Hendrix")); - /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.FirstName == "Jimi"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') /// - public static int UpdateFmt(this IDbConnection dbConn, string set = null, string where = null) + public static int UpdateNonDefaults(this IDbConnection dbConn, T item, Expression> obj) { - return dbConn.Exec(dbCmd => dbCmd.UpdateFmt(set, where)); + return dbConn.Exec(dbCmd => dbCmd.UpdateNonDefaults(item, obj)); } /// - /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g. + /// Updates all values set on item matching the where condition (if any). E.g /// - /// db.Update(table:"Person", set: "FirstName = {0}".Params("JJ"), where: "LastName = {0}".Params("Hendrix")); - /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// db.Update(new Person { Id = 1, FirstName = "JJ" }, p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "Id" = 1,"FirstName" = 'JJ',"LastName" = NULL,"Age" = 0 WHERE ("LastName" = 'Hendrix') /// - public static int UpdateFmt(this IDbConnection dbConn, string table = null, string set = null, string where = null) + public static int Update(this IDbConnection dbConn, T item, Expression> where, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.UpdateFmt(table, set, where)); + return dbConn.Exec(dbCmd => dbCmd.Update(item, where, commandFilter)); } /// - /// Insert only fields in POCO specified by the SqlExpression lambda. E.g: - /// db.InsertOnly(new Person { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })) + /// Updates all matching fields populated on anonymousType that matches where condition (if any). E.g: + /// + /// db.Update<Person>(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') /// - public static void InsertOnly(this IDbConnection dbConn, T obj, Func, SqlExpression> onlyFields) + public static int Update(this IDbConnection dbConn, object updateOnly, Expression> where, Action commandFilter = null) { - dbConn.Exec(dbCmd => dbCmd.InsertOnly(obj, onlyFields)); + return dbConn.Exec(dbCmd => dbCmd.Update(updateOnly, where, commandFilter)); } /// /// Using an SqlExpression to only Insert the fields specified, e.g: /// - /// db.InsertOnly(new Person { FirstName = "Amy" }, q => q.Insert(p => new { p.FirstName })); + /// db.InsertOnly(new Person { FirstName = "Amy" }, p => p.FirstName)); /// INSERT INTO "Person" ("FirstName") VALUES ('Amy'); + /// + /// db.InsertOnly(new Person { Id =1 , FirstName="Amy" }, p => new { p.Id, p.FirstName })); + /// INSERT INTO "Person" ("Id", "FirstName") VALUES (1, 'Amy'); /// - public static void InsertOnly(this IDbConnection dbConn, T obj, SqlExpression onlyFields) + public static long InsertOnly(this IDbConnection dbConn, T obj, Expression> onlyFields, bool selectIdentity = false) { - dbConn.Exec(dbCmd => dbCmd.InsertOnly(obj, onlyFields)); + return dbConn.Exec(dbCmd => dbCmd.InsertOnly(obj, onlyFields.GetFieldNames(), selectIdentity)); } /// - /// Delete the rows that matches the where expression, e.g: + /// Using an SqlExpression to only Insert the fields specified, e.g: /// - /// db.Delete<Person>(p => p.Age == 27); - /// DELETE FROM "Person" WHERE ("Age" = 27) + /// db.InsertOnly(new Person { FirstName = "Amy" }, new[]{ "FirstName" })); + /// INSERT INTO "Person" ("FirstName") VALUES ('Amy'); /// - public static int Delete(this IDbConnection dbConn, Expression> where) + public static long InsertOnly(this IDbConnection dbConn, T obj, string[] onlyFields, bool selectIdentity = false) { - return dbConn.Exec(dbCmd => dbCmd.Delete(where)); + return dbConn.Exec(dbCmd => dbCmd.InsertOnly(obj, onlyFields, selectIdentity)); } /// - /// Delete the rows that matches the where expression, e.g: + /// Using an SqlExpression to only Insert the fields specified, e.g: /// - /// db.Delete<Person>(ev => ev.Where(p => p.Age == 27)); - /// DELETE FROM "Person" WHERE ("Age" = 27) + /// db.InsertOnly(() => new Person { FirstName = "Amy" })); + /// INSERT INTO "Person" ("FirstName") VALUES (@FirstName); /// - public static int Delete(this IDbConnection dbConn, Func, SqlExpression> where) + public static long InsertOnly(this IDbConnection dbConn, Expression> insertFields, bool selectIdentity = false) { - return dbConn.Exec(dbCmd => dbCmd.Delete(where)); + return dbConn.Exec(dbCmd => dbCmd.InsertOnly(insertFields, selectIdentity)); } /// /// Delete the rows that matches the where expression, e.g: /// - /// var q = db.From>Person<()); - /// db.Delete<Person>(q.Where(p => p.Age == 27)); + /// db.Delete<Person>(p => p.Age == 27); /// DELETE FROM "Person" WHERE ("Age" = 27) /// - public static int Delete(this IDbConnection dbConn, SqlExpression where) + public static int Delete(this IDbConnection dbConn, Expression> where, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.Delete(where)); + return dbConn.Exec(dbCmd => dbCmd.Delete(where, commandFilter)); } /// - /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// Delete the rows that matches the where expression, e.g: /// - /// db.Delete<Person>(where:"Age = {0}".Params(27)); - /// DELETE FROM "Person" WHERE Age = 27 + /// var q = db.From<Person>()); + /// db.Delete<Person>(q.Where(p => p.Age == 27)); + /// DELETE FROM "Person" WHERE ("Age" = 27) /// - public static int DeleteFmt(this IDbConnection dbConn, string where = null) + public static int Delete(this IDbConnection dbConn, SqlExpression where, Action commandFilter = null) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(where)); + return dbConn.Exec(dbCmd => dbCmd.Delete(where, commandFilter)); } /// - /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// Delete the rows that matches the where filter, e.g: /// - /// db.Delete(table:"Person", where: "Age = {0}".Params(27)); - /// DELETE FROM "Person" WHERE Age = 27 + /// db.DeleteWhere<Person>("Age = {0}", new object[] { 27 }); + /// DELETE FROM "Person" WHERE ("Age" = 27) /// - public static int DeleteFmt(this IDbConnection dbConn, string table = null, string where = null) + public static int DeleteWhere(this IDbConnection dbConn, string whereFilter, object[] whereParams) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmt(table, where)); + return dbConn.Exec(dbCmd => dbCmd.DeleteWhere(whereFilter, whereParams)); } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApiAsync.cs b/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApiAsync.cs index 9102b3682..281aff183 100644 --- a/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApiAsync.cs +++ b/src/ServiceStack.OrmLite/OrmLiteWriteExpressionsApiAsync.cs @@ -1,5 +1,6 @@ -#if NET45 +#if ASYNC using System; +using System.Collections.Generic; using System.Data; using System.Linq.Expressions; using System.Threading; @@ -12,186 +13,303 @@ public static class OrmLiteWriteExpressionsApiAsync /// /// Use an SqlExpression to select which fields to update and construct the where expression, E.g: /// - /// db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + /// var q = db.From>Person<()); + /// db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') /// /// What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: /// - /// db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); + /// db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, ev.Update(p => p.FirstName)); /// UPDATE "Person" SET "FirstName" = 'JJ' /// - public static Task UpdateOnlyAsync(this IDbConnection dbConn, T model, Func, SqlExpression> onlyFields, CancellationToken token = default(CancellationToken)) + public static Task UpdateOnlyFieldsAsync(this IDbConnection dbConn, + T model, + SqlExpression onlyFields, + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(model, onlyFields, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyFieldsAsync(model, onlyFields, commandFilter, token)); } /// - /// Use an SqlExpression to select which fields to update and construct the where expression, E.g: - /// - /// var q = db.From>Person<()); - /// db.UpdateOnly(new Person { FirstName = "JJ" }, q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: /// - /// What's not in the update expression doesn't get updated. No where expression updates all rows. E.g: + /// db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, new[]{ "FirstName" }, p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + public static Task UpdateOnlyFieldsAsync(this IDbConnection dbConn, + T obj, + string[] onlyFields, + Expression> where = null, + Action commandFilter = null, + CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyFieldsAsync(obj, onlyFields, where, commandFilter, token)); + } + + /// + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: /// - /// db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev.Update(p => p.FirstName)); + /// db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + /// db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName); /// UPDATE "Person" SET "FirstName" = 'JJ' /// - public static Task UpdateOnlyAsync(this IDbConnection dbConn, T model, SqlExpression onlyFields, CancellationToken token = default(CancellationToken)) + public static Task UpdateOnlyFieldsAsync(this IDbConnection dbConn, + T obj, + Expression> onlyFields = null, + Expression> where = null, + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(model, onlyFields, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyFieldsAsync(obj, onlyFields, where, commandFilter, token)); } /// /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: /// - /// db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + /// db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }, where: p => p.LastName == "Hendrix"); /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') /// - /// db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName); + /// db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }); /// UPDATE "Person" SET "FirstName" = 'JJ' /// - public static Task UpdateOnlyAsync(this IDbConnection dbConn, T obj, - Expression> onlyFields = null, + public static Task UpdateOnlyAsync(this IDbConnection dbConn, + Expression> updateFields, Expression> where = null, - CancellationToken token = default(CancellationToken)) + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(obj, onlyFields, where, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(updateFields, dbCmd.GetDialectProvider().SqlExpression().Where(where), commandFilter, token)); } /// - /// Updates all non-default values set on item matching the where condition (if any). E.g + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: /// - /// db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.FirstName == "Jimi"); + /// db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }, db.From<Person>().Where(p => p.LastName == "Hendrix")); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + public static Task UpdateOnlyAsync(this IDbConnection dbConn, + Expression> updateFields, + SqlExpression q, + Action commandFilter = null, + CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(updateFields, q, commandFilter, token)); + } + + /// + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: + /// + /// var q = db.From>Person<().Where(p => p.LastName == "Hendrix"); + /// db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }, q.WhereExpression, q.Params); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + public static Task UpdateOnlyAsync(this IDbConnection dbConn, + Expression> updateFields, + string whereExpression, + IEnumerable sqlParams, + Action commandFilter = null, + CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(updateFields, whereExpression, sqlParams, commandFilter, token)); + } + + /// + /// Updates all values from Object Dictionary matching the where condition. E.g + /// + /// db.UpdateOnlyAsync<Person>(new Dictionary<string,object< { {"FirstName", "JJ"} }, where:p => p.FirstName == "Jimi"); /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') /// - public static Task UpdateNonDefaultsAsync(this IDbConnection dbConn, T item, Expression> obj, CancellationToken token = default(CancellationToken)) + public static Task UpdateOnlyAsync(this IDbConnection dbConn, + Dictionary updateFields, + Expression> where, + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateNonDefaultsAsync(item, obj, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(updateFields, where, commandFilter, token)); } /// - /// Updates all values set on item matching the where condition (if any). E.g + /// Updates all values from Object Dictionary, Requires Id which is used as a Primary Key Filter. E.g /// - /// db.Update(new Person { Id = 1, FirstName = "JJ" }, p => p.LastName == "Hendrix"); - /// UPDATE "Person" SET "Id" = 1,"FirstName" = 'JJ',"LastName" = NULL,"Age" = 0 WHERE ("LastName" = 'Hendrix') + /// db.UpdateOnlyAsync<Person>(new Dictionary<string,object< { {"Id", 1}, {"FirstName", "JJ"} }); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("Id" = 1) /// - public static Task UpdateAsync(this IDbConnection dbConn, T item, Expression> where, CancellationToken token = default(CancellationToken)) + public static Task UpdateOnlyAsync(this IDbConnection dbConn, + Dictionary updateFields, + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(item, where, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(updateFields, commandFilter, token)); } /// - /// Updates all matching fields populated on anonymousType that matches where condition (if any). E.g: + /// Updates all values from Object Dictionary matching the where condition. E.g /// - /// db.Update<Person>(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// db.UpdateOnlyAsync<Person>(new Dictionary<string,object< { {"FirstName", "JJ"} }, "FirstName == {0}", new[]{ "Jimi" }); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') /// - public static Task UpdateAsync(this IDbConnection dbConn, object updateOnly, Expression> where = null, CancellationToken token = default(CancellationToken)) + public static Task UpdateOnlyAsync(this IDbConnection dbConn, + Dictionary updateFields, + string whereExpression, + object[] whereParams, + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(updateOnly, where, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateOnlyAsync(updateFields, whereExpression, whereParams, commandFilter, token)); } /// - /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g: + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: + /// Numeric fields generates an increment sql which is useful to increment counters, etc... + /// avoiding concurrency conflicts /// - /// db.Update<Person>(set:"FirstName = {0}".Params("JJ"), where:"LastName = {0}".Params("Hendrix")); - /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// db.UpdateAddAsync(() => new Person { Age = 5 }, where: p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "Age" = "Age" + 5 WHERE ("LastName" = 'Hendrix') + /// + /// db.UpdateAddAsync(() => new Person { Age = 5 }); + /// UPDATE "Person" SET "Age" = "Age" + 5 /// - public static Task UpdateFmtAsync(this IDbConnection dbConn, string set = null, string where = null, CancellationToken token = default(CancellationToken)) + public static Task UpdateAddAsync(this IDbConnection dbConn, + Expression> updateFields, + Expression> where = null, + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateFmtAsync(set, where, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAddAsync(updateFields, dbCmd.GetDialectProvider().SqlExpression().Where(where), commandFilter, token)); } /// - /// Flexible Update method to succinctly execute a free-text update statement using optional params. E.g. + /// Update record, updating only fields specified in updateOnly that matches the where condition (if any), E.g: + /// Numeric fields generates an increment sql which is useful to increment counters, etc... + /// avoiding concurrency conflicts /// - /// db.Update(table:"Person", set: "FirstName = {0}".Params("JJ"), where: "LastName = {0}".Params("Hendrix")); - /// UPDATE "Person" SET FirstName = 'JJ' WHERE LastName = 'Hendrix' + /// db.UpdateAddAsync(() => new Person { Age = 5 }, db.From<Person>().Where(p => p.LastName == "Hendrix")); + /// UPDATE "Person" SET "Age" = "Age" + 5 WHERE ("LastName" = 'Hendrix') /// - public static Task UpdateFmtAsync(this IDbConnection dbConn, string table = null, string set = null, string where = null, CancellationToken token = default(CancellationToken)) + public static Task UpdateAddAsync(this IDbConnection dbConn, + Expression> updateFields, + SqlExpression q, + Action commandFilter = null, + CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.UpdateFmtAsync(table, set, where, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateAddAsync(updateFields, q, commandFilter, token)); } /// - /// Insert only fields in POCO specified by the SqlExpression lambda. E.g: - /// db.InsertOnly(new Person { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })) + /// Updates all non-default values set on item matching the where condition (if any). E.g + /// + /// db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.FirstName == "Jimi"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("FirstName" = 'Jimi') /// - public static Task InsertOnlyAsync(this IDbConnection dbConn, T obj, Func, SqlExpression> onlyFields, CancellationToken token = default(CancellationToken)) + public static Task UpdateNonDefaultsAsync(this IDbConnection dbConn, T item, Expression> obj, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.InsertOnlyAsync(obj, onlyFields, token)); + return dbConn.Exec(dbCmd => dbCmd.UpdateNonDefaultsAsync(item, obj, token)); + } + + /// + /// Updates all values set on item matching the where condition (if any). E.g + /// + /// db.UpdateAsync(new Person { Id = 1, FirstName = "JJ" }, p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "Id" = 1,"FirstName" = 'JJ',"LastName" = NULL,"Age" = 0 WHERE ("LastName" = 'Hendrix') + /// + public static Task UpdateAsync(this IDbConnection dbConn, + T item, + Expression> where, + Action commandFilter = null, + CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(item, where, commandFilter, token)); + } + + /// + /// Updates all matching fields populated on anonymousType that matches where condition (if any). E.g: + /// + /// db.UpdateAsync<Person>(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + /// UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix') + /// + public static Task UpdateAsync(this IDbConnection dbConn, + object updateOnly, + Expression> where = null, + Action commandFilter = null, + CancellationToken token = default) + { + return dbConn.Exec(dbCmd => dbCmd.UpdateAsync(updateOnly, where, commandFilter, token)); } /// /// Using an SqlExpression to only Insert the fields specified, e.g: /// - /// db.InsertOnly(new Person { FirstName = "Amy" }, q => q.Insert(p => new { p.FirstName })); + /// db.InsertOnlyAsync(new Person { FirstName = "Amy" }, p => p.FirstName)); /// INSERT INTO "Person" ("FirstName") VALUES ('Amy'); + /// + /// db.InsertOnlyAsync(new Person { Id =1 , FirstName="Amy" }, p => new { p.Id, p.FirstName })); + /// INSERT INTO "Person" ("Id", "FirstName") VALUES (1, 'Amy'); /// - public static Task InsertOnlyAsync(this IDbConnection dbConn, T obj, SqlExpression onlyFields, CancellationToken token = default(CancellationToken)) + public static Task InsertOnlyAsync(this IDbConnection dbConn, T obj, Expression> onlyFields, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.InsertOnlyAsync(obj, onlyFields, token)); + return dbConn.Exec(dbCmd => dbCmd.InsertOnlyAsync(obj, onlyFields.GetFieldNames(), token)); } /// - /// Delete the rows that matches the where expression, e.g: + /// Using an SqlExpression to only Insert the fields specified, e.g: /// - /// db.Delete<Person>(p => p.Age == 27); - /// DELETE FROM "Person" WHERE ("Age" = 27) + /// db.InsertOnlyAsync(new Person { FirstName = "Amy" }, new[]{ "FirstName" })); + /// INSERT INTO "Person" ("FirstName") VALUES ('Amy'); /// - public static Task DeleteAsync(this IDbConnection dbConn, Expression> where, CancellationToken token = default(CancellationToken)) + public static Task InsertOnlyAsync(this IDbConnection dbConn, T obj, string[] onlyFields, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(where, token)); + return dbConn.Exec(dbCmd => dbCmd.InsertOnlyAsync(obj, onlyFields, token)); } /// - /// Delete the rows that matches the where expression, e.g: + /// Using an SqlExpression to only Insert the fields specified, e.g: /// - /// db.Delete<Person>(ev => ev.Where(p => p.Age == 27)); - /// DELETE FROM "Person" WHERE ("Age" = 27) + /// db.InsertOnlyAsync(() => new Person { FirstName = "Amy" })); + /// INSERT INTO "Person" ("FirstName") VALUES (@FirstName); /// - public static Task DeleteAsync(this IDbConnection dbConn, Func, SqlExpression> where, CancellationToken token = default(CancellationToken)) + public static Task InsertOnlyAsync(this IDbConnection dbConn, Expression> insertFields, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(where, token)); + return dbConn.Exec(dbCmd => dbCmd.InsertOnlyAsync(insertFields, token)); } /// /// Delete the rows that matches the where expression, e.g: /// - /// var q = db.From>Person<()); - /// db.Delete<Person>(q.Where(p => p.Age == 27)); + /// db.DeleteAsync<Person>(p => p.Age == 27); /// DELETE FROM "Person" WHERE ("Age" = 27) /// - public static Task DeleteAsync(this IDbConnection dbConn, SqlExpression where, CancellationToken token = default(CancellationToken)) + public static Task DeleteAsync(this IDbConnection dbConn, Expression> where, + Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(where, token)); + return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(where, commandFilter, token)); } /// - /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// Delete the rows that matches the where expression, e.g: /// - /// db.Delete<Person>(where:"Age = {0}".Params(27)); - /// DELETE FROM "Person" WHERE Age = 27 + /// var q = db.From>Person<()); + /// db.DeleteAsync<Person>(q.Where(p => p.Age == 27)); + /// DELETE FROM "Person" WHERE ("Age" = 27) /// - public static Task DeleteFmtAsync(this IDbConnection dbConn, string where, CancellationToken token = default(CancellationToken)) - { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(where, token)); - } - public static Task DeleteFmtAsync(this IDbConnection dbConn, string where = null) + public static Task DeleteAsync(this IDbConnection dbConn, SqlExpression where + , Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(where, default(CancellationToken))); + return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(where, commandFilter, token)); } - + /// - /// Flexible Delete method to succinctly execute a delete statement using free-text where expression. E.g. + /// Delete the rows that matches the where filter, e.g: /// - /// db.Delete(table:"Person", where: "Age = {0}".Params(27)); - /// DELETE FROM "Person" WHERE Age = 27 + /// db.DeleteWhereAsync<Person>("Age = {0}", new object[] { 27 }); + /// DELETE FROM "Person" WHERE ("Age" = 27) /// - public static Task DeleteFmtAsync(this IDbConnection dbConn, string table = null, string where = null, CancellationToken token = default(CancellationToken)) + public static Task DeleteWhereAsync(this IDbConnection dbConn, string whereFilter, object[] whereParams + , Action commandFilter = null, CancellationToken token = default) { - return dbConn.Exec(dbCmd => dbCmd.DeleteFmtAsync(table, where, token)); + return dbConn.Exec(dbCmd => dbCmd.DeleteWhereAsync(whereFilter, whereParams, commandFilter, token)); } } } diff --git a/src/ServiceStack.OrmLite/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLite/Properties/AssemblyInfo.cs index d34185aeb..22ae012d6 100644 --- a/src/ServiceStack.OrmLite/Properties/AssemblyInfo.cs +++ b/src/ServiceStack.OrmLite/Properties/AssemblyInfo.cs @@ -1,25 +1 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("ServiceStack")] -[assembly: AssemblyProduct("ServiceStack.OrmLite")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("d0f92eb9-6843-4996-951a-a0f04b076ec9")] - -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: System.Reflection.AssemblyVersion("6.0.0.0")] diff --git a/src/ServiceStack.OrmLite/PropertyInvoker.cs b/src/ServiceStack.OrmLite/PropertyInvoker.cs deleted file mode 100644 index c79fbbf62..000000000 --- a/src/ServiceStack.OrmLite/PropertyInvoker.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -// ServiceStack.OrmLite: Light-weight POCO ORM for .NET and Mono -// -// Authors: -// Demis Bellot (demis.bellot@gmail.com) -// -// Copyright 2013 Service Stack LLC. All Rights Reserved. -// -// Licensed under the same terms of ServiceStack. -// - -using System; -using System.Linq.Expressions; -using System.Reflection; - -namespace ServiceStack.OrmLite -{ - public static class PropertyInvoker - { - public static PropertySetterDelegate GetPropertySetterFn(this PropertyInfo propertyInfo) - { - var propertySetMethod = propertyInfo.GetSetMethod(); - if (propertySetMethod == null) return null; - -#if NO_EXPRESSIONS - return (o, convertedValue) => - { - propertySetMethod.Invoke(o, new[] { convertedValue }); - return; - }; -#else - var instance = Expression.Parameter(typeof(object), "i"); - var argument = Expression.Parameter(typeof(object), "a"); - - var instanceParam = Expression.Convert(instance, propertyInfo.DeclaringType); - var valueParam = Expression.Convert(argument, propertyInfo.PropertyType); - - var setterCall = Expression.Call(instanceParam, propertyInfo.GetSetMethod(), valueParam); - - return Expression.Lambda(setterCall, instance, argument).Compile(); -#endif - } - - public static PropertyGetterDelegate GetPropertyGetterFn(this PropertyInfo propertyInfo) - { - var getMethodInfo = propertyInfo.GetGetMethod(); - if (getMethodInfo == null) return null; - -#if NO_EXPRESSIONS - return o => propertyInfo.GetGetMethod().Invoke(o, new object[] { }); -#else - try - { - var oInstanceParam = Expression.Parameter(typeof(object), "oInstanceParam"); - var instanceParam = Expression.Convert(oInstanceParam, propertyInfo.DeclaringType); - - var exprCallPropertyGetFn = Expression.Call(instanceParam, getMethodInfo); - var oExprCallPropertyGetFn = Expression.Convert(exprCallPropertyGetFn, typeof(object)); - - var propertyGetFn = Expression.Lambda - ( - oExprCallPropertyGetFn, - oInstanceParam - ).Compile(); - - return propertyGetFn; - - } - catch (Exception ex) - { - Console.Write(ex.Message); - throw; - } -#endif - } - } - - -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/ReflectionPropertyInvoker.cs b/src/ServiceStack.OrmLite/ReflectionPropertyInvoker.cs deleted file mode 100644 index 53c95fa19..000000000 --- a/src/ServiceStack.OrmLite/ReflectionPropertyInvoker.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// ServiceStack.OrmLite: Light-weight POCO ORM for .NET and Mono -// -// Authors: -// Demis Bellot (demis.bellot@gmail.com) -// -// Copyright 2013 Service Stack LLC. All Rights Reserved. -// -// Licensed under the same terms of ServiceStack. -// - -using System; -using System.Reflection; - -namespace ServiceStack.OrmLite -{ - public class ReflectionPropertyInvoker - : IPropertyInvoker - { - public static readonly ReflectionPropertyInvoker Instance = new ReflectionPropertyInvoker(); - - public Func ConvertValueFn { get; set; } - - public void SetPropertyValue(PropertyInfo propertyInfo, Type fieldType, object onInstance, object withValue) - { - var convertedValue = ConvertValueFn(withValue, fieldType); - - var propertySetMethod = propertyInfo.GetSetMethod(); - if (propertySetMethod == null) return; - - propertySetMethod.Invoke(onInstance, new[] { convertedValue }); - } - - public object GetPropertyValue(PropertyInfo propertyInfo, object fromInstance) - { - var value = propertyInfo.GetGetMethod().Invoke(fromInstance, new object[] { }); - return value; - } - } -} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Android.csproj b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Android.csproj deleted file mode 100644 index ea06ebede..000000000 --- a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Android.csproj +++ /dev/null @@ -1,105 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {42BF9D4F-100D-4577-8538-5FD309D2CBEB} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{F278D4AB-4730-4720-B08E-FE5E31564D9E};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Library - ServiceStack.OrmLite.Android - Resources\Resource.designer.cs - Resource - Resources - Assets - ServiceStack.OrmLite.Android - v2.3 - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - None - false - - - full - true - bin\Release - prompt - 4 - false - false - - - - - - - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Core.csproj b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Core.csproj new file mode 100644 index 000000000..fc18e6a3d --- /dev/null +++ b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Core.csproj @@ -0,0 +1,49 @@ + + + + ServiceStack.OrmLite.Core + ServiceStack.OrmLite + ServiceStack.OrmLite + netstandard2.0;net6.0 + ServiceStack.OrmLite .NET Standard 2.0 + + .NET Standard 2.0 version of ServiceStack.OrmLite + + OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC + + + $(DefineConstants);NETCORE;NETSTANDARD2_0 + + + $(DefineConstants);NETCORE;NET6_0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Signed.csproj b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Signed.csproj deleted file mode 100644 index 3528b5ef6..000000000 --- a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Signed.csproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - Library - Properties - ServiceStack.OrmLite - ServiceStack.OrmLite - v4.0 - 512 - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - - True - full - False - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - - - pdbonly - True - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - bin\Release\ServiceStack.OrmLite.xml - - - True - bin\STATIC_ONLY NO_EXPRESSIONS\ - DEBUG;TRACE - full - AnyCPU - prompt - 4 - False - AllRules.ruleset - - - True - bin\MonoTouch\ - TRACE;DEBUG;STATIC_ONLY NO_EXPRESSIONS - full - AnyCPU - prompt - 4 - False - AllRules.ruleset - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - AllRules.ruleset - - - true - - - servicestack-sn.pfx - - - - - 3.5 - - - 3.5 - - - - ..\..\lib\signed\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\signed\ServiceStack.Text.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Source.csproj b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Source.csproj new file mode 100644 index 000000000..25c2c7673 --- /dev/null +++ b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.Source.csproj @@ -0,0 +1,51 @@ + + + + ServiceStack.OrmLite + ServiceStack.OrmLite + netstandard2.0;net6.0 + OrmLite - Fast, code-first, config-free POCO ORM + + Common library for the Light, simple and fast convention-based code-first POCO, OrmLite. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs. + OrmLite is a suite extension methods on ADO.NET's underlying IDbConnection providing DRY, typed access for common data usage patterns that map to clean, simple POCOs. Great support for testing where OrmLite methods can be mocked. + + OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + false + $(DefineConstants);ASYNC + + + $(DefineConstants);NETCORE;NETSTANDARD2_0 + + + $(DefineConstants);NETCORE;NET6_0;NET6_0_OR_GREATER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj index 3eb67056c..d17d41029 100644 --- a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj +++ b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj @@ -1,201 +1,55 @@ - - + + - Debug - AnyCPU - 9.0.30729 - 2.0 - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - Library - Properties - ServiceStack.OrmLite + ServiceStack.OrmLite ServiceStack.OrmLite - v4.0 - 512 - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - + net472;netstandard2.0;net6.0 + OrmLite - Fast, code-first, config-free POCO ORM + + Common library for the Light, simple and fast convention-based code-first POCO, OrmLite. + Support for Creating and Dropping Table Schemas from POCOs, Complex Property types transparently stored in schemaless text blobs. + OrmLite is a suite extension methods on ADO.NET's underlying IDbConnection providing DRY, typed access for common data usage patterns that map to clean, simple POCOs. Great support for testing where OrmLite methods can be mocked. + + OrmLite;RDBMS;SQL;POCO;Code-First;ORM;Schema-less;Blobs + $(DefineConstants);ASYNC - - True - full - False - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset + + $(DefineConstants);NETCORE;NETSTANDARD2_0 - - pdbonly - True - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - bin\Release\ServiceStack.OrmLite.xml - - - True - bin\STATIC_ONLY NO_EXPRESSIONS\ - DEBUG;TRACE - full - AnyCPU - prompt - 4 - False - AllRules.ruleset - - - True - bin\MonoTouch\ - TRACE;DEBUG;STATIC_ONLY NO_EXPRESSIONS - full - AnyCPU - prompt - 4 - False - AllRules.ruleset - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - AllRules.ruleset + + $(DefineConstants);NETCORE;NET6_0 + - - - 3.5 - - - 3.5 - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - + + + + + + + + + + - - - + + + + + + + + + + - - - - \ No newline at end of file + + diff --git a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj.user b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj.user deleted file mode 100644 index 5fea7996b..000000000 --- a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj.user +++ /dev/null @@ -1,14 +0,0 @@ - - - - ProjectFiles - - - - - - - en-US - false - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.iOS.csproj b/src/ServiceStack.OrmLite/ServiceStack.OrmLite.iOS.csproj deleted file mode 100644 index 3862bcc22..000000000 --- a/src/ServiceStack.OrmLite/ServiceStack.OrmLite.iOS.csproj +++ /dev/null @@ -1,103 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07} - {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Library - ServiceStack.OrmLite.iOS - Resources - ServiceStack.OrmLite.iOS - - - true - full - false - bin\iPhone\Debug - DEBUG;NO_EXPRESSIONS - prompt - 4 - false - true - iPhone Developer - - - none - true - bin\iPhone\Release - prompt - 4 - false - iPhone Developer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ..\..\lib\ServiceStack.Common.MonoTouch.dll - - - ..\..\lib\ServiceStack.Interfaces.MonoTouch.dll - - - ..\..\lib\ServiceStack.Text.MonoTouch.dll - False - - - - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/SqlBuilder.cs b/src/ServiceStack.OrmLite/SqlBuilder.cs index 9076dd49d..9c388f61c 100644 --- a/src/ServiceStack.OrmLite/SqlBuilder.cs +++ b/src/ServiceStack.OrmLite/SqlBuilder.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using System.Data; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Text.RegularExpressions; using System.Threading; using ServiceStack.Text; +using PropertyAttributes = System.Reflection.PropertyAttributes; namespace ServiceStack.OrmLite { @@ -54,7 +56,7 @@ public void AddDynamicParams(object cmdParams) if (cmdParams == null) return; foreach (var pi in cmdParams.GetType().GetPublicProperties()) { - var getterFn = pi.GetPropertyGetterFn(); + var getterFn = pi.CreateGetter(); if (getterFn == null) continue; var value = getterFn(cmdParams); properties.Add(new Property(pi.Name, pi.PropertyType, value)); @@ -67,11 +69,17 @@ public void AddDynamicParams(object cmdParams) public object CreateDynamicType() { var assemblyName = new AssemblyName { Name = "tmpAssembly" }; +#if NETCORE + var typeBuilder = + AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run) + .DefineDynamicModule("tmpModule") + .DefineType("SqlBuilderDynamicParameters", TypeAttributes.Public | TypeAttributes.Class); +#else var typeBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run) .DefineDynamicModule("tmpModule") .DefineType("SqlBuilderDynamicParameters", TypeAttributes.Public | TypeAttributes.Class); - +#endif var emptyCtor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); var ctorIL = emptyCtor.GetILGenerator(); @@ -136,7 +144,11 @@ public object CreateDynamicType() ctorIL.Emit(OpCodes.Ret); +#if NETCORE + var generetedType = typeBuilder.CreateTypeInfo().AsType(); +#else var generetedType = typeBuilder.CreateType(); +#endif var instance = Activator.CreateInstance(generetedType); //Using reflection for less property types. Not caching since it's a generated type. @@ -215,15 +227,16 @@ void ResolveSql() public string RawSql { get { ResolveSql(); return rawSql; } } public object Parameters { get { ResolveSql(); return parameters; } } - public string ToSelectStatement() - { - return RawSql; - } + public List Params { get; private set; } - public string SelectInto() + public string ToSelectStatement() => ToSelectStatement(QueryType.Select); + public string ToSelectStatement(QueryType forType) { return RawSql; } + + public string SelectInto() => RawSql; + public string SelectInto(QueryType queryType) => RawSql; } public Template AddTemplate(string sql, object parameters = null) diff --git a/src/ServiceStack.OrmLite/SqlInValues.cs b/src/ServiceStack.OrmLite/SqlInValues.cs index 5ebbd948a..a873a5e5e 100644 --- a/src/ServiceStack.OrmLite/SqlInValues.cs +++ b/src/ServiceStack.OrmLite/SqlInValues.cs @@ -4,27 +4,35 @@ namespace ServiceStack.OrmLite { public class SqlInValues { + public const string EmptyIn = "NULL"; + private readonly IEnumerable values; private readonly IOrmLiteDialectProvider dialectProvider; - public int Count { get; private set; } + public int Count { get; } public SqlInValues(IEnumerable values, IOrmLiteDialectProvider dialectProvider=null) { this.values = values; this.dialectProvider = dialectProvider ?? OrmLiteConfig.DialectProvider; - if (values != null) - foreach (var value in values) - ++Count; + if (values == null) return; + foreach (var value in values) + { + ++Count; + } } public string ToSqlInString() { - if (Count == 0) - return "NULL"; + return Count == 0 + ? EmptyIn + : OrmLiteUtils.SqlJoin(values, dialectProvider); + } - return OrmLiteUtils.SqlJoin(values, dialectProvider); + public IEnumerable GetValues() + { + return values; } } } \ No newline at end of file diff --git a/src/ServiceStack.OrmLite/Support/LoadList.cs b/src/ServiceStack.OrmLite/Support/LoadList.cs index 711fbde5e..052803f14 100644 --- a/src/ServiceStack.OrmLite/Support/LoadList.cs +++ b/src/ServiceStack.OrmLite/Support/LoadList.cs @@ -3,15 +3,17 @@ using System.Collections.Generic; using System.Data; using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Support { internal abstract class LoadList { protected IDbCommand dbCmd; - protected SqlExpression expr; + protected SqlExpression q; protected IOrmLiteDialectProvider dialectProvider; protected List parentResults; @@ -19,42 +21,42 @@ internal abstract class LoadList protected List fieldDefs; protected string subSql; - public List FieldDefs - { - get { return fieldDefs; } - } + public List FieldDefs => fieldDefs; - public List ParentResults - { - get { return parentResults; } - } + public List ParentResults => parentResults; - protected LoadList(IDbCommand dbCmd, SqlExpression expr) + protected LoadList(IDbCommand dbCmd, SqlExpression q) { dialectProvider = dbCmd.GetDialectProvider(); - if (expr == null) - expr = dialectProvider.SqlExpression(); + if (q == null) + q = dialectProvider.SqlExpression(); this.dbCmd = dbCmd; - this.expr = expr; + this.q = q; - var sql = expr.SelectInto(); - parentResults = dbCmd.ExprConvertToList(sql); + //Use .Clone() to prevent SqlExpressionSelectFilter from adding params to original query + var parentQ = q.Clone(); + var sql = parentQ.SelectInto(QueryType.Select); + parentResults = dbCmd.ExprConvertToList(sql, parentQ.Params, onlyFields:q.OnlyFields); modelDef = ModelDefinition.Definition; fieldDefs = modelDef.AllFieldDefinitionsArray.Where(x => x.IsReference).ToList(); - subSql = dialectProvider.GetLoadChildrenSubSelect(modelDef, expr); + var subQ = q.Clone(); + var subQSql = dialectProvider.GetLoadChildrenSubSelect(subQ); + subSql = dialectProvider.MergeParamsIntoSql(subQSql, subQ.Params); } protected string GetRefListSql(ModelDefinition refModelDef, FieldDefinition refField) { - var sqlRef = "SELECT {0} FROM {1} WHERE {2} IN ({3})".Fmt( - dialectProvider.GetColumnNames(refModelDef), - dialectProvider.GetQuotedTableName(refModelDef), - dialectProvider.GetQuotedColumnName(refField), - subSql); + var sqlRef = $"SELECT {dialectProvider.GetColumnNames(refModelDef)} " + + $"FROM {dialectProvider.GetQuotedTableName(refModelDef)} " + + $"WHERE {dialectProvider.GetQuotedColumnName(refField)} " + + $"IN ({subSql})"; + + if (OrmLiteConfig.LoadReferenceSelectFilter != null) + sqlRef = OrmLiteConfig.LoadReferenceSelectFilter(refModelDef.ModelType, sqlRef); return sqlRef; } @@ -81,39 +83,78 @@ protected void SetListChildResults(FieldDefinition fieldDef, Type refType, IList if (map.TryGetValue(pkValue, out refValues)) { var castResults = untypedApi.Cast(refValues); - fieldDef.SetValueFn(result, castResults); + fieldDef.SetValue(result, castResults); } } } - protected string GetRefSelfSql(FieldDefinition refSelf, ModelDefinition refModelDef) + protected string GetRefSelfSql(ModelDefinition modelDef, FieldDefinition refSelf, ModelDefinition refModelDef) { //Load Self Table.RefTableId PK - expr.Select(dialectProvider.GetQuotedColumnName(refSelf)); - var subSqlRef = expr.ToSelectStatement(); + var refQ = q.Clone(); + refQ.Select(dialectProvider.GetQuotedColumnName(modelDef, refSelf)); + refQ.OrderBy().ClearLimits(); //clear any ORDER BY or LIMIT's in Sub Select's + + var subSqlRef = refQ.ToMergedParamsSelectStatement(); - var sqlRef = "SELECT {0} FROM {1} WHERE {2} IN ({3})".Fmt( - dialectProvider.GetColumnNames(refModelDef), - dialectProvider.GetQuotedTableName(refModelDef), - dialectProvider.GetQuotedColumnName(refModelDef.PrimaryKey), - subSqlRef); + var sqlRef = $"SELECT {dialectProvider.GetColumnNames(refModelDef)} " + + $"FROM {dialectProvider.GetQuotedTableName(refModelDef)} " + + $"WHERE {dialectProvider.GetQuotedColumnName(refModelDef.PrimaryKey)} " + + $"IN ({subSqlRef})"; + + if (OrmLiteConfig.LoadReferenceSelectFilter != null) + sqlRef = OrmLiteConfig.LoadReferenceSelectFilter(refModelDef.ModelType, sqlRef); return sqlRef; } protected string GetRefFieldSql(ModelDefinition refModelDef, FieldDefinition refField) { - var sqlRef = "SELECT {0} FROM {1} WHERE {2} IN ({3})".Fmt( - dialectProvider.GetColumnNames(refModelDef), - dialectProvider.GetQuotedTableName(refModelDef), - dialectProvider.GetQuotedColumnName(refField), - subSql); + var sqlRef = $"SELECT {dialectProvider.GetColumnNames(refModelDef)} " + + $"FROM {dialectProvider.GetQuotedTableName(refModelDef)} " + + $"WHERE {dialectProvider.GetQuotedColumnName(refField)} " + + $"IN ({subSql})"; + + if (OrmLiteConfig.LoadReferenceSelectFilter != null) + sqlRef = OrmLiteConfig.LoadReferenceSelectFilter(refModelDef.ModelType, sqlRef); + return sqlRef; } + protected Dictionary CreateRefMap() + { + return OrmLiteConfig.IsCaseInsensitive + ? new Dictionary(CaseInsensitiveObjectComparer.Instance) + : new Dictionary(); + } + + public class CaseInsensitiveObjectComparer : IEqualityComparer + { + public static CaseInsensitiveObjectComparer Instance = new CaseInsensitiveObjectComparer(); + + public new bool Equals(object x, object y) + { + if (x == null && y == null) return true; + if (x == null || y == null) return false; + + var xStr = x as string; + var yStr = y as string; + + return xStr != null && yStr != null + ? xStr.Equals(yStr, StringComparison.OrdinalIgnoreCase) + : x.Equals(y); + } + + public int GetHashCode(object obj) + { + var str = obj as string; + return str?.ToUpper().GetHashCode() ?? obj.GetHashCode(); + } + } + protected void SetRefSelfChildResults(FieldDefinition fieldDef, ModelDefinition refModelDef, FieldDefinition refSelf, IList childResults) { - var map = new Dictionary(); + var map = CreateRefMap(); foreach (var result in childResults) { @@ -123,18 +164,17 @@ protected void SetRefSelfChildResults(FieldDefinition fieldDef, ModelDefinition foreach (var result in parentResults) { - object childResult; var fkValue = refSelf.GetValue(result); - if (fkValue != null && map.TryGetValue(fkValue, out childResult)) + if (fkValue != null && map.TryGetValue(fkValue, out var childResult)) { - fieldDef.SetValueFn(result, childResult); + fieldDef.SetValue(result, childResult); } } } protected void SetRefFieldChildResults(FieldDefinition fieldDef, FieldDefinition refField, IList childResults) { - var map = new Dictionary(); + var map = CreateRefMap(); foreach (var result in childResults) { @@ -144,11 +184,10 @@ protected void SetRefFieldChildResults(FieldDefinition fieldDef, FieldDefinition foreach (var result in parentResults) { - object childResult; var pkValue = modelDef.PrimaryKey.GetValue(result); - if (map.TryGetValue(pkValue, out childResult)) + if (map.TryGetValue(pkValue, out var childResult)) { - fieldDef.SetValueFn(result, childResult); + fieldDef.SetValue(result, childResult); } } } @@ -156,7 +195,7 @@ protected void SetRefFieldChildResults(FieldDefinition fieldDef, FieldDefinition internal class LoadListSync : LoadList { - public LoadListSync(IDbCommand dbCmd, SqlExpression expr) : base(dbCmd, expr) {} + public LoadListSync(IDbCommand dbCmd, SqlExpression q) : base(dbCmd, q) {} public void SetRefFieldList(FieldDefinition fieldDef, Type refType) { @@ -181,7 +220,7 @@ public void SetRefField(FieldDefinition fieldDef, Type refType) if (refSelf != null) { - var sqlRef = GetRefSelfSql(refSelf, refModelDef); + var sqlRef = GetRefSelfSql(modelDef, refSelf, refModelDef); var childResults = dbCmd.ConvertToList(refType, sqlRef); SetRefSelfChildResults(fieldDef, refModelDef, refSelf, childResults); } @@ -194,7 +233,7 @@ public void SetRefField(FieldDefinition fieldDef, Type refType) } } -#if NET45 +#if ASYNC internal class LoadListAsync : LoadList { public LoadListAsync(IDbCommand dbCmd, SqlExpression expr) : base(dbCmd, expr) { } @@ -206,7 +245,7 @@ public async Task SetRefFieldListAsync(FieldDefinition fieldDef, Type refType, C var sqlRef = GetRefListSql(refModelDef, refField); - var childResults = await dbCmd.ConvertToListAsync(refType, sqlRef, token); + var childResults = await dbCmd.ConvertToListAsync(refType, sqlRef, token).ConfigAwait(); SetListChildResults(fieldDef, refType, childResults, refField); } @@ -220,17 +259,17 @@ public async Task SetRefFieldAsync(FieldDefinition fieldDef, Type refType, Cance ? modelDef.GetRefFieldDef(refModelDef, refType) : modelDef.GetRefFieldDefIfExists(refModelDef); - if (refField != null) + if (refSelf != null) { - var sqlRef = GetRefFieldSql(refModelDef, refField); - var childResults = await dbCmd.ConvertToListAsync(refType, sqlRef, token); - SetRefFieldChildResults(fieldDef, refField, childResults); + var sqlRef = GetRefSelfSql(modelDef, refSelf, refModelDef); + var childResults = await dbCmd.ConvertToListAsync(refType, sqlRef, token).ConfigAwait(); + SetRefSelfChildResults(fieldDef, refModelDef, refSelf, childResults); } - else if (refSelf != null) + else if (refField != null) { - var sqlRef = GetRefSelfSql(refSelf, refModelDef); - var childResults = await dbCmd.ConvertToListAsync(refType, sqlRef, token); - SetRefSelfChildResults(fieldDef, refModelDef, refSelf, childResults); + var sqlRef = GetRefFieldSql(refModelDef, refField); + var childResults = await dbCmd.ConvertToListAsync(refType, sqlRef, token).ConfigAwait(); + SetRefFieldChildResults(fieldDef, refField, childResults); } } } diff --git a/src/ServiceStack.OrmLite/Support/LoadReferences.cs b/src/ServiceStack.OrmLite/Support/LoadReferences.cs index 0f4ffe125..5da08f745 100644 --- a/src/ServiceStack.OrmLite/Support/LoadReferences.cs +++ b/src/ServiceStack.OrmLite/Support/LoadReferences.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Support { @@ -27,10 +28,7 @@ protected LoadReferences(IDbCommand dbCmd, T instance) dialectProvider = dbCmd.GetDialectProvider(); } - public List FieldDefs - { - get { return fieldDefs; } - } + public List FieldDefs => fieldDefs; protected string GetRefListSql(Type refType) { @@ -41,6 +39,9 @@ protected string GetRefListSql(Type refType) var sqlFilter = dialectProvider.GetQuotedColumnName(refField.FieldName) + "={0}"; var sql = dialectProvider.ToSelectStatement(refType, sqlFilter, pkValue); + if (OrmLiteConfig.LoadReferenceSelectFilter != null) + sql = OrmLiteConfig.LoadReferenceSelectFilter(refType, sql); + return sql; } @@ -48,6 +49,10 @@ protected string GetRefFieldSql(Type refType, FieldDefinition refField) { var sqlFilter = dialectProvider.GetQuotedColumnName(refField.FieldName) + "={0}"; var sql = dialectProvider.ToSelectStatement(refType, sqlFilter, pkValue); + + if (OrmLiteConfig.LoadReferenceSelectFilter != null) + sql = OrmLiteConfig.LoadReferenceSelectFilter(refType, sql); + return sql; } @@ -55,8 +60,15 @@ protected string GetRefSelfSql(Type refType, FieldDefinition refSelf, ModelDefin { //Load Self Table.RefTableId PK var refPkValue = refSelf.GetValue(instance); + if (refPkValue == null) + return null; + var sqlFilter = dialectProvider.GetQuotedColumnName(refModelDef.PrimaryKey.FieldName) + "={0}"; var sql = dialectProvider.ToSelectStatement(refType, sqlFilter, refPkValue); + + if (OrmLiteConfig.LoadReferenceSelectFilter != null) + sql = OrmLiteConfig.LoadReferenceSelectFilter(refType, sql); + return sql; } } @@ -71,7 +83,7 @@ public void SetRefFieldList(FieldDefinition fieldDef, Type refType) var sql = GetRefListSql(refType); var results = dbCmd.ConvertToList(refType, sql); - fieldDef.SetValueFn(instance, results); + fieldDef.SetValue(instance, results); } public void SetRefField(FieldDefinition fieldDef, Type refType) @@ -86,19 +98,22 @@ public void SetRefField(FieldDefinition fieldDef, Type refType) if (refSelf != null) { var sql = GetRefSelfSql(refType, refSelf, refModelDef); + if (sql == null) + return; + var result = dbCmd.ConvertTo(refType, sql); - fieldDef.SetValueFn(instance, result); + fieldDef.SetValue(instance, result); } else if (refField != null) { var sql = GetRefFieldSql(refType, refField); var result = dbCmd.ConvertTo(refType, sql); - fieldDef.SetValueFn(instance, result); + fieldDef.SetValue(instance, result); } } } -#if NET45 +#if ASYNC internal class LoadReferencesAsync : LoadReferences { public LoadReferencesAsync(IDbCommand dbCmd, T instance) @@ -108,8 +123,8 @@ public async Task SetRefFieldList(FieldDefinition fieldDef, Type refType, Cancel { var sql = GetRefListSql(refType); - var results = await dbCmd.ConvertToListAsync(refType, sql, token); - fieldDef.SetValueFn(instance, results); + var results = await dbCmd.ConvertToListAsync(refType, sql, token).ConfigAwait(); + fieldDef.SetValue(instance, results); } public async Task SetRefField(FieldDefinition fieldDef, Type refType, CancellationToken token) @@ -124,14 +139,17 @@ public async Task SetRefField(FieldDefinition fieldDef, Type refType, Cancellati if (refField != null) { var sql = GetRefFieldSql(refType, refField); - var result = await dbCmd.ConvertToAsync(refType, sql, token); - fieldDef.SetValueFn(instance, result); + var result = await dbCmd.ConvertToAsync(refType, sql, token).ConfigAwait(); + fieldDef.SetValue(instance, result); } else if (refSelf != null) { var sql = GetRefSelfSql(refType, refSelf, refModelDef); - var result = await dbCmd.ConvertToAsync(refType, sql, token); - fieldDef.SetValueFn(instance, result); + if (sql == null) + return; + + var result = await dbCmd.ConvertToAsync(refType, sql, token).ConfigAwait(); + fieldDef.SetValue(instance, result); } } } diff --git a/src/ServiceStack.OrmLite/UntypedApi.cs b/src/ServiceStack.OrmLite/UntypedApi.cs index 370eaf40b..369a7c760 100644 --- a/src/ServiceStack.OrmLite/UntypedApi.cs +++ b/src/ServiceStack.OrmLite/UntypedApi.cs @@ -16,7 +16,7 @@ public static class UntypedApiExtensions public static IUntypedApi CreateTypedApi(this IDbConnection db, Type forType) { - var genericType = untypedApiMap.GetOrAdd(forType, key => typeof(UntypedApi<>).MakeGenericType(key)); + var genericType = untypedApiMap.GetOrAdd(forType, key => typeof(UntypedApi<>).GetCachedGenericType(key)); var unTypedApi = genericType.CreateInstance(); unTypedApi.Db = db; return unTypedApi; @@ -24,11 +24,18 @@ public static IUntypedApi CreateTypedApi(this IDbConnection db, Type forType) public static IUntypedApi CreateTypedApi(this IDbCommand dbCmd, Type forType) { - var genericType = untypedApiMap.GetOrAdd(forType, key => typeof(UntypedApi<>).MakeGenericType(key)); + var genericType = untypedApiMap.GetOrAdd(forType, key => typeof(UntypedApi<>).GetCachedGenericType(key)); var unTypedApi = genericType.CreateInstance(); unTypedApi.DbCmd = dbCmd; return unTypedApi; } + + public static IUntypedApi CreateTypedApi(this Type forType) + { + var genericType = untypedApiMap.GetOrAdd(forType, key => typeof(UntypedApi<>).GetCachedGenericType(key)); + var unTypedApi = genericType.CreateInstance(); + return unTypedApi; + } } public class UntypedApi : IUntypedApi @@ -36,7 +43,12 @@ public class UntypedApi : IUntypedApi public IDbConnection Db { get; set; } public IDbCommand DbCmd { get; set; } - public T Exec(Func filter) + public TReturn Exec(Func filter) + { + return DbCmd != null ? filter(DbCmd) : Db.Exec(filter); + } + + public Task Exec(Func> filter) { return DbCmd != null ? filter(DbCmd) : Db.Exec(filter); } @@ -59,7 +71,7 @@ public bool Save(object obj) return Exec(dbCmd => dbCmd.Save((T)obj)); } -#if NET45 +#if ASYNC public Task SaveAllAsync(IEnumerable objs, CancellationToken token) { return Exec(dbCmd => dbCmd.SaveAllAsync((IEnumerable)objs, token)); @@ -83,12 +95,22 @@ public Task SaveAsync(object obj, CancellationToken token) public void InsertAll(IEnumerable objs) { - Exec(dbCmd => dbCmd.InsertAll((IEnumerable)objs)); + Exec(dbCmd => dbCmd.InsertAll((IEnumerable)objs, commandFilter:null)); + } + + public void InsertAll(IEnumerable objs, Action commandFilter) + { + Exec(dbCmd => dbCmd.InsertAll((IEnumerable)objs, commandFilter:commandFilter)); } public long Insert(object obj, bool selectIdentity = false) { - return Exec(dbCmd => dbCmd.Insert((T)obj, selectIdentity: selectIdentity)); + return Exec(dbCmd => dbCmd.Insert((T)obj, commandFilter: null, selectIdentity: selectIdentity)); + } + + public long Insert(object obj, Action commandFilter, bool selectIdentity = false) + { + return Exec(dbCmd => dbCmd.Insert((T)obj, commandFilter: commandFilter, selectIdentity: selectIdentity)); } public int UpdateAll(IEnumerable objs) @@ -96,11 +118,21 @@ public int UpdateAll(IEnumerable objs) return Exec(dbCmd => dbCmd.UpdateAll((IEnumerable)objs)); } + public int UpdateAll(IEnumerable objs, Action commandFilter) + { + return Exec(dbCmd => dbCmd.UpdateAll((IEnumerable)objs, commandFilter: commandFilter)); + } + public int Update(object obj) { return Exec(dbCmd => dbCmd.Update((T)obj)); } + public int Update(object obj, Action commandFilter) + { + return Exec(dbCmd => dbCmd.Update((T)obj, commandFilter: commandFilter)); + } + public int DeleteAll() { return Exec(dbCmd => dbCmd.DeleteAll()); diff --git a/src/ServiceStack.OrmLite/UpperCaseNamingStrategy.cs b/src/ServiceStack.OrmLite/UpperCaseNamingStrategy.cs deleted file mode 100644 index 00e409ad3..000000000 --- a/src/ServiceStack.OrmLite/UpperCaseNamingStrategy.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace ServiceStack.OrmLite -{ - public class UpperCaseNamingStrategy : OrmLiteNamingStrategyBase - { - public override string GetTableName(string name) - { - return name.ToUpper(); - } - - public override string GetColumnName(string name) - { - return name.ToUpper(); - } - } -} diff --git a/src/ServiceStack.OrmLiteV45/Properties/AssemblyInfo.cs b/src/ServiceStack.OrmLiteV45/Properties/AssemblyInfo.cs deleted file mode 100644 index 4761da58d..000000000 --- a/src/ServiceStack.OrmLiteV45/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("ServiceStack")] -[assembly: AssemblyProduct("ServiceStack.OrmLite")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("49a8aed0-90c5-4477-a8c1-6bda4a72da63")] - -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] diff --git a/src/ServiceStack.OrmLiteV45/ServiceStack.OrmLiteV45.Signed.csproj b/src/ServiceStack.OrmLiteV45/ServiceStack.OrmLiteV45.Signed.csproj deleted file mode 100644 index 92097be2d..000000000 --- a/src/ServiceStack.OrmLiteV45/ServiceStack.OrmLiteV45.Signed.csproj +++ /dev/null @@ -1,254 +0,0 @@ - - - - - Debug - AnyCPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689} - Library - Properties - ServiceStack.OrmLite - ServiceStack.OrmLite - v4.5 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET45 - prompt - 4 - - - bin\Signed\ - TRACE;NET45 - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - true - - - servicestack-sn.pfx - - - - ..\..\lib\signed\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\signed\ServiceStack.Text.dll - - - - - - - - - AliasNamingStrategy.cs - - - Async\OrmLiteReadCommandExtensionsAsync.cs - - - Async\OrmLiteResultsFilterExtensionsAsync.cs - - - Async\OrmLiteUtilExtensionsAsync.cs - - - Async\OrmLiteWriteCommandExtensionsAsync.cs - - - Async\ReadExpressionCommandExtensionsAsync.cs - - - Async\WriteExpressionCommandExtensionsAsync.cs - - - Dapper\SqlMapper.cs - - - DbTypes.cs - - - Expressions\ParameterRebinder.cs - - - Expressions\PredicateBuilder.cs - - - Expressions\ReadExpressionCommandExtensions.cs - - - Expressions\Sql.cs - - - Expressions\SqlExpression.cs - - - Expressions\SqlExpression.Join.cs - - - Expressions\SqlExpressionVisitor.cs - - - Expressions\WriteExpressionCommandExtensions.cs - - - FieldDefinition.cs - - - INamingStrategy.cs - - - IOrmLiteDialectProvider.cs - - - IPropertyInvoker.cs - - - IUntypedApi.cs - - - JoinSqlBuilder.cs - - - ModelDefinition.cs - - - OrmLiteCommand.cs - - - OrmLiteConfig.cs - - - OrmLiteConfigExtensions.cs - - - OrmLiteConnection.cs - - - OrmLiteConnectionFactory.cs - - - OrmLiteContext.cs - - - OrmLiteDialectProviderBase.cs - - - OrmLiteDialectProviderExtensions.cs - - - OrmLiteExecFilter.cs - - - OrmLiteNamingStrategyBase.cs - - - OrmLitePersistenceProvider.cs - - - OrmLiteReadApi.cs - - - OrmLiteReadApiAsync.cs - - - OrmLiteReadCommandExtensions.cs - - - OrmLiteReadExpressionsApi.cs - - - OrmLiteReadExpressionsApiAsync.cs - - - OrmLiteResultsFilter.cs - - - OrmLiteResultsFilterExtensions.cs - - - OrmLiteSchemaApi.cs - - - OrmLiteSchemaModifyApi.cs - - - OrmLiteSPStatement.cs - - - OrmLiteTransaction.cs - - - OrmLiteUtils.cs - - - OrmLiteWriteApi.cs - - - OrmLiteWriteApiAsync.cs - - - OrmLiteWriteCommandExtensions.cs - - - OrmLiteWriteExpressionsApi.cs - - - OrmLiteWriteExpressionsApiAsync.cs - - - PropertyInvoker.cs - - - ReflectionPropertyInvoker.cs - - - SqlBuilder.cs - - - SqlInValues.cs - - - Support\LoadList.cs - - - Support\LoadReferences.cs - - - UntypedApi.cs - - - UpperCaseNamingStrategy.cs - - - - - - - \ No newline at end of file diff --git a/src/ServiceStack.OrmLiteV45/ServiceStack.OrmLiteV45.csproj b/src/ServiceStack.OrmLiteV45/ServiceStack.OrmLiteV45.csproj deleted file mode 100644 index 9ce65fd40..000000000 --- a/src/ServiceStack.OrmLiteV45/ServiceStack.OrmLiteV45.csproj +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Debug - AnyCPU - {FDC37335-9ECC-413B-BEC5-16B466B0E689} - Library - Properties - ServiceStack.OrmLite - ServiceStack.OrmLite - v4.5 - 512 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45 - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE;NET45 - prompt - 4 - - - bin\Signed\ - TRACE;NET45 - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - AliasNamingStrategy.cs - - - Async\OrmLiteReadCommandExtensionsAsync.cs - - - Async\OrmLiteResultsFilterExtensionsAsync.cs - - - Async\OrmLiteUtilExtensionsAsync.cs - - - Async\OrmLiteWriteCommandExtensionsAsync.cs - - - Async\ReadExpressionCommandExtensionsAsync.cs - - - Async\WriteExpressionCommandExtensionsAsync.cs - - - Dapper\SqlMapper.cs - - - DbTypes.cs - - - Expressions\ParameterRebinder.cs - - - Expressions\PredicateBuilder.cs - - - Expressions\ReadExpressionCommandExtensions.cs - - - Expressions\Sql.cs - - - Expressions\SqlExpression.cs - - - Expressions\SqlExpression.Join.cs - - - Expressions\SqlExpressionVisitor.cs - - - Expressions\WriteExpressionCommandExtensions.cs - - - FieldDefinition.cs - - - INamingStrategy.cs - - - IOrmLiteDialectProvider.cs - - - IPropertyInvoker.cs - - - IUntypedApi.cs - - - JoinSqlBuilder.cs - - - ModelDefinition.cs - - - OrmLiteCommand.cs - - - OrmLiteConfig.cs - - - OrmLiteConfigExtensions.cs - - - OrmLiteConnection.cs - - - OrmLiteConnectionFactory.cs - - - OrmLiteContext.cs - - - OrmLiteDialectProviderBase.cs - - - OrmLiteDialectProviderExtensions.cs - - - OrmLiteExecFilter.cs - - - OrmLiteNamingStrategyBase.cs - - - OrmLitePersistenceProvider.cs - - - OrmLiteReadApi.cs - - - OrmLiteReadApiAsync.cs - - - OrmLiteReadCommandExtensions.cs - - - OrmLiteReadExpressionsApi.cs - - - OrmLiteReadExpressionsApiAsync.cs - - - OrmLiteResultsFilter.cs - - - OrmLiteResultsFilterExtensions.cs - - - OrmLiteSchemaApi.cs - - - OrmLiteSchemaModifyApi.cs - - - OrmLiteSPStatement.cs - - - OrmLiteTransaction.cs - - - OrmLiteUtils.cs - - - OrmLiteWriteApi.cs - - - OrmLiteWriteApiAsync.cs - - - OrmLiteWriteCommandExtensions.cs - - - OrmLiteWriteExpressionsApi.cs - - - OrmLiteWriteExpressionsApiAsync.cs - - - PropertyInvoker.cs - - - ReflectionPropertyInvoker.cs - - - SqlBuilder.cs - - - SqlInValues.cs - - - Support\LoadList.cs - - - Support\LoadReferences.cs - - - UntypedApi.cs - - - UpperCaseNamingStrategy.cs - - - - - - - \ No newline at end of file diff --git a/src/SqlServerExpressionsTest/IgnoredFieldSelectTest.cs b/src/SqlServerExpressionsTest/IgnoredFieldSelectTest.cs deleted file mode 100644 index 0449a7f39..000000000 --- a/src/SqlServerExpressionsTest/IgnoredFieldSelectTest.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Linq; -using ServiceStack.OrmLite; -using System.Data; -using ServiceStack.DataAnnotations; - -namespace SqlServerExpressionsTest -{ - public class User_2 - { - public long Id { get; set; } - - [Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - - public long? UserDataId { get; set; } - - public long UserServiceId { get; set; } - - [Ignore] - [Alias("DataValue")] - public string UserDataValue { get; set; } - - [Ignore] - [Alias("ServiceName")] - public string UserServiceName { get; set; } - } - - [Alias("UserData_2")] - public class UserData_2 - { - public long Id { get; set; } - public string DataValue { get; set; } - } - - [Alias("UserService_2")] - public class UserService_2 - { - public long Id { get; set; } - public string ServiceName { get; set; } - } - - - public class IgnoredFieldSelectTest - { - public static void Test(string connectionString) - { - //using (IDbConnection db = ":memory:".OpenDbConnection()) - using (IDbConnection db = connectionString.OpenDbConnection()) - { - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - - //Insert Test - db.Insert(new UserData_2 { Id = 5, DataValue = "Value-5" }); - db.Insert(new UserData_2 { Id = 6, DataValue = "Value-6" }); - - db.Insert(new UserService_2 { Id = 8, ServiceName = "Value-8" }); - db.Insert(new UserService_2 { Id = 9, ServiceName = "Value-9" }); - - var user2 = new User_2 { Id = 1, Name = "A", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 8 }; - db.Insert(user2); - db.Insert(new User_2 { Id = 2, Name = "B", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 9 }); - db.Insert(new User_2 { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - - //Update Test - user2.CreatedDate = DateTime.Now; - db.Update(user2,x=>x.Id == 1); - - //Select Test - - var rowsB = db.SelectFmt("Name = {0}", "B"); - var rowsB1 = db.Select(user => user.Name == "B"); - - var rowsUData = db.Select(); - var rowsUServ = db.Select(); - - var jn2 = new JoinSqlBuilder(); - jn2 = jn2.Join(x => x.UserDataId, x => x.Id, x => new { x.Name, x.Id }, x => new { x.DataValue}) - .Join(x => x.UserServiceId, x => x.Id, null, x => new { x.ServiceName }) - .OrderByDescending(x => x.Name) - .OrderBy(x => x.Id) - .Select(x => x.Id); - - var sql2 = jn2.ToSql(); - var items2 = db.Select(sql2); - Console.WriteLine("Ignored Field Selected Items - {0}",items2.Count()); - - var item = db.Single(sql2); - - } - } - } -} diff --git a/src/SqlServerExpressionsTest/JoinTest.cs b/src/SqlServerExpressionsTest/JoinTest.cs deleted file mode 100644 index 0d484614e..000000000 --- a/src/SqlServerExpressionsTest/JoinTest.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using ServiceStack.OrmLite; -using System.Data; -using ServiceStack.DataAnnotations; - -namespace SqlServerExpressionsTest -{ - public class User - { - public long Id { get; set; } - - [Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - - public long? UserDataId { get; set; } - - public long UserServiceId { get; set; } - - } - - public class UserEx - { - [BelongTo(typeof(User))] - public long Id { get; set; } - [BelongTo(typeof(User))] - public string Name { get; set; } - public DateTime CreatedDate { get; set; } - [BelongTo(typeof(UserData))] - public string UserDataValue { get; set; } - [BelongTo(typeof(UserService))] - [Alias("ServiceName")] - public string UserServiceName { get; set; } - } - - - [Alias("UserData")] - public class UserData - { - [AutoIncrement] - public long Id { get; set; } - public string UserDataValue { get; set; } - } - - [Alias("UserService")] - public class UserService - { - [AutoIncrement] - public long Id { get; set; } - public string ServiceName { get; set; } - } - - public class JoinTest - { - public static void Test(string connectionString) - { - //using (IDbConnection db = ":memory:".OpenDbConnection()) - using (IDbConnection db = connectionString.OpenDbConnection()) - { - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - - db.Insert(new UserData { Id = 5, UserDataValue = "Value-5" }); - db.Insert(new UserData { Id = 6, UserDataValue = "Value-6" }); - - db.Insert(new UserService { Id = 8, ServiceName = "Value-8" }); - db.Insert(new UserService { Id = 9, ServiceName = "Value-9" }); - - db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 8 }); - db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 9 }); - db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - - - var rowsB = db.SelectFmt("Name = {0}", "B"); - var rowsB1 = db.Select(user => user.Name == "B"); - - var jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id, x => new { x.Name, x.Id }, x => new { x.UserDataValue }) - .LeftJoin(x => x.UserServiceId, x => x.Id, null, x => new { x.ServiceName }) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .Select(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql = jn.ToSql(); - var items = db.Select(sql); - - jn.Clear(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x => x.Id) - .OrderByDescending(x => x.ServiceName) - .Where(x => x.Id > 0) - .Or(x => x.Id < 10) - .And(x => x.Name != "" || x.Name != null); - - var sql2 = jn.ToSql(); - var item = db.Single(sql2); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .SelectAll() - .Where(x=> x.Id == 0); - - var sql3 = jn.ToSql(); - var items3 = db.Select(sql3); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id, x => new { x.Name, x.Id }, x => new { x.UserDataValue }) - .LeftJoin(x => x.UserServiceId, x => x.Id, null, x => new { x.ServiceName }) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .SelectDistinct() - .SelectAll() - .Where(x=> x.Id == 0); - - var sql4 = jn.ToSql(); - var items4 = db.Select(sql4); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .SelectCount(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql5 = jn.ToSql(); - var items5 = db.ScalarFmt(sql5); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectMax(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql6 = jn.ToSql(); - var items6 = db.ScalarFmt(sql6); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectMin(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql7 = jn.ToSql(); - var items7 = db.ScalarFmt(sql7); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectAverage(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql8 = jn.ToSql(); - var items8 = db.ScalarFmt(sql8); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectSum(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql9 = jn.ToSql(); - var items9 = db.ScalarFmt(sql9); - - } - } - } -} diff --git a/src/SqlServerExpressionsTest/Program.cs b/src/SqlServerExpressionsTest/Program.cs deleted file mode 100644 index a93031f31..000000000 --- a/src/SqlServerExpressionsTest/Program.cs +++ /dev/null @@ -1,300 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Data; -using ServiceStack; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.SqlServer; - - -namespace SqlServerExpressionsTest -{ - public class Author - { - public Author() { } - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set; } - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set; } - public DateTime Birthday { get; set; } - public DateTime? LastActivity { get; set; } - public Decimal? Earnings { get; set; } - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set; } - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set; } - public Int16 Rate { get; set; } - } - - - - class MainClass - { - public static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - - OrmLiteConfig.DialectProvider = SqlServerOrmLiteDialectProvider.Instance; - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - Console.WriteLine("Join Test"); - //JoinTest.Test(GetFileConnectionString()); - - Console.WriteLine("Ignored Field Select Test"); - IgnoredFieldSelectTest.Test(GetFileConnectionString()); - - using (IDbConnection db = GetFileConnectionString().OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.DeleteAll(); - - var authors = new List { - new Author { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }, - new Author { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }, - new Author { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }, - new Author { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }, - new Author { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }, - new Author { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }, - new Author { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }, - new Author { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }, - new Author { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }, - new Author { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }, - new Author { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }, - new Author { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }, - new Author { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }, - new Author { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico" }, - }; - - db.InsertAll(authors); - - - // lets start! - // select authors born 20 year ago - int year = DateTime.Today.AddYears(-20).Year; - int expected=5; - - ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - List result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31))); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected = 6; - ev.Where(rn => Sql.In(rn.City, new object[] { "London", "Madrid", "Berlin" })); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => Sql.In(rn.City, "London", "Madrid", "Berlin")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from Bogota and Cartagena : 7 - expected = 7; - ev.Where(rn => Sql.In(rn.City, new object[] { "Bogota", "Cartagena" })); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name starts with A - expected = 3; - ev.Where(rn => rn.Name.StartsWith("A")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.StartsWith("A")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected = 3; - ev.Where(rn => rn.Name.ToUpper().EndsWith("GARZON")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.ToUpper().EndsWith("GARZON")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected = 3; - ev.Where(rn => rn.Name.EndsWith("garzon")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name contains Benedict - expected = 2; - ev.Where(rn => rn.Name.Contains("Benedict")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors with Earnings <= 50 - expected = 3; - ev.Where(rn => rn.Earnings <= 50); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Earnings <= 50); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors with Rate = 10 and city=Mexio - expected = 1; - ev.Where(rn => rn.Rate == 10 && rn.City == "Mexico"); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected = 2; - ev.Where(rn => rn.Rate == 0).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected == rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected = 4; - ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); - ev.Where(rn => !rn.Active); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - //update comment for City == null - expected = 2; - ev.Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected == rows); - - // delete where City is null - expected = 2; - rows = db.Delete(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected == rows); - - - - // lets select all records ordered by Rate Descending and Name Ascending - expected = 14; - ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - Console.WriteLine(ev.OrderByExpression); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel", author.Name, "Claudia Espinel" == author.Name); - - // select only first 5 rows .... - - //TODO: SqlServer expression impl doesn't handle Limit/Offset - - //expected = 5; - //ev.Limit(5); // note: order is the same as in the last sentence - //result = db.Select(ev); - //Console.WriteLine(ev.WhereExpression); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); - Console.WriteLine(ev.SelectExpression); - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name); - - //paging : - //ev.Limit(0, 4);// first page, page size=4; - //result = db.Select(ev); - //author = result.FirstOrDefault(); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name); - - //ev.Limit(4, 4);// second page - //result = db.Select(ev); - //author = result.FirstOrDefault(); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper() == author.Name); - - //ev.Limit(8, 4);// third page - //result = db.Select(ev); - //author = result.FirstOrDefault(); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper() == author.Name); - - // select distinct.. - //ev.Limit(); // clear limit - //ev.SelectDistinct(r => r.City); - //expected = 6; - //result = db.Select(ev); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - Console.WriteLine(); - // Tests for predicate overloads that make use of the expression visitor - Console.WriteLine("First author by name (exists)"); - author = db.Single(a => a.Name == "Jorge Garzon"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon", author.Name, "Jorge Garzon" == author.Name); - - try - { - Console.WriteLine("First author by name (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - - Console.WriteLine("Expected exception thrown, OK? False"); - } - catch - { - Console.WriteLine("Expected exception thrown, OK? True"); - } - - Console.WriteLine("First author or default (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - Console.WriteLine("Expected:null ; OK? {0}", author == null); - - Console.WriteLine("First author or default by city (multiple matches)"); - author = db.Single(a => a.City == "Bogota"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Angel Colmenares", author.Name, "Angel Colmenares" == author.Name); - - - Console.ReadLine(); - Console.WriteLine("Press Enter to continue"); - - } - - Console.WriteLine("This is The End my friend!"); - } - - - private static string GetFileConnectionString() - { - var connectionString = "~/test.mdf".MapAbsolutePath(); - - - return connectionString; - } - - } -} \ No newline at end of file diff --git a/src/SqlServerExpressionsTest/Properties/AssemblyInfo.cs b/src/SqlServerExpressionsTest/Properties/AssemblyInfo.cs deleted file mode 100644 index 02db8cf6e..000000000 --- a/src/SqlServerExpressionsTest/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SqlServerExpressionsTets")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SqlServerExpressionsTets")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("9aed4094-fae8-4623-9c4d-6a8dce0ea60b")] - diff --git a/src/SqlServerExpressionsTest/SqlServerExpressionsTest.csproj b/src/SqlServerExpressionsTest/SqlServerExpressionsTest.csproj deleted file mode 100644 index f1a8ab30e..000000000 --- a/src/SqlServerExpressionsTest/SqlServerExpressionsTest.csproj +++ /dev/null @@ -1,143 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {19825530-1D25-4528-AB6D-E236809A7F34} - Exe - Properties - SqlServerExpressionsTest - SqlServerExpressionsTest - 512 - false - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - bin\Signed\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\tests\ServiceStack.Text.dll - - - - - - - - - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - - - {1887DC99-9139-43E3-A7AA-6D74714B3A5D} - ServiceStack.OrmLite.SqlServer - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - Always - - - test.mdf - Always - - - - - False - Microsoft .NET Framework 4 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - SQL Server 2008 Express - true - - - False - Windows Installer 3.1 - true - - - False - Windows Installer 4.5 - true - - - - - \ No newline at end of file diff --git a/src/SqlServerExpressionsTest/test.mdf b/src/SqlServerExpressionsTest/test.mdf deleted file mode 100644 index 6d61eaf6c..000000000 Binary files a/src/SqlServerExpressionsTest/test.mdf and /dev/null differ diff --git a/src/SqlServerExpressionsTest/test_log.LDF b/src/SqlServerExpressionsTest/test_log.LDF deleted file mode 100644 index 5513b5c77..000000000 Binary files a/src/SqlServerExpressionsTest/test_log.LDF and /dev/null differ diff --git a/src/SqliteExpressionsTest/CountTest.cs b/src/SqliteExpressionsTest/CountTest.cs deleted file mode 100644 index 2e96faf1f..000000000 --- a/src/SqliteExpressionsTest/CountTest.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using ServiceStack; -using ServiceStack.OrmLite; -using System.IO; -using System.Data; -using ServiceStack.OrmLite.Sqlite; - -namespace SqliteExpressionsTest -{ - - public class CountTest - { - private static string GetFileConnectionString() - { - var connectionString = "~/db.sqlite".MapAbsolutePath(); - if (File.Exists(connectionString)) - File.Delete(connectionString); - - return connectionString; - } - - public static void Test() - { - OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance; - - var path = GetFileConnectionString(); - if (File.Exists(path)) - File.Delete(path); - //using (IDbConnection db = ":memory:".OpenDbConnection()) - using (IDbConnection db = path.OpenDbConnection()) - { - db.CreateTable(true); - - db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 8 }); - db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 9 }); - db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - var count1 = db.Count(x => x.Id == 1); - var count2 = db.Count(ev.Where(x => x.Id == 2)); - var count3 = db.Count(); - - count1 = db.Count(x => x.Id == 1); - count2 = db.Count(ev.Where(x => x.Id == 2)); - count3 = db.Count(); - } - - File.Delete(path); - } - } -} diff --git a/src/SqliteExpressionsTest/IgnoredFieldSelectTest.cs b/src/SqliteExpressionsTest/IgnoredFieldSelectTest.cs deleted file mode 100644 index b24692312..000000000 --- a/src/SqliteExpressionsTest/IgnoredFieldSelectTest.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Linq; -using ServiceStack; -using ServiceStack.OrmLite; -using System.IO; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Sqlite; - -namespace SqliteExpressionsTest -{ - public class User_2 - { - public long Id { get; set; } - - [Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - - public long? UserDataId { get; set; } - - public long UserServiceId { get; set; } - - [Ignore] - [Alias("DataValue")] - public string UserDataValue { get; set; } - - [Ignore] - [Alias("ServiceName")] - public string UserServiceName { get; set; } - } - - [Alias("UserData_2")] - public class UserData_2 - { - public long Id { get; set; } - public string DataValue { get; set; } - } - - [Alias("UserService_2")] - public class UserService_2 - { - public long Id { get; set; } - public string ServiceName { get; set; } - } - - - public class IgnoredFieldSelectTest - { - private static string GetFileConnectionString() - { - var connectionString = "~/db.sqlite".MapAbsolutePath(); - if (File.Exists(connectionString)) - File.Delete(connectionString); - - return connectionString; - } - - - public static void Test() - { - OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance; - - var path = GetFileConnectionString(); - if (File.Exists(path)) - File.Delete(path); - //using (IDbConnection db = ":memory:".OpenDbConnection()) - using (IDbConnection db = path.OpenDbConnection()) - { - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - - //Insert Test - db.Insert(new UserData_2 { Id = 5, DataValue = "Value-5" }); - db.Insert(new UserData_2 { Id = 6, DataValue = "Value-6" }); - - db.Insert(new UserService_2 { Id = 8, ServiceName = "Value-8" }); - db.Insert(new UserService_2 { Id = 9, ServiceName = "Value-9" }); - - var user2 = new User_2 { Id = 1, Name = "A", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 8 }; - db.Insert(user2); - db.Insert(new User_2 { Id = 2, Name = "B", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 9 }); - db.Insert(new User_2 { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - - //Update Test - user2.CreatedDate = DateTime.Now; - db.Update(user2,x=>x.Id == 1); - - //Select Test - - var rowsB = db.SelectFmt("Name = {0}", "B"); - var rowsB1 = db.Select(user => user.Name == "B"); - - var rowsUData = db.Select(); - var rowsUServ = db.Select(); - - var jn2 = new JoinSqlBuilder(); - jn2 = jn2.Join(x => x.UserDataId, x => x.Id, x => new { x.Name, x.Id }, x => new { x.DataValue}) - .Join(x => x.UserServiceId, x => x.Id, null, x => new { x.ServiceName }) - .OrderByDescending(x => x.Name) - .OrderBy(x => x.Id) - .Select(x => x.Id); - - var sql2 = jn2.ToSql(); - var items2 = db.Select(sql2); - Console.WriteLine("Ignored Field Selected Items - {0}",items2.Count()); - - var item = db.Single(sql2); - - } - - File.Delete(path); - } - } -} diff --git a/src/SqliteExpressionsTest/JoinTest.cs b/src/SqliteExpressionsTest/JoinTest.cs deleted file mode 100644 index 7523e147e..000000000 --- a/src/SqliteExpressionsTest/JoinTest.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using ServiceStack; -using ServiceStack.OrmLite; -using System.IO; -using System.Data; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Sqlite; - -namespace SqliteExpressionsTest -{ - public class User - { - public long Id { get; set; } - - [Index] - public string Name { get; set; } - - public DateTime CreatedDate { get; set; } - - public long? UserDataId { get; set; } - - public long UserServiceId { get; set; } - - } - - public class UserEx - { - [BelongTo(typeof(User))] - public long Id { get; set; } - [BelongTo(typeof(User))] - public string Name { get; set; } - [BelongTo(typeof(User))] - public DateTime CreatedDate { get; set; } - [BelongTo(typeof(UserData))] - public string UserDataValue { get; set; } - [BelongTo(typeof(UserService))] - [Alias("ServiceName")] - public string UserServiceName { get; set; } - } - - - [Alias("UserData")] - public class UserData - { - [AutoIncrement] - public long Id { get; set; } - public string UserDataValue { get; set; } - } - - [Alias("UserService")] - public class UserService - { - [AutoIncrement] - public long Id { get; set; } - public string ServiceName { get; set; } - } - - public class JoinTest - { - private static string GetFileConnectionString() - { - var connectionString = "~/db.sqlite".MapAbsolutePath(); - if (File.Exists(connectionString)) - File.Delete(connectionString); - - return connectionString; - } - - - public static void Test() - { - OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance; - - var path = GetFileConnectionString(); - if (File.Exists(path)) - File.Delete(path); - //using (IDbConnection db = ":memory:".OpenDbConnection()) - using (IDbConnection db = path.OpenDbConnection()) - { - db.CreateTable(true); - db.CreateTable(true); - db.CreateTable(true); - - db.Insert(new UserData { Id = 5, UserDataValue = "Value-5" }); - db.Insert(new UserData { Id = 6, UserDataValue = "Value-6" }); - - db.Insert(new UserService { Id = 8, ServiceName = "Value-8" }); - db.Insert(new UserService { Id = 9, ServiceName = "Value-9" }); - - db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 8 }); - db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now, UserDataId = 5, UserServiceId = 9 }); - db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - - - var rowsB = db.SelectFmt("Name = {0}", "B"); - var rowsB1 = db.Select(user => user.Name == "B"); - - var jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id, x => new { x.Name, x.Id }, x => new { x.UserDataValue }) - .LeftJoin(x => x.UserServiceId, x => x.Id, null, x => new { x.ServiceName }) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .Select(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql = jn.ToSql(); - var items = db.Select(sql); - - jn.Clear(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x => x.Id) - .OrderByDescending(x => x.ServiceName) - .Where(x => x.Id > 0) - .Or(x => x.Id < 10) - .And(x => x.Name != "" || x.Name != null); - - var sql2 = jn.ToSql(); - var item = db.Single(sql2); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .SelectAll() - .Where(x=> x.Id == 0); - - var sql3 = jn.ToSql(); - var items3 = db.Select(sql3); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id, x => new { x.Name, x.Id }, x => new { x.UserDataValue }) - .LeftJoin(x => x.UserServiceId, x => x.Id, null, x => new { x.ServiceName }) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .SelectDistinct() - .SelectAll() - .Where(x=> x.Id == 0); - - var sql4 = jn.ToSql(); - var items4 = db.Select(sql4); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x=>x.Name) - .OrderBy(x=>x.Id) - .SelectCount(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql5 = jn.ToSql(); - var items5 = db.ScalarFmt(sql5); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectMax(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql6 = jn.ToSql(); - var items6 = db.ScalarFmt(sql6); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectMin(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql7 = jn.ToSql(); - var items7 = db.ScalarFmt(sql7); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectAverage(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql8 = jn.ToSql(); - var items8 = db.ScalarFmt(sql8); - - jn.Clear(); - jn = new JoinSqlBuilder(); - jn = jn.Join(x => x.UserDataId, x => x.Id) - .LeftJoin(x => x.UserServiceId, x => x.Id) - .OrderByDescending(x => x.Name) - .OrderBy(x=>x.Id) - .SelectSum(x=>x.Id) - .Where(x=> x.Id == 0); - - var sql9 = jn.ToSql(); - var items9 = db.ScalarFmt(sql9); - - } - - File.Delete(path); - } - } -} diff --git a/src/SqliteExpressionsTest/Program.cs b/src/SqliteExpressionsTest/Program.cs deleted file mode 100644 index 0af96b3f2..000000000 --- a/src/SqliteExpressionsTest/Program.cs +++ /dev/null @@ -1,304 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Collections.Generic; -using System.Data; -using ServiceStack; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Sqlite; - - -namespace SqliteExpressionsTest -{ - public class Author - { - public Author(){} - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - public DateTime Birthday { get; set;} - public DateTime ? LastActivity { get; set;} - public Decimal? Earnings { get; set;} - public bool Active { get; set; } - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - public Int16 Rate{ get; set;} - } - - - - class MainClass - { - public static void Main (string[] args) - { - Console.WriteLine ("Hello World!"); - - Console.WriteLine("Join Test"); - JoinTest.Test(); - - Console.WriteLine("Ignored Field Select Test"); - IgnoredFieldSelectTest.Test(); - - Console.WriteLine("Count Test"); - CountTest.Test(); - - OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance; - SqlExpression ev = OrmLiteConfig.DialectProvider.SqlExpression(); - - using (IDbConnection db = GetFileConnectionString().OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.DeleteAll(); - - List authors = new List(); - authors.Add(new Author(){Name="Demis Bellot",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 99.9m,Comments="CSharp books", Rate=10, City="London"}); - authors.Add(new Author(){Name="Angel Colmenares",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 50.0m,Comments="CSharp books", Rate=5, City="Bogota"}); - authors.Add(new Author(){Name="Adam Witco",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 80.0m,Comments="Math Books", Rate=9, City="London"}); - authors.Add(new Author(){Name="Claudia Espinel",Birthday= DateTime.Today.AddYears(-23),Active=true,Earnings= 60.0m,Comments="Cooking books", Rate=10, City="Bogota"}); - authors.Add(new Author(){Name="Libardo Pajaro",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 80.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Jorge Garzon",Birthday= DateTime.Today.AddYears(-28),Active=true,Earnings= 70.0m,Comments="CSharp books", Rate=9, City="Bogota"}); - authors.Add(new Author(){Name="Alejandro Isaza",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 70.0m,Comments="Java books", Rate=0, City="Bogota"}); - authors.Add(new Author(){Name="Wilmer Agamez",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 30.0m,Comments="Java books", Rate=0, City="Cartagena"}); - authors.Add(new Author(){Name="Rodger Contreras",Birthday= DateTime.Today.AddYears(-25),Active=true,Earnings= 90.0m,Comments="CSharp books", Rate=8, City="Cartagena"}); - authors.Add(new Author(){Name="Chuck Benedict",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="CSharp books", Rate=8, City="London"}); - authors.Add(new Author(){Name="James Benedict II",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.5m,Comments="Java books", Rate=5, City="Berlin"}); - authors.Add(new Author(){Name="Ethan Brown",Birthday= DateTime.Today.AddYears(-20),Active=true,Earnings= 45.0m,Comments="CSharp books", Rate=5, City="Madrid"}); - authors.Add(new Author(){Name="Xavi Garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 75.0m,Comments="CSharp books", Rate=9, City="Madrid"}); - authors.Add(new Author(){Name="Luis garzon",Birthday= DateTime.Today.AddYears(-22),Active=true,Earnings= 85.0m,Comments="CSharp books", Rate=10, City="Mexico"}); - - db.InsertAll(authors); - - - // lets start ! - - // select authors born 20 year ago - int year = DateTime.Today.AddYears(-20).Year; - int expected=5; - - ev.Where(rn=> rn.Birthday>=new DateTime(year, 1,1) && rn.Birthday<=new DateTime(year, 12,31)); - List result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31))); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected=6; - ev.Where(rn=> Sql.In( rn.City, new object[]{"London", "Madrid", "Berlin"}) ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from Bogota and Cartagena : 7 - expected=7; - ev.Where(rn => Sql.In(rn.City, new object[] { "Bogota", "Cartagena" })); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name starts with A - expected=3; - ev.Where(rn=> rn.Name.StartsWith("A") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => rn.Name.StartsWith("A")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected=3; - ev.Where(rn=> rn.Name.ToUpper().EndsWith("GARZON") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => rn.Name.ToUpper().EndsWith("GARZON")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected=3; - ev.Where(rn=> rn.Name.EndsWith("garzon") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name contains Benedict - expected=2; - ev.Where(rn=> rn.Name.Contains("Benedict") ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors with Earnings <= 50 - expected=3; - ev.Where(rn=> rn.Earnings<=50 ); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => rn.Earnings <= 50); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors with Rate = 10 and city=Mexio - expected=1; - ev.Where(rn=> rn.Rate==10 && rn.City=="Mexico"); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected=2; - ev.Where(rn=> rn.Rate==0 ).Update(rn=> rn.Active); - var rows = db.UpdateOnly( new Author(){ Active=false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected=4; - ev.Insert(rn =>new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate} ); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Victor Grozny", Birthday=DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly( new Author(){Active=false, Rate=0, Name="Ivan Chorny", Birthday=DateTime.Today.AddYears(-19) }, ev); - ev.Where(rn=> !rn.Active); - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - //update comment for City == null - expected=2; - ev.Where( rn => rn.City==null ).Update(rn=> rn.Comments); - rows=db.UpdateOnly(new Author(){Comments="No comments"}, ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - // delete where City is null - expected=2; - rows = db.Delete( ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected==rows); - - - - // lets select all records ordered by Rate Descending and Name Ascending - expected=14; - ev.Where().OrderBy(rn=> new{ at=Sql.Desc(rn.Rate), rn.Name }); // clear where condition - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - Console.WriteLine(ev.OrderByExpression); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel", author.Name, "Claudia Espinel"==author.Name); - - // select only first 5 rows .... - - expected=5; - ev.Limit(5); // note: order is the same as in the last sentence - result=db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - ev.Select(rn=> new { at= Sql.As( rn.Name.ToUpper(), "Name" ), rn.City} ); - Console.WriteLine(ev.SelectExpression); - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - //paging : - ev.Limit(0,4);// first page, page size=4; - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper()==author.Name); - - ev.Limit(4,4);// second page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper()==author.Name); - - ev.Limit(8,4);// third page - result=db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper()==author.Name); - - // select distinct.. - ev.Limit(); // clear limit - ev.SelectDistinct(r=>r.City); - expected=6; - result=db.Select(ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected==result.Count); - - - Console.WriteLine(); - // Tests for predicate overloads that make use of the expression visitor - Console.WriteLine("First author by name (exists)"); - author = db.Single(a => a.Name == "Jorge Garzon"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon", author.Name, "Jorge Garzon"==author.Name); - - try - { - Console.WriteLine("First author by name (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - - Console.WriteLine("Expected exception thrown, OK? False"); - } - catch - { - Console.WriteLine("Expected exception thrown, OK? True"); - } - - Console.WriteLine("First author or default (does not exist)"); - author = db.Single(a => a.Name == "Does not exist"); - Console.WriteLine("Expected:null ; OK? {0}", author == null); - - Console.WriteLine("First author or default by city (multiple matches)"); - author = db.Single(a => a.City == "Bogota"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Angel Colmenares", author.Name, "Angel Colmenares"==author.Name); - - - Console.ReadLine(); - Console.WriteLine("Press Enter to continue"); - - } - - Console.WriteLine ("This is The End my friend!"); - } - - - private static string GetFileConnectionString() - { - var connectionString = "~/db.sqlite".MapAbsolutePath(); - if (File.Exists(connectionString)) - File.Delete(connectionString); - - return connectionString; - } - - } -} \ No newline at end of file diff --git a/src/SqliteExpressionsTest/Properties/AssemblyInfo.cs b/src/SqliteExpressionsTest/Properties/AssemblyInfo.cs deleted file mode 100644 index 48ec879e4..000000000 --- a/src/SqliteExpressionsTest/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Using directives - -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -#endregion - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SqliteExpressionsTest")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SqliteExpressionsTest")] -[assembly: AssemblyCopyright("Copyright 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// This sets the default COM visibility of types in the assembly to invisible. -// If you need to expose a type to COM, use [ComVisible(true)] on that type. -[assembly: ComVisible(false)] - diff --git a/src/SqliteExpressionsTest/SqliteExpressionsTest.csproj b/src/SqliteExpressionsTest/SqliteExpressionsTest.csproj deleted file mode 100644 index 90dae3494..000000000 --- a/src/SqliteExpressionsTest/SqliteExpressionsTest.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - {7CF9CE3E-F5FE-4C73-843F-57A64B202743} - Debug - x86 - Exe - SqliteExpressionsTest - SqliteExpressionsTest - Properties - 10.0.0 - 2.0 - - - x86 - - - bin\Debug\ - True - Full - False - True - DEBUG;TRACE - - - bin\Release\ - False - None - True - False - TRACE - - - 4 - - - 4 - - - bin\x86\Signed\ - TRACE - true - None - x86 - MinimumRecommendedRules.ruleset - - - - ..\..\lib\Mono.Data.Sqlite.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - 3.5 - - - 3.5 - - - - 3.5 - - - - 3.5 - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - - - - - - - {CF68A37D-D071-469D-AE04-68594CB95382} - ServiceStack.OrmLite.Sqlite - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - \ No newline at end of file diff --git a/src/SqliteExpressionsTest/app.config b/src/SqliteExpressionsTest/app.config deleted file mode 100644 index 88f2be5e2..000000000 --- a/src/SqliteExpressionsTest/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/T4/OrmLite.Core.ttinclude b/src/T4/OrmLite.Core.ttinclude index 5cf67a3a8..e9043b6be 100644 --- a/src/T4/OrmLite.Core.ttinclude +++ b/src/T4/OrmLite.Core.ttinclude @@ -1,3 +1,4 @@ + <#@ template language="C#" hostspecific="True" #> <#@ assembly name="EnvDTE" #> <#@ assembly name="System.Core.dll" #> @@ -16,12 +17,12 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Text.RegularExpressions" #> <#@ import namespace="System.Configuration" #> -<#@ import namespace="System.Windows.Forms" #> +<#@ import namespace="System.Windows.Forms" #> <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> <#+ /* - This is code is based on the T4 template from the PetaPoco project which in turn is based on the subsonic project. + This code is based on the T4 template from the PetaPoco project which in turn is based on the subsonic project. ----------------------------------------------------------------------------------------- @@ -86,6 +87,8 @@ string ClassPrefix = ""; string ClassSuffix = ""; string SchemaName = null; bool IncludeViews = false; +bool IncludeFunctions = false; +bool IncludeSPReturnTypes = false; //Will create {StoredProcName}_Result classes for any SPs with output results public class Table { @@ -95,6 +98,7 @@ public class Table public string Name; public string Schema; public bool IsView; + public bool IsFunction; public string CleanName; public string ClassName; public string SequenceName; @@ -196,6 +200,7 @@ public class TableIndex public class FKey { public string ToTable; + public string ToTableSingular; public string FromColumn; public string ToColumn; } @@ -208,9 +213,11 @@ public class SP public string Schema; public string SchemaQualifiedName {get{return Schema+"."+Name;}} public List Parameters; + public List SPOutputColumns; public SP() { Parameters=new List(); + SPOutputColumns = new List(); } public string ArgList { @@ -230,6 +237,12 @@ public class SP } } +public class SPOutputColumn +{ + public string Name ; + public string DotNetType ; +} + public enum SPParamDir { OutDirection, @@ -264,8 +277,14 @@ static Func CleanUp = (str) => { str = rxCleanUp.Replace(str, "_"); - if (char.IsDigit(str[0]) || cs_keywords.Contains(str)) + if (char.IsDigit(str[0])) + { + str = "_" + str; + } + else if (cs_keywords.Contains(str)) + { str = "@" + str; + } return str; }; @@ -283,6 +302,8 @@ static string CheckNullable(Column col) return result; } + + string GetConnectionString(ref string connectionStringName, out string providerName) { var _CurrentProject = GetCurrentProject(); @@ -520,7 +541,7 @@ Tables LoadTables(bool makeSingular) else { // Assume SQL Server - reader=new SqlServerSchemaReader(); + reader=new SqlServerSchemaReader(IncludeSPReturnTypes); } reader.outer=this; @@ -534,11 +555,11 @@ Tables LoadTables(bool makeSingular) result.RemoveAt(i); continue; } - if (!IncludeViews && result[i].IsView) + if ((!IncludeViews && result[i].IsView) ||(!IncludeFunctions && result[i].IsFunction)) { result.RemoveAt(i); continue; - } + } } } @@ -589,6 +610,21 @@ List SPsNotSupported(string providerName) return new List(); } +string GetParamDirection(SPParamDir direction) + { + switch(direction) + { + case SPParamDir.InAndOutDirection: + return "ParameterDirection.InputOutput"; + case SPParamDir.OutDirection: + return "ParameterDirection.Output"; + case SPParamDir.InDirection: + default: + return "ParameterDirection.Input"; + } + } + + List LoadSPs() { InitConnectionString(); @@ -666,7 +702,7 @@ List LoadSPs() else { // Assume SQL Server - reader=new SqlServerSchemaReader(); + reader=new SqlServerSchemaReader(IncludeSPReturnTypes); } reader.outer=this; @@ -781,17 +817,25 @@ static int GetDatatypeSize(string type) return -1; } +// Edit here to get a method to read the proc class SqlServerSchemaReader : SchemaReader { + private bool IncludeSPReturnTypes; + public SqlServerSchemaReader(bool includeSPReturnTypes) + { + IncludeSPReturnTypes = includeSPReturnTypes; + } // SchemaReader.ReadSchema + + public override Tables ReadSchema(DbConnection connection, DbProviderFactory factory) { - var result=new Tables(); + var result = new Tables(); _connection=connection; _factory=factory; - var cmd=_factory.CreateCommand(); + var cmd = _factory.CreateCommand(); cmd.Connection=connection; cmd.CommandText=TABLE_SQL; @@ -807,13 +851,41 @@ class SqlServerSchemaReader : SchemaReader tbl.Name=rdr["TABLE_NAME"].ToString(); tbl.Schema=rdr["TABLE_SCHEMA"].ToString(); tbl.IsView=string.Compare(rdr["TABLE_TYPE"].ToString(), "View", true)==0; + tbl.IsFunction=string.Compare(rdr["TABLE_TYPE"].ToString(), "TVF", true)==0; tbl.CleanName=CleanUp(tbl.Name); tbl.ClassName=Inflector.MakeSingular(tbl.CleanName); - + result.Add(tbl); } } } + + var cmdFks = _factory.CreateCommand(); + cmdFks.Connection=connection; + cmdFks.CommandText=FOREIGN_KEYS_SQL; + //get all the foreign keys and add them to the tables. + using(cmdFks) + { + using (var rdr=cmdFks.ExecuteReader()) + { + while(rdr.Read()) + { + var tableName = rdr["TableWithForeignKey"].ToString(); + var table = result.FirstOrDefault(x => x.Name == tableName); + if (table != null) { + if (table.FKeys == null) { + table.FKeys = new List(); + } + var newForeignKey = new FKey(); + newForeignKey.ToTable = rdr["TargetTable"].ToString(); + newForeignKey.ToTableSingular = Inflector.MakeSingular(CleanUp(newForeignKey.ToTable)); + newForeignKey.FromColumn = rdr["ForeignKeyColumn"].ToString(); + newForeignKey.ToColumn = rdr["TargetTableKey"].ToString(); + table.FKeys.Add(newForeignKey); + } + } + } + } foreach (var tbl in result) { @@ -862,6 +934,7 @@ class SqlServerSchemaReader : SchemaReader foreach (var sp in result) { sp.Parameters=LoadSPParams(sp); + if (IncludeSPReturnTypes) sp.SPOutputColumns = LoadSPOutputColumns(sp); } return result; } @@ -947,6 +1020,43 @@ class SqlServerSchemaReader : SchemaReader } } + List LoadSPOutputColumns(SP sp) + { + var result=new List(); + using (var cmd=_factory.CreateCommand()) + { + cmd.Connection=_connection; + cmd.CommandText=string.Format(@"SELECT name,CAST(is_nullable as VARCHAR(1)) is_nullable,system_type_name FROM sys.dm_exec_describe_first_result_set_for_object(OBJECT_ID('{0}'), 1) WHERE is_hidden = 0",sp.SchemaQualifiedName); + using (IDataReader rdr=cmd.ExecuteReader()) + { + while(rdr.Read()) + { + if (!rdr.IsDBNull(0)) + { + SPOutputColumn param=new SPOutputColumn(); + param.Name = rdr["name"].ToString(); + + var sqlType = rdr["system_type_name"].ToString(); + var index = sqlType.IndexOf('('); //Trim off size data + if (index > 0) sqlType = sqlType.Substring(0,index); + + var nullable = rdr["is_nullable"].ToString() ; + if (nullable == "0") + { + param.DotNetType = GetPropertyType(sqlType); + } + else + { + param.DotNetType = GetNullablePropertyType(sqlType); + } + if (!result.Any(t=>t.Name == param.Name)) result.Add(param); + } + } + } + } + return result; + } + string GetPK(string table){ @@ -1043,10 +1153,13 @@ class SqlServerSchemaReader : SchemaReader case "datetime": case "datetime2": case "date": - case "time": sysType= "DateTime"; sysDbType = "DbType.DateTime"; break; + case "time": + sysType= "TimeSpan"; + sysDbType = "DbType.DateTime"; + break; case "datetimeoffset": sysType = "DateTimeOffset"; sysDbType = "DbType.DateTimeOffset"; @@ -1115,8 +1228,10 @@ class SqlServerSchemaReader : SchemaReader case "datetime": case "datetime2": case "date": + sysType= "DateTime"; + break; case "time": - sysType= "DateTime"; + sysType= "TimeSpan"; break; case "datetimeoffset": sysType = "DateTimeOffset"; @@ -1156,25 +1271,67 @@ class SqlServerSchemaReader : SchemaReader } - const string TABLE_SQL=@"SELECT * - FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW'"; - - const string COLUMN_SQL=@"SELECT - TABLE_CATALOG AS [Database], - TABLE_SCHEMA AS Owner, - TABLE_NAME AS TableName, - COLUMN_NAME AS ColumnName, - ORDINAL_POSITION AS OrdinalPosition, - COLUMN_DEFAULT AS DefaultSetting, - IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, - CHARACTER_MAXIMUM_LENGTH AS MaxLength, - DATETIME_PRECISION AS DatePrecision, - COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity, - COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_NAME=@tableName AND TABLE_SCHEMA=@schemaName - ORDER BY OrdinalPosition ASC"; + const string TABLE_SQL=@"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW' + UNION + SELECT SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME, 'TVF' FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'FUNCTION' AND DATA_TYPE = 'TABLE'"; + + const string COLUMN_SQL=@"SELECT T.[Database] , + T.Owner , + T.TableName , + T.ColumnName , + T.OrdinalPosition , + T.DefaultSetting , + T.IsNullable , + T.DataType , + T.MaxLength , + T.DatePrecision , + T.IsIdentity , + T.IsComputed FROM ( + SELECT + TABLE_CATALOG AS [Database], + TABLE_SCHEMA AS Owner, + TABLE_NAME AS TableName, + COLUMN_NAME AS ColumnName, + ORDINAL_POSITION AS OrdinalPosition, + COLUMN_DEFAULT AS DefaultSetting, + IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, + CHARACTER_MAXIMUM_LENGTH AS MaxLength, + DATETIME_PRECISION AS DatePrecision, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME=@tableName AND TABLE_SCHEMA=@schemaName + --ORDER BY OrdinalPosition ASC + UNION + SELECT TABLE_CATALOG AS [Database], + TABLE_SCHEMA AS Owner, + TABLE_NAME AS TableName, + COLUMN_NAME AS ColumnName, + ORDINAL_POSITION AS OrdinalPosition, + COLUMN_DEFAULT AS DefaultSetting, + IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, + CHARACTER_MAXIMUM_LENGTH AS MaxLength, + DATETIME_PRECISION AS DatePrecision, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity, + COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed + FROM INFORMATION_SCHEMA.ROUTINE_COLUMNS + WHERE TABLE_NAME=@tableName AND TABLE_SCHEMA=@schemaName + ) T + ORDER BY T.OrdinalPosition ASC"; + + const string FOREIGN_KEYS_SQL= +@"SELECT DISTINCT + tableWithForeignKey.name AS TableWithForeignKey, + columnWithForeignKey.name AS ForeignKeyColumn, + referencedTable.name AS TargetTable, + referencedColumn.name AS TargetTableKey +FROM sys.foreign_key_columns foreignKeyColumn +INNER JOIN sys.tables tableWithForeignKey ON tableWithForeignKey.object_id = foreignKeyColumn.parent_object_id +INNER JOIN sys.columns columnWithForeignKey ON columnWithForeignKey.object_id = foreignKeyColumn.parent_object_id + AND columnWithForeignKey.column_id = foreignKeyColumn.parent_column_id +INNER JOIN sys.tables referencedTable ON referencedTable.object_id = foreignKeyColumn.referenced_object_id +INNER JOIN sys.columns referencedColumn ON referencedColumn.object_id = foreignKeyColumn.referenced_object_id + AND referencedColumn.column_id = foreignKeyColumn.referenced_column_id"; const string SP_NAMES_SQL=@"SELECT o.name AS sp_name, s.name AS schema_name FROM sys.objects o @@ -1187,7 +1344,7 @@ WHERE o.type = 'P' 'sysdiagrams' )"; - const string SP_PARAMETERS_SQL=@"SELECT * from information_schema.PARAMETERS + const string SP_PARAMETERS_SQL=@"SELECT * from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME = @spname order by ORDINAL_POSITION"; @@ -1431,6 +1588,33 @@ class PostGreSqlSchemaReader : SchemaReader } } +var cmdFks = _factory.CreateCommand(); + cmdFks.Connection=connection; + cmdFks.CommandText=FOREIGN_KEYS_SQL; + //get all the foreign keys and add them to the tables. + using(cmdFks) + { + using (var rdr=cmdFks.ExecuteReader()) + { + while(rdr.Read()) + { + var tableName = rdr["TableWithForeignKey"].ToString(); + var table = result.FirstOrDefault(x => x.Name == tableName); + if (table != null) { + if (table.FKeys == null) { + table.FKeys = new List(); + } + var newForeignKey = new FKey(); + newForeignKey.ToTable = rdr["TargetTable"].ToString(); + newForeignKey.ToTableSingular = Inflector.MakeSingular(CleanUp(newForeignKey.ToTable)); + newForeignKey.FromColumn = rdr["ForeignKeyColumn"].ToString(); + newForeignKey.ToColumn = rdr["TargetTableKey"].ToString(); + table.FKeys.Add(newForeignKey); + } + } + } + } + foreach (var tbl in result) { tbl.Columns=LoadColumns(tbl); @@ -1492,11 +1676,11 @@ class PostGreSqlSchemaReader : SchemaReader string GetPK(string table){ string sql=@"SELECT kcu.column_name - FROM information_schema.key_column_usage kcu - JOIN information_schema.table_constraints tc - ON kcu.constraint_name=tc.constraint_name - WHERE lower(tc.constraint_type)='primary key' - AND kcu.table_name=@tablename"; + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu + JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc + ON kcu.CONSTRAINT_NAME=tc.CONSTRAINT_NAME + WHERE lower(tc.CONSTRAINT_TYPE)='primary key' + AND kcu.TABLE_NAME=@tablename"; using (var cmd=_factory.CreateCommand()) { @@ -1578,16 +1762,33 @@ class PostGreSqlSchemaReader : SchemaReader const string TABLE_SQL=@" - SELECT table_name, table_schema, table_type - FROM information_schema.tables - WHERE (table_type='BASE TABLE' OR table_type='VIEW') - AND table_schema NOT IN ('pg_catalog', 'information_schema'); + SELECT TABLE_NAME, TABLE_SCHEMA, TABLE_TYPE + FROM INFORMATION_SCHEMA.TABLES + WHERE (TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW') + AND TABLE_SCHEMA NOT IN ('pg_catalog', 'INFORMATION_SCHEMA'); "; const string COLUMN_SQL=@" - SELECT column_name, is_nullable, udt_name, column_default - FROM information_schema.columns - WHERE table_name=@tableName; + SELECT COLUMN_NAME, IS_NULLABLE, UDT_NAME, COLUMN_DEFAULT + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME=@tableName; + "; + + const string FOREIGN_KEYS_SQL=@" + SELECT + R.TABLE_NAME AS TableWithForeignKey, + R.COLUMN_NAME AS ForeignKeyColumn, + U.TABLE_NAME AS TargetTable, + U.COLUMN_NAME AS TargetTableKey + FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE U + INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS FK + ON U.CONSTRAINT_CATALOG = FK.UNIQUE_CONSTRAINT_CATALOG + AND U.CONSTRAINT_SCHEMA = FK.UNIQUE_CONSTRAINT_SCHEMA + AND U.CONSTRAINT_NAME = FK.UNIQUE_CONSTRAINT_NAME + INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE R + ON R.CONSTRAINT_CATALOG = FK.CONSTRAINT_CATALOG + AND R.CONSTRAINT_SCHEMA = FK.CONSTRAINT_SCHEMA + AND R.CONSTRAINT_NAME = FK.CONSTRAINT_NAME "; } @@ -1717,8 +1918,8 @@ class MySqlSchemaReader : SchemaReader const string TABLE_SQL=@" SELECT * - FROM information_schema.tables - WHERE (table_type='BASE TABLE' OR table_type='VIEW') + FROM INFORMATION_SCHEMA.TABLES + WHERE (TABLE_TYPE='BASE TABLE' OR TABLE_TYPE='VIEW') "; } @@ -2320,16 +2521,37 @@ public static class Inflector { /// The word. /// public static string MakeInitialCaps(string word) { - return String.Concat(word.Substring(0, 1).ToUpper(), word.Substring(1).ToLower()); + return FixInvalidChars(String.Concat(word.Substring(0, 1).ToUpper(), word.Substring(1).ToLower())); } + public static string FixInvalidChars(string word) { + var val = word; + val = val.Replace("-","_Dash") + .Replace(' ','_') + .Replace("#","_Hash") + .Replace("$","_Dollar") + .Replace("+","_Plus") + .Replace("%","_Percent") + .Replace(">","_GreaterThan") + .Replace("<","_LessThan") + .Replace("&","_And") + .Replace(",","_Comma") + .Replace("'","_Apst") + .Replace("/","_Per"); + if (char.IsDigit(val[0])) { val = "_" + val; }; + + return val; + } + /// /// Makes the initial lower case. /// /// The word. /// public static string MakeInitialLowerCase(string word) { - return String.Concat(word.Substring(0, 1).ToLower(), word.Substring(1)); + var val = String.Concat(word.Substring(0, 1).ToLower(), word.Substring(1)); + val = FixInvalidChars(val); + return val; } @@ -2457,12 +2679,12 @@ class Manager { CurrentBlock = new Block { Name = name }; } - public void StartFooter(bool includeInDefault = true) { + public void StartFooter(bool includeInDefault) { CurrentBlock = footer; footer.IncludeInDefault = includeInDefault; } - public void StartHeader(bool includeInDefault = true) { + public void StartHeader(bool includeInDefault) { CurrentBlock = header; header.IncludeInDefault = includeInDefault; } @@ -2476,7 +2698,7 @@ class Manager { currentBlock = null; } - public virtual void Process(bool split, bool sync = true) { + public virtual void Process(bool split, bool sync) { if (split) { EndBlock(); String headerText = template.ToString(header.Start, header.Length); @@ -2597,10 +2819,12 @@ class Manager { if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName)) checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); } + + } } /* End of Manager.tt */ -#> \ No newline at end of file +#> diff --git a/src/T4/OrmLite.Poco.tt b/src/T4/OrmLite.Poco.tt index 301b28511..25db3ad5e 100644 --- a/src/T4/OrmLite.Poco.tt +++ b/src/T4/OrmLite.Poco.tt @@ -10,7 +10,10 @@ bool UseIdAsPK = true; // if true: Changes the primary key property name to Id bool GenerateConstructor = false; // if true: Generates the default empty constructor bool UseSchemaAttribute = true; // if true: Adds explicit '[Schema]' attribute - + bool CreateAutoQueryTypes = false; //if true: Will create Query types with all possible search fields explicitly typed + bool AddNamedConnection = false; //if true: Adds NamedConnection attribute so AutoQuery will override default IDbConnection + bool IncludeReferences = false; //if true: Addes References(typeof(ReferenceTableType)) to FKs + string UseSpecificNamedConnection = ""; //if not null: Will use name provided as NamedConnection and AddNamedConnection = true, else ConnectionStringName is used as default NamedConnection // Read schema var tables = LoadTables(MakeSingular); @@ -32,7 +35,9 @@ if (string.IsNullOrEmpty(Namespace)) Namespace=ConnectionStringName; if (string.IsNullOrEmpty(Namespace)) Namespace="OrmLitePoco"; var manager = Manager.Create(Host, GenerationEnvironment); -manager.StartHeader(); #>// +manager.StartHeader(true); +#> +// // This file was generated by a T4 template. // Don't change it directly as your change would get overwritten. Instead, make changes // to the .tt file (i.e. the T4 template) and save it to regenerate this file. @@ -41,13 +46,10 @@ manager.StartHeader(); #>// #pragma warning disable 1591 using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using ServiceStack.OrmLite; using ServiceStack.DataAnnotations; using ServiceStack.Model; +using ServiceStack; namespace <#=Namespace #> { @@ -57,10 +59,13 @@ foreach(Table tbl in from t in tables where !t.Ignore select t) { manager.StartNewFile(tbl.Name + ".cs"); #> +<#if (CreateAutoQueryTypes && AddNamedConnection) {#> + [NamedConnection("<#=!string.IsNullOrEmpty(UseSpecificNamedConnection) ? UseSpecificNamedConnection : ConnectionStringName#>")] + <#}#> <# if (MakeSingular) {#> [Alias("<#=tbl.Name#>")] <#}#> -<# if (UseSchemaAttribute && !string.IsNullOrEmpty(tbl.Schema)) {#> +<# if (UseSchemaAttribute && !string.IsNullOrEmpty(tbl.Schema) && tbl.Schema != "dbo") {#> [Schema("<#=tbl.Schema#>")] <#}#> public partial class <#=tbl.ClassName#><#if (tbl.HasPK() && UseIdAsPK) { #> : IHasId<<#=tbl.PK.PropertyType#>><#}#> @@ -71,8 +76,14 @@ manager.StartNewFile(tbl.Name + ".cs"); } <# } +var priorProperyNames = new List(); foreach(Column col in from c in tbl.Columns where !c.Ignore select c) { +if (priorProperyNames.Contains(col.PropertyName)) //Change duplicate style names +{ + col.PropertyName = "_" + col.PropertyName; +} +priorProperyNames.Add(col.PropertyName); if ((col.Name!=col.PropertyName) || (col.IsPK && UseIdAsPK)) { #> [Alias("<#=col.Name#>")] <# } if (col.PropertyType == "string" && col.Size > 0) { #> @@ -80,26 +91,68 @@ foreach(Column col in from c in tbl.Columns where !c.Ignore select c) <# } if (col.IsAutoIncrement) { #> [AutoIncrement] <# } if (col.IsComputed) { #> - [Compute] + [Compute] + <# } if (IncludeReferences && tbl.FKeys != null && tbl.FKeys.Any(x => x.FromColumn == col.PropertyName)) { + var toTable = MakeSingular ? tbl.FKeys.First(x => x.FromColumn == col.PropertyName).ToTableSingular : tbl.FKeys.First(x => x.FromColumn == col.PropertyName).ToTable;#> + [References(typeof(<#=ClassPrefix + toTable + ClassSuffix#>))] <# } if (col.IsNullable != true && col.IsAutoIncrement != true) { #> [Required] <# } if (!col.IsPK){#> - public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set;} + public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set; } <# } if (col.IsPK && UseIdAsPK) { #> - public <#=col.ProperPropertyType#> Id { get; set;} + public <#=col.ProperPropertyType#> Id { get; set; } <# } if (col.IsPK && !UseIdAsPK) { #> [PrimaryKey] - public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set;} + public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set; } <# } #> <# } #> } + +<#if (CreateAutoQueryTypes) {#> + public partial class <#=tbl.ClassName#>Query: QueryDb<<#=tbl.ClassName#>> + { +<#foreach(Column col in from c in tbl.Columns where !c.Ignore select c) +{ +var ormName = (col.IsPK && UseIdAsPK) ? "Id" : col.PropertyName; +var isString = col.ProperPropertyType == "string"; +var nullablePropType = col.ProperPropertyType.Replace("?","") + "?"; +var isArray = col.ProperPropertyType.Contains("[]"); +var isBool = col.ProperPropertyType.Contains("bool"); +var isGuid = col.ProperPropertyType.Contains("Guid"); + if (!col.IsPK){#> + public <#=!isArray && !isString ? nullablePropType : col.ProperPropertyType#> <#=ormName#> { get; set; } +<# } if (col.IsPK && UseIdAsPK) { #> + public <#=isString ? "string" : nullablePropType#> Id { get; set;} +<# } if (col.IsPK && !UseIdAsPK) { #> + public <#=isString ? "string" : nullablePropType#> <#=col.PropertyName#> { get; set; }<# } + +if (isString){ #> + public <#=col.ProperPropertyType#> <#=ormName#>StartsWith { get; set; } + public <#=col.ProperPropertyType#> <#=ormName#>EndsWith { get; set; } + public <#=col.ProperPropertyType#> <#=ormName#>Contains { get; set; } + public <#=col.ProperPropertyType#> <#=ormName#>Like { get; set; } + public <#=col.ProperPropertyType#>[] <#=ormName#>Between { get; set; } + public <#=col.ProperPropertyType#>[] <#=ormName#>In { get; set; } +<#} +else if (!isArray && !isBool) { if (!isGuid) {#> + public <#=nullablePropType#> <#=ormName#>GreaterThanOrEqualTo { get; set; } + public <#=nullablePropType#> <#=ormName#>GreaterThan { get; set; } + public <#=nullablePropType#> <#=ormName#>LessThan { get; set; } + public <#=nullablePropType#> <#=ormName#>LessThanOrEqualTo { get; set; } + public <#=nullablePropType#> <#=ormName#>NotEqualTo { get; set; } + public <#=col.ProperPropertyType#>[] <#=ormName#>Between { get; set; } +<#}#> + public <#=col.ProperPropertyType#>[] <#=ormName#>In { get; set; } +<#}#> + +<# } #> +} + <#}#> <# manager.EndBlock(); #> <# } #> -<#manager.StartFooter(); #> +<#manager.StartFooter(true); #> } #pragma warning restore 1591 <#manager.EndBlock(); #> -<#manager.Process(SplitIntoMultipleFiles); #> +<#manager.Process(SplitIntoMultipleFiles, true); #> <# } #> - - diff --git a/src/T4/OrmLite.SP.tt b/src/T4/OrmLite.SP.tt index 52793c94e..2337fadf0 100644 --- a/src/T4/OrmLite.SP.tt +++ b/src/T4/OrmLite.SP.tt @@ -22,6 +22,7 @@ using System.Data.Common; using System.Data; using System.Collections.Generic; using ServiceStack.OrmLite; +using ServiceStack.DataAnnotations; namespace <#=SPNamespace#> { @@ -33,24 +34,40 @@ namespace <#=SPNamespace#> param.Direction = paramDirection; param.DbType = paramType; param.ParameterName = paramName; - param.Value = paramValue; + param.Value = paramValue ?? DBNull.Value; return param; } <#foreach(var sp in sps){#> - public static OrmLiteSPStatement <#=sp.CleanName#>(this IDbConnection db<#foreach(var param in sp.Parameters){#>, <#=param.NullableSysType#> <#=Inflector.MakeInitialLowerCase(param.Name)#> = null<#}#>) + public static OrmLiteSPStatement <#=sp.CleanName#>(this IDbConnection db<#foreach(var param in sp.Parameters){#>, <#=param.NullableSysType#> @<#=Inflector.MakeInitialLowerCase(param.Name)#> = null<#}#>) { var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); dbCmd.CommandText = "<#=sp.Name#>"; dbCmd.CommandType = CommandType.StoredProcedure; <#if (sp.Parameters.Count > 0) { foreach(var param in sp.Parameters){#> - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"<#=param.Name#>",<#=Inflector.MakeInitialLowerCase(param.Name)#>,ParameterDirection.Input,<#=param.DbType#>)); + dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"<#=param.Name#>",@<#=Inflector.MakeInitialLowerCase(param.Name)#>,<#=GetParamDirection(param.Direction)#>,<#=param.DbType#>)); <#}#> <#}#> + dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"__ReturnValue",0,ParameterDirection.ReturnValue,DbType.Int32)); return new OrmLiteSPStatement(db, dbCmd); } <#}#> } + + <#if (IncludeSPReturnTypes) foreach(var sp in sps) + { + if (!sp.SPOutputColumns.Any()) continue; #> + public class <#=sp.CleanName#>_Result + { + <# foreach(var prop in sp.SPOutputColumns) { var _alias = false; var propName = prop.Name; if (propName.Contains(' ') || propName.Contains('$') || propName.Contains('+') || propName.Contains('%')) { propName = propName.Replace(' ','_').Replace("$","_Dollar").Replace("+","_Plus").Replace("%","_Percent"); _alias = true; }; if (char.IsDigit(propName[0])) { propName = "_" + propName; _alias = true; }; + + if (_alias) {#> [Alias("<#=prop.Name#>")] + <#}#> + public <#=prop.DotNetType#> <#=propName#> { get; set; } + <#} + #> } -<# } #> +<#}#> +} +<#}#> diff --git a/src/XamarinTests/SqliteExpressionsTest.iOS/AppDelegate.cs b/src/XamarinTests/SqliteExpressionsTest.iOS/AppDelegate.cs deleted file mode 100644 index 314b29896..000000000 --- a/src/XamarinTests/SqliteExpressionsTest.iOS/AppDelegate.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using MonoTouch.Foundation; -using MonoTouch.UIKit; - -namespace SqliteExpressionsTest.iOS -{ - // The UIApplicationDelegate for the application. This class is responsible for launching the - // User Interface of the application, as well as listening (and optionally responding) to - // application events from iOS. - [Register("AppDelegate")] - public partial class AppDelegate : UIApplicationDelegate - { - // class-level declarations - UIWindow window; - - // - // This method is invoked when the application has loaded and is ready to run. In this - // method you should instantiate the window, load the UI into it and then make the window - // visible. - // - // You have 17 seconds to return from this method, or iOS will terminate your application. - // - public override bool FinishedLaunching(UIApplication app, NSDictionary options) - { - // create a new window instance based on the screen size - window = new UIWindow(UIScreen.MainScreen.Bounds); - - // If you have defined a view, add it here: - this.window.RootViewController = new MainViewController(); - - // make the window visible - window.MakeKeyAndVisible(); - - return true; - } - } -} \ No newline at end of file diff --git a/src/XamarinTests/SqliteExpressionsTest.iOS/Author.cs b/src/XamarinTests/SqliteExpressionsTest.iOS/Author.cs deleted file mode 100644 index d7680fec4..000000000 --- a/src/XamarinTests/SqliteExpressionsTest.iOS/Author.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Data; -using System.IO; -using System.Linq; -using ServiceStack.Common.Utils; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Sqlite; - -namespace SqliteExpressionsTest -{ - public class Author - { - /// - /// Gets or sets the id. - /// - [AutoIncrement] - [Alias("AuthorID")] - public Int32 Id { get; set;} - - /// - /// Gets or sets the name. - /// - [Index(Unique = true)] - [StringLength(40)] - public string Name { get; set;} - - /// - /// Gets or sets the birthday. - /// - public DateTime Birthday { get; set;} - - /// - /// Gets or sets the last activity. - /// - public DateTime? LastActivity { get; set;} - - /// - /// Gets or sets the earnings. - /// - public Decimal? Earnings { get; set;} - - /// - /// Gets or sets a value indicating whether active. - /// - public bool Active { get; set; } - - /// - /// Gets or sets the city. - /// - [StringLength(80)] - [Alias("JobCity")] - public string City { get; set;} - - /// - /// Gets or sets the comments. - /// - [StringLength(80)] - [Alias("Comment")] - public string Comments { get; set;} - - /// - /// Gets or sets the rate. - /// - public Int16 Rate{ get; set;} - - - } - - -} \ No newline at end of file diff --git a/src/XamarinTests/SqliteExpressionsTest.iOS/Info.plist b/src/XamarinTests/SqliteExpressionsTest.iOS/Info.plist deleted file mode 100644 index 63f203d5a..000000000 --- a/src/XamarinTests/SqliteExpressionsTest.iOS/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - UIDeviceFamily - - 1 - 2 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - MinimumOSVersion - 3.2 - - \ No newline at end of file diff --git a/src/XamarinTests/SqliteExpressionsTest.iOS/Main.cs b/src/XamarinTests/SqliteExpressionsTest.iOS/Main.cs deleted file mode 100644 index 61ad82422..000000000 --- a/src/XamarinTests/SqliteExpressionsTest.iOS/Main.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using MonoTouch.Foundation; -using MonoTouch.UIKit; - -namespace SqliteExpressionsTest.iOS -{ - public class Application - { - // This is the main entry point of the application. - static void Main(string[] args) - { - // if you want to use a different Application Delegate class from "AppDelegate" - // you can specify it here. - UIApplication.Main(args, null, "AppDelegate"); - } - } -} \ No newline at end of file diff --git a/src/XamarinTests/SqliteExpressionsTest.iOS/MainViewController.cs b/src/XamarinTests/SqliteExpressionsTest.iOS/MainViewController.cs deleted file mode 100644 index a4bcb5b27..000000000 --- a/src/XamarinTests/SqliteExpressionsTest.iOS/MainViewController.cs +++ /dev/null @@ -1,366 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using MonoTouch.CoreFoundation; -using MonoTouch.UIKit; -using MonoTouch.Foundation; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.Sqlite; - -namespace SqliteExpressionsTest.iOS -{ - [Register("UniversalView")] - public class UniversalView : UIView - { - private UIButton runTests; - - public UniversalView() - { - Initialize(); - } - - public UniversalView(RectangleF bounds) - : base(bounds) - { - Initialize(); - } - - void Initialize() - { - //BackgroundColor = UIColor.Red; - this.runTests = UIButton.FromType(UIButtonType.RoundedRect); - this.runTests.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleMargins; - this.runTests.Bounds = new RectangleF(50, 50, 125, 40); - this.runTests.SetTitle("Run tests", UIControlState.Normal); - this.runTests.SetTitle("Tests running...", UIControlState.Disabled); - - this.AddSubview(this.runTests); - - this.runTests.TouchUpInside += async (sender, args) => - { - this.runTests.Enabled = false; - await this.RunAsync(); - this.runTests.Enabled = true; - }; - } - - /// - /// Run tests asyncronously. - /// - /// - /// The . - /// - private async Task RunAsync() - { - await Task.Factory.StartNew(RunAuthorTests); - } - - /// - /// The run author tests. - /// - private static void RunAuthorTests() - { - //Console.WriteLine("Hello World!"); - - //Console.WriteLine("Join Test"); - //JoinTest.Test(); - - //Console.WriteLine("Ignored Field Select Test"); - //IgnoredFieldSelectTest.Test(); - - //Console.WriteLine("Count Test"); - //CountTest.Test(); - - OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance; - SqlExpressionVisitor ev = OrmLiteConfig.DialectProvider.ExpressionVisitor(); - - using (IDbConnection db = GetFileConnectionString().OpenDbConnection()) - { - db.DropTable(); - db.CreateTable(); - db.DeleteAll(); - - var authors = new List(); - authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); - authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); - authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); - authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); - authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); - authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); - authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); - authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); - authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); - authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); - authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); - authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); - authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico" }); - - db.InsertAll(authors); - - - // lets start ! - - // select authors born 20 year ago - int year = DateTime.Today.AddYears(-20).Year; - int expected = 5; - - ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - List result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31))); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= new DateTime(year, 12, 31)); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from London, Berlin and Madrid : 6 - expected = 6; - ev.Where(rn => Sql.In(rn.City, new object[] { "London", "Madrid", "Berlin" })); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors from Bogota and Cartagena : 7 - expected = 7; - ev.Where(rn => Sql.In(rn.City, new object[] { "Bogota", "Cartagena" })); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name starts with A - expected = 3; - ev.Where(rn => rn.Name.StartsWith("A")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.StartsWith("A")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) - expected = 3; - ev.Where(rn => rn.Name.ToUpper().EndsWith("GARZON")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.ToUpper().EndsWith("GARZON")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors which name ends with garzon - //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters - //in the string. - //An underscore ("_") in the LIKE pattern matches any single character in the string. - //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). - expected = 3; - ev.Where(rn => rn.Name.EndsWith("garzon")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.EndsWith("garzon")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors which name contains Benedict - expected = 2; - ev.Where(rn => rn.Name.Contains("Benedict")); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Name.Contains("Benedict")); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // select authors with Earnings <= 50 - expected = 3; - ev.Where(rn => rn.Earnings <= 50); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Earnings <= 50); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // select authors with Rate = 10 and city=Mexio - expected = 1; - ev.Where(rn => rn.Rate == 10 && rn.City == "Mexico"); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - // enough selecting, lets update; - // set Active=false where rate =0 - expected = 2; - ev.Where(rn => rn.Rate == 0).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected == rows); - - // insert values only in Id, Name, Birthday, Rate and Active fields - expected = 4; - //ev = OrmLiteConfig.DialectProvider.ExpressionVisitor(); - - //ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); - ev.Where(rn => !rn.Active); - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - //update comment for City == null - expected = 2; - ev.Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected == rows); - - // delete where City is null - expected = 2; - rows = db.Delete(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, rows, expected == rows); - - - - // lets select all records ordered by Rate Descending and Name Ascending - //expected = 14; - //ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition - //result = db.Select(ev); - //Console.WriteLine(ev.WhereExpression); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - //Console.WriteLine(ev.OrderByExpression); - //var author = result.FirstOrDefault(); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel", author.Name, "Claudia Espinel" == author.Name); - - // select only first 5 rows .... - - ev = OrmLiteConfig.DialectProvider.ExpressionVisitor(); - expected = 5; - ev.Limit(5); // note: order is the same as in the last sentence - result = db.Select(ev); - Console.WriteLine(ev.WhereExpression); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - // and finally lets select only Name and City (name will be "UPPERCASED" ) - - //ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); - //Console.WriteLine(ev.SelectExpression); - //result = db.Select(ev); - //var author = result.FirstOrDefault(); - //Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name); - - //paging : - ev.Limit(0, 4);// first page, page size=4; - result = db.Select(ev); - var author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name); - - ev.Limit(4, 4);// second page - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper() == author.Name); - - ev.Limit(8, 4);// third page - result = db.Select(ev); - author = result.FirstOrDefault(); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper() == author.Name); - - // select distinct.. - ev.Limit(); // clear limit - ev.SelectDistinct(r => r.City); - expected = 6; - result = db.Select(ev); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", expected, result.Count, expected == result.Count); - - - Console.WriteLine(); - // Tests for predicate overloads that make use of the expression visitor - Console.WriteLine("First author by name (exists)"); - author = db.First(a => a.Name == "Jorge Garzon"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Jorge Garzon", author.Name, "Jorge Garzon" == author.Name); - - try - { - Console.WriteLine("First author by name (does not exist)"); - author = db.First(a => a.Name == "Does not exist"); - - Console.WriteLine("Expected exception thrown, OK? False"); - } - catch - { - Console.WriteLine("Expected exception thrown, OK? True"); - } - - Console.WriteLine("First author or default (does not exist)"); - author = db.FirstOrDefault(a => a.Name == "Does not exist"); - Console.WriteLine("Expected:null ; OK? {0}", author == null); - - Console.WriteLine("First author or default by city (multiple matches)"); - author = db.FirstOrDefault(a => a.City == "Bogota"); - Console.WriteLine("Expected:{0} ; Selected:{1}, OK? {2}", "Angel Colmenares", author.Name, "Angel Colmenares" == author.Name); - - - Console.ReadLine(); - Console.WriteLine("Press Enter to continue"); - - } - - Console.WriteLine("This is The End my friend!"); - } - - /// - /// The get file connection string. - /// - /// - /// The . - /// - private static string GetFileConnectionString() - { - var connectionString = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.Personal), - "db.sqlite"); - - //var connectionString = "~/db.sqlite".MapAbsolutePath(); - if (File.Exists(connectionString)) - { - File.Delete(connectionString); - } - - return connectionString; - } - } - - [Register("MainViewController")] - public class MainViewController : UIViewController - { - public MainViewController() - { - } - - public override void DidReceiveMemoryWarning() - { - // Releases the view if it doesn't have a superview. - base.DidReceiveMemoryWarning(); - - // Release any cached data, images, etc that aren't in use. - } - - public override void ViewDidLoad() - { - View = new UniversalView(); - - base.ViewDidLoad(); - - } - } -} \ No newline at end of file diff --git a/src/XamarinTests/SqliteExpressionsTest.iOS/Properties/AssemblyInfo.cs b/src/XamarinTests/SqliteExpressionsTest.iOS/Properties/AssemblyInfo.cs deleted file mode 100644 index 2808dbd38..000000000 --- a/src/XamarinTests/SqliteExpressionsTest.iOS/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SqliteExpressionsTest.iOS")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SqliteExpressionsTest.iOS")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a46294af-fcc4-4747-8a38-2dd90478e8e3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] diff --git a/src/XamarinTests/SqliteExpressionsTest.iOS/SqliteExpressionsTest.iOS.csproj b/src/XamarinTests/SqliteExpressionsTest.iOS/SqliteExpressionsTest.iOS.csproj deleted file mode 100644 index 82661245a..000000000 --- a/src/XamarinTests/SqliteExpressionsTest.iOS/SqliteExpressionsTest.iOS.csproj +++ /dev/null @@ -1,123 +0,0 @@ - - - - Debug - iPhoneSimulator - 8.0.30703 - 2.0 - {9627154D-8CA4-4212-8033-26356B0C54F6} - {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Exe - SqliteExpressionsTest.iOS - Resources - SqliteExpressionsTestiOS - - - true - full - false - bin\iPhoneSimulator\Debug - DEBUG - prompt - 4 - false - None - true - - - none - true - bin\iPhoneSimulator\Release - prompt - 4 - false - None - - - true - full - false - bin\iPhone\Debug - DEBUG - prompt - 4 - false - true - iPhone Developer - - - none - true - bin\iPhone\Release - prompt - 4 - false - iPhone Developer - - - none - True - bin\iPhone\Ad-Hoc - prompt - 4 - False - iPhone Distribution - True - - - none - True - bin\iPhone\AppStore - prompt - 4 - False - iPhone Distribution - - - - CountTest.cs - - - IgnoredFieldSelectTest.cs - - - JoinTest.cs - - - Program.cs - - - - - - - - - - - {E6EA93E2-37BC-477F-8B87-BC30C3BBDB85} - ServiceStack.OrmLite.Sqlite.iOS - - - {7E3FEA8A-C770-4D50-8AD5-F56FCF0B7E07} - ServiceStack.OrmLite.iOS - - - - - - - ..\..\..\lib\ServiceStack.Common.MonoTouch.dll - - - ..\..\..\lib\ServiceStack.Interfaces.MonoTouch.dll - - - - - - - - - - \ No newline at end of file diff --git a/src/dapper-dot-net/.hgignore b/src/dapper-dot-net/.hgignore deleted file mode 100644 index 3bf2be9cf..000000000 --- a/src/dapper-dot-net/.hgignore +++ /dev/null @@ -1,3 +0,0 @@ -/*.suo -bin/* -obj/* \ No newline at end of file diff --git a/src/dapper-dot-net/EntityFramework/Model.Designer.cs b/src/dapper-dot-net/EntityFramework/Model.Designer.cs deleted file mode 100644 index ef6f54338..000000000 --- a/src/dapper-dot-net/EntityFramework/Model.Designer.cs +++ /dev/null @@ -1,456 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -using System; -using System.ComponentModel; -using System.Data.EntityClient; -using System.Data.Objects; -using System.Data.Objects.DataClasses; -using System.Linq; -using System.Runtime.Serialization; -using System.Xml.Serialization; - -[assembly: EdmSchemaAttribute()] -namespace SqlMapper.EntityFramework -{ - #region Contexts - - /// - /// No Metadata Documentation available. - /// - public partial class tempdbEntities1 : ObjectContext - { - #region Constructors - - /// - /// Initializes a new tempdbEntities1 object using the connection string found in the 'tempdbEntities1' section of the application configuration file. - /// - public tempdbEntities1() : base("name=tempdbEntities1", "tempdbEntities1") - { - this.ContextOptions.LazyLoadingEnabled = true; - OnContextCreated(); - } - - /// - /// Initialize a new tempdbEntities1 object. - /// - public tempdbEntities1(string connectionString) : base(connectionString, "tempdbEntities1") - { - this.ContextOptions.LazyLoadingEnabled = true; - OnContextCreated(); - } - - /// - /// Initialize a new tempdbEntities1 object. - /// - public tempdbEntities1(EntityConnection connection) : base(connection, "tempdbEntities1") - { - this.ContextOptions.LazyLoadingEnabled = true; - OnContextCreated(); - } - - #endregion - - #region Partial Methods - - partial void OnContextCreated(); - - #endregion - - #region ObjectSet Properties - - /// - /// No Metadata Documentation available. - /// - public ObjectSet Posts - { - get - { - if ((_Posts == null)) - { - _Posts = base.CreateObjectSet("Posts"); - } - return _Posts; - } - } - private ObjectSet _Posts; - - #endregion - - #region AddTo Methods - - /// - /// Deprecated Method for adding a new object to the Posts EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. - /// - public void AddToPosts(Post post) - { - base.AddObject("Posts", post); - } - - #endregion - - } - - #endregion - - #region Entities - - /// - /// No Metadata Documentation available. - /// - [EdmEntityTypeAttribute(NamespaceName="tempdbModel", Name="Post")] - [Serializable()] - [DataContractAttribute(IsReference=true)] - public partial class Post : EntityObject - { - #region Factory Method - - /// - /// Create a new Post object. - /// - /// Initial value of the Id property. - /// Initial value of the Text property. - /// Initial value of the CreationDate property. - /// Initial value of the LastChangeDate property. - public static Post CreatePost(global::System.Int32 id, global::System.String text, global::System.DateTime creationDate, global::System.DateTime lastChangeDate) - { - Post post = new Post(); - post.Id = id; - post.Text = text; - post.CreationDate = creationDate; - post.LastChangeDate = lastChangeDate; - return post; - } - - #endregion - - #region Simple Properties - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] - [DataMemberAttribute()] - public global::System.Int32 Id - { - get - { - return _Id; - } - set - { - if (_Id != value) - { - OnIdChanging(value); - ReportPropertyChanging("Id"); - _Id = StructuralObject.SetValidValue(value, "Id"); - ReportPropertyChanged("Id"); - OnIdChanged(); - } - } - } - private global::System.Int32 _Id; - partial void OnIdChanging(global::System.Int32 value); - partial void OnIdChanged(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] - [DataMemberAttribute()] - public global::System.String Text - { - get - { - return _Text; - } - set - { - OnTextChanging(value); - ReportPropertyChanging("Text"); - _Text = StructuralObject.SetValidValue(value, false, "Text"); - ReportPropertyChanged("Text"); - OnTextChanged(); - } - } - private global::System.String _Text; - partial void OnTextChanging(global::System.String value); - partial void OnTextChanged(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] - [DataMemberAttribute()] - public global::System.DateTime CreationDate - { - get - { - return _CreationDate; - } - set - { - OnCreationDateChanging(value); - ReportPropertyChanging("CreationDate"); - _CreationDate = StructuralObject.SetValidValue(value, "CreationDate"); - ReportPropertyChanged("CreationDate"); - OnCreationDateChanged(); - } - } - private global::System.DateTime _CreationDate; - partial void OnCreationDateChanging(global::System.DateTime value); - partial void OnCreationDateChanged(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] - [DataMemberAttribute()] - public global::System.DateTime LastChangeDate - { - get - { - return _LastChangeDate; - } - set - { - OnLastChangeDateChanging(value); - ReportPropertyChanging("LastChangeDate"); - _LastChangeDate = StructuralObject.SetValidValue(value, "LastChangeDate"); - ReportPropertyChanged("LastChangeDate"); - OnLastChangeDateChanged(); - } - } - private global::System.DateTime _LastChangeDate; - partial void OnLastChangeDateChanging(global::System.DateTime value); - partial void OnLastChangeDateChanged(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter1 - { - get - { - return _Counter1; - } - set - { - OnCounter1Changing(value); - ReportPropertyChanging("Counter1"); - _Counter1 = StructuralObject.SetValidValue(value, "Counter1"); - ReportPropertyChanged("Counter1"); - OnCounter1Changed(); - } - } - private Nullable _Counter1; - partial void OnCounter1Changing(Nullable value); - partial void OnCounter1Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter2 - { - get - { - return _Counter2; - } - set - { - OnCounter2Changing(value); - ReportPropertyChanging("Counter2"); - _Counter2 = StructuralObject.SetValidValue(value, "Counter2"); - ReportPropertyChanged("Counter2"); - OnCounter2Changed(); - } - } - private Nullable _Counter2; - partial void OnCounter2Changing(Nullable value); - partial void OnCounter2Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter3 - { - get - { - return _Counter3; - } - set - { - OnCounter3Changing(value); - ReportPropertyChanging("Counter3"); - _Counter3 = StructuralObject.SetValidValue(value, "Counter3"); - ReportPropertyChanged("Counter3"); - OnCounter3Changed(); - } - } - private Nullable _Counter3; - partial void OnCounter3Changing(Nullable value); - partial void OnCounter3Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter4 - { - get - { - return _Counter4; - } - set - { - OnCounter4Changing(value); - ReportPropertyChanging("Counter4"); - _Counter4 = StructuralObject.SetValidValue(value, "Counter4"); - ReportPropertyChanged("Counter4"); - OnCounter4Changed(); - } - } - private Nullable _Counter4; - partial void OnCounter4Changing(Nullable value); - partial void OnCounter4Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter5 - { - get - { - return _Counter5; - } - set - { - OnCounter5Changing(value); - ReportPropertyChanging("Counter5"); - _Counter5 = StructuralObject.SetValidValue(value, "Counter5"); - ReportPropertyChanged("Counter5"); - OnCounter5Changed(); - } - } - private Nullable _Counter5; - partial void OnCounter5Changing(Nullable value); - partial void OnCounter5Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter6 - { - get - { - return _Counter6; - } - set - { - OnCounter6Changing(value); - ReportPropertyChanging("Counter6"); - _Counter6 = StructuralObject.SetValidValue(value, "Counter6"); - ReportPropertyChanged("Counter6"); - OnCounter6Changed(); - } - } - private Nullable _Counter6; - partial void OnCounter6Changing(Nullable value); - partial void OnCounter6Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter7 - { - get - { - return _Counter7; - } - set - { - OnCounter7Changing(value); - ReportPropertyChanging("Counter7"); - _Counter7 = StructuralObject.SetValidValue(value, "Counter7"); - ReportPropertyChanged("Counter7"); - OnCounter7Changed(); - } - } - private Nullable _Counter7; - partial void OnCounter7Changing(Nullable value); - partial void OnCounter7Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter8 - { - get - { - return _Counter8; - } - set - { - OnCounter8Changing(value); - ReportPropertyChanging("Counter8"); - _Counter8 = StructuralObject.SetValidValue(value, "Counter8"); - ReportPropertyChanged("Counter8"); - OnCounter8Changed(); - } - } - private Nullable _Counter8; - partial void OnCounter8Changing(Nullable value); - partial void OnCounter8Changed(); - - /// - /// No Metadata Documentation available. - /// - [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] - [DataMemberAttribute()] - public Nullable Counter9 - { - get - { - return _Counter9; - } - set - { - OnCounter9Changing(value); - ReportPropertyChanging("Counter9"); - _Counter9 = StructuralObject.SetValidValue(value, "Counter9"); - ReportPropertyChanged("Counter9"); - OnCounter9Changed(); - } - } - private Nullable _Counter9; - partial void OnCounter9Changing(Nullable value); - partial void OnCounter9Changed(); - - #endregion - - } - - #endregion - -} diff --git a/src/dapper-dot-net/EntityFramework/Model.edmx b/src/dapper-dot-net/EntityFramework/Model.edmx deleted file mode 100644 index e9d3f1c59..000000000 --- a/src/dapper-dot-net/EntityFramework/Model.edmx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/dapper-dot-net/License.txt b/src/dapper-dot-net/License.txt deleted file mode 100644 index 443c7d942..000000000 --- a/src/dapper-dot-net/License.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2010 Stack Overflow Internet Services, Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/src/dapper-dot-net/Linq2Sql/DataClasses.dbml b/src/dapper-dot-net/Linq2Sql/DataClasses.dbml deleted file mode 100644 index bf2a0c991..000000000 --- a/src/dapper-dot-net/Linq2Sql/DataClasses.dbml +++ /dev/null @@ -1,20 +0,0 @@ - - -
- - - - - - - - - - - - - - - -
- \ No newline at end of file diff --git a/src/dapper-dot-net/Linq2Sql/DataClasses.dbml.layout b/src/dapper-dot-net/Linq2Sql/DataClasses.dbml.layout deleted file mode 100644 index 3b729024b..000000000 --- a/src/dapper-dot-net/Linq2Sql/DataClasses.dbml.layout +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/dapper-dot-net/Linq2Sql/DataClasses.designer.cs b/src/dapper-dot-net/Linq2Sql/DataClasses.designer.cs deleted file mode 100644 index c05cdd63f..000000000 --- a/src/dapper-dot-net/Linq2Sql/DataClasses.designer.cs +++ /dev/null @@ -1,427 +0,0 @@ -#pragma warning disable 1591 -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18449 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace SqlMapper.Linq2Sql -{ - using System.Data.Linq; - using System.Data.Linq.Mapping; - using System.Data; - using System.Collections.Generic; - using System.Reflection; - using System.Linq; - using System.Linq.Expressions; - using System.ComponentModel; - using System; - - - [global::System.Data.Linq.Mapping.DatabaseAttribute(Name="tempdb")] - public partial class DataClassesDataContext : System.Data.Linq.DataContext - { - - private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource(); - - #region Extensibility Method Definitions - partial void OnCreated(); - partial void InsertPost(Post instance); - partial void UpdatePost(Post instance); - partial void DeletePost(Post instance); - #endregion - - public DataClassesDataContext() : - base(global::SqlMapper.Properties.Settings.Default.tempdbConnectionString, mappingSource) - { - OnCreated(); - } - - public DataClassesDataContext(string connection) : - base(connection, mappingSource) - { - OnCreated(); - } - - public DataClassesDataContext(System.Data.IDbConnection connection) : - base(connection, mappingSource) - { - OnCreated(); - } - - public DataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) : - base(connection, mappingSource) - { - OnCreated(); - } - - public DataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) : - base(connection, mappingSource) - { - OnCreated(); - } - - public System.Data.Linq.Table Posts - { - get - { - return this.GetTable(); - } - } - } - - [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Posts")] - public partial class Post : INotifyPropertyChanging, INotifyPropertyChanged - { - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); - - private int _Id; - - private string _Text; - - private System.DateTime _CreationDate; - - private System.DateTime _LastChangeDate; - - private System.Nullable _Counter1; - - private System.Nullable _Counter2; - - private System.Nullable _Counter3; - - private System.Nullable _Counter4; - - private System.Nullable _Counter5; - - private System.Nullable _Counter6; - - private System.Nullable _Counter7; - - private System.Nullable _Counter8; - - private System.Nullable _Counter9; - - #region Extensibility Method Definitions - partial void OnLoaded(); - partial void OnValidate(System.Data.Linq.ChangeAction action); - partial void OnCreated(); - partial void OnIdChanging(int value); - partial void OnIdChanged(); - partial void OnTextChanging(string value); - partial void OnTextChanged(); - partial void OnCreationDateChanging(System.DateTime value); - partial void OnCreationDateChanged(); - partial void OnLastChangeDateChanging(System.DateTime value); - partial void OnLastChangeDateChanged(); - partial void OnCounter1Changing(System.Nullable value); - partial void OnCounter1Changed(); - partial void OnCounter2Changing(System.Nullable value); - partial void OnCounter2Changed(); - partial void OnCounter3Changing(System.Nullable value); - partial void OnCounter3Changed(); - partial void OnCounter4Changing(System.Nullable value); - partial void OnCounter4Changed(); - partial void OnCounter5Changing(System.Nullable value); - partial void OnCounter5Changed(); - partial void OnCounter6Changing(System.Nullable value); - partial void OnCounter6Changed(); - partial void OnCounter7Changing(System.Nullable value); - partial void OnCounter7Changed(); - partial void OnCounter8Changing(System.Nullable value); - partial void OnCounter8Changed(); - partial void OnCounter9Changing(System.Nullable value); - partial void OnCounter9Changed(); - #endregion - - public Post() - { - OnCreated(); - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] - public int Id - { - get - { - return this._Id; - } - set - { - if ((this._Id != value)) - { - this.OnIdChanging(value); - this.SendPropertyChanging(); - this._Id = value; - this.SendPropertyChanged("Id"); - this.OnIdChanged(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Text", DbType="VarChar(MAX) NOT NULL", CanBeNull=false)] - public string Text - { - get - { - return this._Text; - } - set - { - if ((this._Text != value)) - { - this.OnTextChanging(value); - this.SendPropertyChanging(); - this._Text = value; - this.SendPropertyChanged("Text"); - this.OnTextChanged(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CreationDate", DbType="DateTime NOT NULL")] - public System.DateTime CreationDate - { - get - { - return this._CreationDate; - } - set - { - if ((this._CreationDate != value)) - { - this.OnCreationDateChanging(value); - this.SendPropertyChanging(); - this._CreationDate = value; - this.SendPropertyChanged("CreationDate"); - this.OnCreationDateChanged(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_LastChangeDate", DbType="DateTime NOT NULL")] - public System.DateTime LastChangeDate - { - get - { - return this._LastChangeDate; - } - set - { - if ((this._LastChangeDate != value)) - { - this.OnLastChangeDateChanging(value); - this.SendPropertyChanging(); - this._LastChangeDate = value; - this.SendPropertyChanged("LastChangeDate"); - this.OnLastChangeDateChanged(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter1", DbType="Int")] - public System.Nullable Counter1 - { - get - { - return this._Counter1; - } - set - { - if ((this._Counter1 != value)) - { - this.OnCounter1Changing(value); - this.SendPropertyChanging(); - this._Counter1 = value; - this.SendPropertyChanged("Counter1"); - this.OnCounter1Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter2", DbType="Int")] - public System.Nullable Counter2 - { - get - { - return this._Counter2; - } - set - { - if ((this._Counter2 != value)) - { - this.OnCounter2Changing(value); - this.SendPropertyChanging(); - this._Counter2 = value; - this.SendPropertyChanged("Counter2"); - this.OnCounter2Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter3", DbType="Int")] - public System.Nullable Counter3 - { - get - { - return this._Counter3; - } - set - { - if ((this._Counter3 != value)) - { - this.OnCounter3Changing(value); - this.SendPropertyChanging(); - this._Counter3 = value; - this.SendPropertyChanged("Counter3"); - this.OnCounter3Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter4", DbType="Int")] - public System.Nullable Counter4 - { - get - { - return this._Counter4; - } - set - { - if ((this._Counter4 != value)) - { - this.OnCounter4Changing(value); - this.SendPropertyChanging(); - this._Counter4 = value; - this.SendPropertyChanged("Counter4"); - this.OnCounter4Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter5", DbType="Int")] - public System.Nullable Counter5 - { - get - { - return this._Counter5; - } - set - { - if ((this._Counter5 != value)) - { - this.OnCounter5Changing(value); - this.SendPropertyChanging(); - this._Counter5 = value; - this.SendPropertyChanged("Counter5"); - this.OnCounter5Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter6", DbType="Int")] - public System.Nullable Counter6 - { - get - { - return this._Counter6; - } - set - { - if ((this._Counter6 != value)) - { - this.OnCounter6Changing(value); - this.SendPropertyChanging(); - this._Counter6 = value; - this.SendPropertyChanged("Counter6"); - this.OnCounter6Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter7", DbType="Int")] - public System.Nullable Counter7 - { - get - { - return this._Counter7; - } - set - { - if ((this._Counter7 != value)) - { - this.OnCounter7Changing(value); - this.SendPropertyChanging(); - this._Counter7 = value; - this.SendPropertyChanged("Counter7"); - this.OnCounter7Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter8", DbType="Int")] - public System.Nullable Counter8 - { - get - { - return this._Counter8; - } - set - { - if ((this._Counter8 != value)) - { - this.OnCounter8Changing(value); - this.SendPropertyChanging(); - this._Counter8 = value; - this.SendPropertyChanged("Counter8"); - this.OnCounter8Changed(); - } - } - } - - [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Counter9", DbType="Int")] - public System.Nullable Counter9 - { - get - { - return this._Counter9; - } - set - { - if ((this._Counter9 != value)) - { - this.OnCounter9Changing(value); - this.SendPropertyChanging(); - this._Counter9 = value; - this.SendPropertyChanged("Counter9"); - this.OnCounter9Changed(); - } - } - } - - public event PropertyChangingEventHandler PropertyChanging; - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanging() - { - if ((this.PropertyChanging != null)) - { - this.PropertyChanging(this, emptyChangingEventArgs); - } - } - - protected virtual void SendPropertyChanged(String propertyName) - { - if ((this.PropertyChanged != null)) - { - this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - } -} -#pragma warning restore 1591 diff --git a/src/dapper-dot-net/Linq2Sql/Post.cs b/src/dapper-dot-net/Linq2Sql/Post.cs deleted file mode 100644 index d88887e87..000000000 --- a/src/dapper-dot-net/Linq2Sql/Post.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace SqlMapper.Linq2Sql -{ - public partial class Post - { - /* - public int Bloat { get; set; } - public int Bloat1 { get; set; } - public int Bloat2 { get; set; } - public int Bloat3 { get; set; } - public int Bloat4 { get; set; } - public int Bloat5 { get; set; } - public int Bloat6 { get; set; } - public int Bloat7 { get; set; } - public int Bloat8 { get; set; } - - - public int Bloat10 { get; set; } - public int Bloat11 { get; set; } - public int Bloat12 { get; set; } - public int Bloat13 { get; set; } - public int Bloat14 { get; set; } - public int Bloat15 { get; set; } - public int Bloat16 { get; set; } - public int Bloat17 { get; set; } - public int Bloat18 { get; set; } - */ - } -} diff --git a/src/dapper-dot-net/Massive/Massive.cs b/src/dapper-dot-net/Massive/Massive.cs deleted file mode 100644 index eeae39cbd..000000000 --- a/src/dapper-dot-net/Massive/Massive.cs +++ /dev/null @@ -1,442 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Configuration; -using System.Data; -using System.Data.Common; -using System.Dynamic; -using System.Linq; -using System.Text; -using System.Collections; -using System.Text.RegularExpressions; - -namespace Massive -{ - public static class ObjectExtensions - { - /// - /// Extension method for adding in a bunch of parameters - /// - public static void AddParams(this DbCommand cmd, params object[] args) - { - foreach (var item in args) - { - AddParam(cmd, item); - } - } - /// - /// Extension for adding single parameter - /// - public static void AddParam(this DbCommand cmd, object item) - { - var p = cmd.CreateParameter(); - p.ParameterName = string.Format("@{0}", cmd.Parameters.Count); - if (item == null) - { - p.Value = DBNull.Value; - } - else - { - if (item.GetType() == typeof(Guid)) - { - p.Value = item.ToString(); - p.DbType = DbType.String; - p.Size = 4000; - } - else if (item.GetType() == typeof(ExpandoObject)) - { - var d = (IDictionary)item; - p.Value = d.Values.FirstOrDefault(); - } - else - { - p.Value = item; - } - //from DataChomp - if (item.GetType() == typeof(string)) - p.Size = 4000; - } - cmd.Parameters.Add(p); - } - /// - /// Turns an IDataReader to a Dynamic list of things - /// - public static List ToExpandoList(this IDataReader rdr) - { - var result = new List(); - while (rdr.Read()) - { - result.Add(rdr.RecordToExpando()); - } - return result; - } - public static dynamic RecordToExpando(this IDataReader rdr) - { - dynamic e = new ExpandoObject(); - var d = e as IDictionary; - for (int i = 0; i < rdr.FieldCount; i++) - d.Add(rdr.GetName(i), rdr[i]); - return e; - } - /// - /// Turns the object into an ExpandoObject - /// - public static dynamic ToExpando(this object o) - { - var result = new ExpandoObject(); - var d = result as IDictionary; //work with the Expando as a Dictionary - if (o.GetType() == typeof(ExpandoObject)) return o; //shouldn't have to... but just in case - if (o.GetType() == typeof(NameValueCollection) || o.GetType().IsSubclassOf(typeof(NameValueCollection))) - { - var nv = (NameValueCollection)o; - nv.Cast().Select(key => new KeyValuePair(key, nv[key])).ToList().ForEach(i => d.Add(i)); - } - else - { - var props = o.GetType().GetProperties(); - foreach (var item in props) - { - d.Add(item.Name, item.GetValue(o, null)); - } - } - return result; - } - /// - /// Turns the object into a Dictionary - /// - public static IDictionary ToDictionary(this object thingy) - { - return (IDictionary)thingy.ToExpando(); - } - } - /// - /// A class that wraps your database table in Dynamic Funtime - /// - public class DynamicModel - { - DbProviderFactory _factory; - string _connectionString; - - public DynamicModel(string connectionStringName = "", string tableName = "", string primaryKeyField = "") - { - _factory = DbProviderFactories.GetFactory("System.Data.SqlClient"); - /* - TableName = tableName == "" ? this.GetType().Name : tableName; - PrimaryKeyField = string.IsNullOrEmpty(primaryKeyField) ? "ID" : primaryKeyField; - if (connectionStringName == "") - connectionStringName = ConfigurationManager.ConnectionStrings[0].Name; - var _providerName = "System.Data.SqlClient"; - if (ConfigurationManager.ConnectionStrings[connectionStringName] != null) - { - if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName)) - _providerName = ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName; - } - else - { - throw new InvalidOperationException("Can't find a connection string with the name '" + connectionStringName + "'"); - } - _factory = DbProviderFactories.GetFactory(_providerName); - _connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; - */ - } - /// - /// Enumerates the reader yielding the result - thanks to Jeroen Haegebaert - /// - public virtual IEnumerable Query(string sql, params object[] args) - { - using (var conn = OpenConnection()) - { - var rdr = CreateCommand(sql, conn, args).ExecuteReader(); - while (rdr.Read()) - { - yield return rdr.RecordToExpando(); ; - } - } - } - public virtual IEnumerable Query(string sql, DbConnection connection, params object[] args) - { - using (var rdr = CreateCommand(sql, connection, args).ExecuteReader()) - { - while (rdr.Read()) - { - yield return rdr.RecordToExpando(); ; - } - } - - } - /// - /// Returns a single result - /// - public virtual object Scalar(string sql, params object[] args) - { - object result = null; - using (var conn = OpenConnection()) - { - result = CreateCommand(sql, conn, args).ExecuteScalar(); - } - return result; - } - /// - /// Creates a DBCommand that you can use for loving your database. - /// - DbCommand CreateCommand(string sql, DbConnection conn, params object[] args) - { - var result = _factory.CreateCommand(); - result.Connection = conn; - result.CommandText = sql; - if (args.Length > 0) - result.AddParams(args); - return result; - } - /// - /// Returns and OpenConnection - /// - public virtual DbConnection OpenConnection() - { - var result = _factory.CreateConnection(); - result.ConnectionString = _connectionString; - result.Open(); - return result; - } - /// - /// Builds a set of Insert and Update commands based on the passed-on objects. - /// These objects can be POCOs, Anonymous, NameValueCollections, or Expandos. Objects - /// With a PK property (whatever PrimaryKeyField is set to) will be created at UPDATEs - /// - public virtual List BuildCommands(params object[] things) - { - var commands = new List(); - foreach (var item in things) - { - if (HasPrimaryKey(item)) - { - commands.Add(CreateUpdateCommand(item, GetPrimaryKey(item))); - } - else - { - commands.Add(CreateInsertCommand(item)); - } - } - - return commands; - } - /// - /// Executes a set of objects as Insert or Update commands based on their property settings, within a transaction. - /// These objects can be POCOs, Anonymous, NameValueCollections, or Expandos. Objects - /// With a PK property (whatever PrimaryKeyField is set to) will be created at UPDATEs - /// - public virtual int Save(params object[] things) - { - var commands = BuildCommands(things); - return Execute(commands); - } - public virtual int Execute(DbCommand command) - { - return Execute(new DbCommand[] { command }); - } - /// - /// Executes a series of DBCommands in a transaction - /// - public virtual int Execute(IEnumerable commands) - { - var result = 0; - using (var conn = OpenConnection()) - { - using (var tx = conn.BeginTransaction()) - { - foreach (var cmd in commands) - { - cmd.Connection = conn; - cmd.Transaction = tx; - result += cmd.ExecuteNonQuery(); - } - tx.Commit(); - } - } - return result; - } - public virtual string PrimaryKeyField { get; set; } - /// - /// Conventionally introspects the object passed in for a field that - /// looks like a PK. If you've named your PrimaryKeyField, this becomes easy - /// - public virtual bool HasPrimaryKey(object o) - { - return o.ToDictionary().ContainsKey(PrimaryKeyField); - } - /// - /// If the object passed in has a property with the same name as your PrimaryKeyField - /// it is returned here. - /// - public virtual object GetPrimaryKey(object o) - { - object result = null; - o.ToDictionary().TryGetValue(PrimaryKeyField, out result); - return result; - } - public virtual string TableName { get; set; } - /// - /// Creates a command for use with transactions - internal stuff mostly, but here for you to play with - /// - public virtual DbCommand CreateInsertCommand(object o) - { - DbCommand result = null; - var expando = o.ToExpando(); - var settings = (IDictionary)expando; - var sbKeys = new StringBuilder(); - var sbVals = new StringBuilder(); - var stub = "INSERT INTO {0} ({1}) \r\n VALUES ({2})"; - result = CreateCommand(stub, null); - int counter = 0; - foreach (var item in settings) - { - sbKeys.AppendFormat("{0},", item.Key); - sbVals.AppendFormat("@{0},", counter.ToString()); - result.AddParam(item.Value); - counter++; - } - if (counter > 0) - { - var keys = sbKeys.ToString().Substring(0, sbKeys.Length - 1); - var vals = sbVals.ToString().Substring(0, sbVals.Length - 1); - var sql = string.Format(stub, TableName, keys, vals); - result.CommandText = sql; - } - else throw new InvalidOperationException("Can't parse this object to the database - there are no properties set"); - return result; - } - /// - /// Creates a command for use with transactions - internal stuff mostly, but here for you to play with - /// - public virtual DbCommand CreateUpdateCommand(object o, object key) - { - var expando = o.ToExpando(); - var settings = (IDictionary)expando; - var sbKeys = new StringBuilder(); - var stub = "UPDATE {0} SET {1} WHERE {2} = @{3}"; - var args = new List(); - var result = CreateCommand(stub, null); - int counter = 0; - foreach (var item in settings) - { - var val = item.Value; - if (!item.Key.Equals(PrimaryKeyField, StringComparison.CurrentCultureIgnoreCase) && item.Value != null) - { - result.AddParam(val); - sbKeys.AppendFormat("{0} = @{1}, \r\n", item.Key, counter.ToString()); - counter++; - } - } - if (counter > 0) - { - //add the key - result.AddParam(key); - //strip the last commas - var keys = sbKeys.ToString().Substring(0, sbKeys.Length - 4); - result.CommandText = string.Format(stub, TableName, keys, PrimaryKeyField, counter); - } - else throw new InvalidOperationException("No parsable object was sent in - could not divine any name/value pairs"); - return result; - } - /// - /// Removes one or more records from the DB according to the passed-in WHERE - /// - public virtual DbCommand CreateDeleteCommand(string where = "", object key = null, params object[] args) - { - var sql = string.Format("DELETE FROM {0} ", TableName); - if (key != null) - { - sql += string.Format("WHERE {0}=@0", PrimaryKeyField); - args = new object[] { key }; - } - else if (!string.IsNullOrEmpty(where)) - { - sql += where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase) ? where : "WHERE " + where; - } - return CreateCommand(sql, null, args); - } - /// - /// Adds a record to the database. You can pass in an Anonymous object, an ExpandoObject, - /// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString - /// - public virtual object Insert(object o) - { - dynamic result = 0; - using (var conn = OpenConnection()) - { - var cmd = CreateInsertCommand(o); - cmd.Connection = conn; - cmd.ExecuteNonQuery(); - cmd.CommandText = "SELECT @@IDENTITY as newID"; - result = cmd.ExecuteScalar(); - } - return result; - } - /// - /// Updates a record in the database. You can pass in an Anonymous object, an ExpandoObject, - /// A regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString - /// - public virtual int Update(object o, object key) - { - return Execute(CreateUpdateCommand(o, key)); - } - /// - /// Removes one or more records from the DB according to the passed-in WHERE - /// - public int Delete(object key = null, string where = "", params object[] args) - { - return Execute(CreateDeleteCommand(where: where, key: key, args: args)); - } - /// - /// Returns all records complying with the passed-in WHERE clause and arguments, - /// ordered as specified, limited (TOP) by limit. - /// - public virtual IEnumerable All(string where = "", string orderBy = "", int limit = 0, string columns = "*", params object[] args) - { - string sql = limit > 0 ? "SELECT TOP " + limit + " {0} FROM {1} " : "SELECT {0} FROM {1} "; - if (!string.IsNullOrEmpty(where)) - sql += where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase) ? where : "WHERE " + where; - if (!String.IsNullOrEmpty(orderBy)) - sql += orderBy.Trim().StartsWith("order by", StringComparison.CurrentCultureIgnoreCase) ? orderBy : " ORDER BY " + orderBy; - return Query(string.Format(sql, columns, TableName), args); - } - - /// - /// Returns a dynamic PagedResult. Result properties are Items, TotalPages, and TotalRecords. - /// - public virtual dynamic Paged(string where = "", string orderBy = "", string columns = "*", int pageSize = 20, int currentPage = 1, params object[] args) - { - dynamic result = new ExpandoObject(); - var countSQL = string.Format("SELECT COUNT({0}) FROM {1}", PrimaryKeyField, TableName); - if (String.IsNullOrEmpty(orderBy)) - orderBy = PrimaryKeyField; - - if (!string.IsNullOrEmpty(where)) - { - if (!where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase)) - { - where = "WHERE " + where; - } - } - var sql = string.Format("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {2}) AS Row, {0} FROM {3} {4}) AS Paged ", columns, pageSize, orderBy, TableName, where); - var pageStart = (currentPage - 1) * pageSize; - sql += string.Format(" WHERE Row >={0} AND Row <={1}", pageStart, (pageStart + pageSize)); - countSQL += where; - result.TotalRecords = Scalar(countSQL, args); - result.TotalPages = result.TotalRecords / pageSize; - if (result.TotalRecords % pageSize > 0) - result.TotalPages += 1; - result.Items = Query(string.Format(sql, columns, TableName), args); - return result; - } - /// - /// Returns a single row from the database - /// - public virtual dynamic Single(object key, string columns = "*") - { - var sql = string.Format("SELECT {0} FROM {1} WHERE {2} = @0", columns, TableName, PrimaryKeyField); - var items = Query(sql, key).ToList(); - return items.FirstOrDefault(); - } - } -} \ No newline at end of file diff --git a/src/dapper-dot-net/PerformanceTests.cs b/src/dapper-dot-net/PerformanceTests.cs deleted file mode 100644 index 92d13eec0..000000000 --- a/src/dapper-dot-net/PerformanceTests.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Data.SqlClient; -using ServiceStack.OrmLite; -using ServiceStack.OrmLite.SqlServer; -using SqlMapper.Linq2Sql; -using System.Data.Linq; -using System.Diagnostics; -using Massive; - -namespace SqlMapper -{ - class PerformanceTests - { - - class Test - { - public static Test Create(Action iteration, string name) - { - return new Test {Iteration = iteration, Name = name }; - } - - public Action Iteration { get; set; } - public string Name { get; set; } - public Stopwatch Watch { get; set; } - } - - class Tests : List - { - public void Add(Action iteration, string name) - { - Add(Test.Create(iteration, name)); - } - - public void Run(int iterations) - { - // warmup - foreach (var test in this) - { - test.Iteration(iterations + 1); - test.Watch = new Stopwatch(); - test.Watch.Reset(); - } - - var rand = new Random(); - for (int i = 1; i <= iterations; i++) - { - foreach (var test in this.OrderBy(ignore => rand.Next())) - { - test.Watch.Start(); - test.Iteration(i); - test.Watch.Stop(); - } - } - - foreach (var test in this.OrderBy(t => t.Watch.ElapsedMilliseconds)) - { - Console.WriteLine(test.Name + " took " + test.Watch.ElapsedMilliseconds + "ms"); - } - } - } - - static DataClassesDataContext GetL2SContext() - { - return new DataClassesDataContext(Program.GetOpenConnection()); - } - - public void Run(int iterations) - { - var tests = new Tests(); - - var l2scontext1 = GetL2SContext(); - tests.Add(id => l2scontext1.Posts.First(p => p.Id == id), "Linq 2 SQL"); - - var l2scontext2 = GetL2SContext(); - var compiledGetPost = CompiledQuery.Compile((Linq2Sql.DataClassesDataContext ctx, int id) => ctx.Posts.First(p => p.Id == id)); - tests.Add(id => compiledGetPost(l2scontext2,id), "Linq 2 SQL Compiled"); - - var l2scontext3 = GetL2SContext(); - tests.Add(id => l2scontext3.ExecuteQuery("select * from Posts where Id = {0}", id).ToList(), "Linq 2 SQL ExecuteQuery"); - - //Comment out EF to suppress exception - //var entityContext = new EntityFramework.tempdbEntities1(); - //entityContext.Connection.Open(); - //tests.Add(id => entityContext.Posts.First(p => p.Id == id), "Entity framework"); - - //var entityContext2 = new EntityFramework.tempdbEntities1(); - //entityContext2.Connection.Open(); - //tests.Add(id => entityContext.ExecuteStoreQuery("select * from Posts where Id = {0}", id).ToList(), "Entity framework ExecuteStoreQuery"); - - var mapperConnection = Program.GetOpenConnection(); - tests.Add(id => mapperConnection.Query("select * from Posts where Id = @Id", new { Id = id }).ToList(), "Mapper Query"); - - //var mapperConnection2 = Program.GetOpenConnection(); - //tests.Add(id => mapperConnection2.Query("select * from Posts where Id = @Id", new { Id = id }).ToList(), "Dynamic Mapper Query"); - - var massiveModel = new DynamicModel(Program.connectionString); - var massiveConnection = Program.GetOpenConnection(); - tests.Add(id => massiveModel.Query("select * from Posts where Id = @0", massiveConnection, id).ToList(), "Dynamic Massive ORM Query"); - - - //ServiceStack.OrmLite Provider: - OrmLiteConfig.DialectProvider = SqlServerOrmLiteDialectProvider.Instance; //Using SQL Server - IDbConnection ormLiteConn = Program.GetOpenConnection(); - tests.Add(id => ormLiteConn.SelectFmt("select * from Posts where Id = {0}", id), "OrmLite Query"); - - // HAND CODED - var connection = Program.GetOpenConnection(); - - var postCommand = new SqlCommand(); - postCommand.Connection = connection; - postCommand.CommandText = @"select Id, [Text], [CreationDate], LastChangeDate, - Counter1,Counter2,Counter3,Counter4,Counter5,Counter6,Counter7,Counter8,Counter9 from Posts where Id = @Id"; - var idParam = postCommand.Parameters.Add("@Id", System.Data.SqlDbType.Int); - - tests.Add(id => - { - idParam.Value = id; - - using (var reader = postCommand.ExecuteReader()) - { - reader.Read(); - var post = new Post(); - post.Id = reader.GetInt32(0); - post.Text = reader.GetNullableString(1); - post.CreationDate = reader.GetDateTime(2); - post.LastChangeDate = reader.GetDateTime(3); - - post.Counter1 = reader.GetNullableValue(4); - post.Counter2 = reader.GetNullableValue(5); - post.Counter3 = reader.GetNullableValue(6); - post.Counter4 = reader.GetNullableValue(7); - post.Counter5 = reader.GetNullableValue(8); - post.Counter6 = reader.GetNullableValue(9); - post.Counter7 = reader.GetNullableValue(10); - post.Counter8 = reader.GetNullableValue(11); - post.Counter9 = reader.GetNullableValue(12); - } - }, "hand coded"); - - tests.Run(iterations); - } - } - - static class SqlDataReaderHelper - { - public static string GetNullableString(this SqlDataReader reader, int index) - { - object tmp = reader.GetValue(index); - if (tmp != DBNull.Value) - { - return (string)tmp; - } - return null; - } - - public static Nullable GetNullableValue(this SqlDataReader reader, int index) where T : struct - { - object tmp = reader.GetValue(index); - if (tmp != DBNull.Value) - { - return (T)tmp; - } - return null; - } - } -} diff --git a/src/dapper-dot-net/Program.cs b/src/dapper-dot-net/Program.cs deleted file mode 100644 index c3032ae28..000000000 --- a/src/dapper-dot-net/Program.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; -using System.Data.SqlClient; -using System.Data.Metadata.Edm; -using System.Reflection; -using System.Data.EntityClient; -using System.Data.Linq; -using ServiceStack.DataAnnotations; - -namespace SqlMapper -{ - class Post - { - public int Id { get; set; } - public string Text { get; set; } - public DateTime CreationDate { get; set; } - public DateTime LastChangeDate { get; set; } - public int? Counter1 { get; set; } - public int? Counter2 { get; set; } - public int? Counter3 { get; set; } - public int? Counter4 { get; set; } - public int? Counter5 { get; set; } - public int? Counter6 { get; set; } - public int? Counter7 { get; set; } - public int? Counter8 { get; set; } - public int? Counter9 { get; set; } - - } - - class Program - { - - public static readonly string connectionString = "Data Source=IO\\SQLEXPRESS;Initial Catalog=tempdb;Integrated Security=True"; - //public static readonly string connectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True"; - - public static SqlConnection GetOpenConnection() - { - var connection = new SqlConnection(connectionString); - connection.Open(); - return connection; - } - - static void RunPerformanceTests() - { - var test = new PerformanceTests(); - Console.WriteLine("Running 500 itrations that load up a post entity"); - test.Run(500); - } - - static void Main(string[] args) - { - -#if DEBUG - RunTests(); -#else - EnsureDBSetup(); - RunPerformanceTests(); -#endif - - Console.ReadKey(); - } - - private static void EnsureDBSetup() - { - using (var cnn = GetOpenConnection()) - { - var cmd = cnn.CreateCommand(); - cmd.CommandText = @" -if (OBJECT_ID('Posts') is null) -begin - create table Posts - ( - Id int identity primary key, - [Text] varchar(max) not null, - CreationDate datetime not null, - LastChangeDate datetime not null, - Counter1 int, - Counter2 int, - Counter3 int, - Counter4 int, - Counter5 int, - Counter6 int, - Counter7 int, - Counter8 int, - Counter9 int - ) - - set nocount on - - declare @i int - declare @c int - - declare @id int - - set @i = 0 - - while @i < 5000 - begin - - insert Posts ([Text],CreationDate, LastChangeDate) values (replicate('x', 2000), GETDATE(), GETDATE()) - set @id = @@IDENTITY - - set @i = @i + 1 - end -end -"; - cmd.Connection = cnn; - cmd.ExecuteNonQuery(); - } - } - - private static void RunTests() - { - var tester = new Tests(); - foreach (var method in typeof(Tests).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) - { - Console.Write("Running " + method.Name); - method.Invoke(tester, null); - Console.WriteLine(" - OK!"); - } - } - } -} diff --git a/src/dapper-dot-net/Properties/AssemblyInfo.cs b/src/dapper-dot-net/Properties/AssemblyInfo.cs deleted file mode 100644 index 15bf271ed..000000000 --- a/src/dapper-dot-net/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Smackdown")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Smackdown")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("77246f63-77a4-4d9f-a4d6-62282d67c8be")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("4.0.0.0")] -[assembly: AssemblyFileVersion("4.0.0.0")] diff --git a/src/dapper-dot-net/Properties/Settings.Designer.cs b/src/dapper-dot-net/Properties/Settings.Designer.cs deleted file mode 100644 index 8d337e0bb..000000000 --- a/src/dapper-dot-net/Properties/Settings.Designer.cs +++ /dev/null @@ -1,36 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18449 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace SqlMapper.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - - [global::System.Configuration.ApplicationScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] - [global::System.Configuration.DefaultSettingValueAttribute("Data Source=.;Initial Catalog=tempdb;Integrated Security=True")] - public string tempdbConnectionString { - get { - return ((string)(this["tempdbConnectionString"])); - } - } - } -} diff --git a/src/dapper-dot-net/Properties/Settings.settings b/src/dapper-dot-net/Properties/Settings.settings deleted file mode 100644 index d145a094b..000000000 --- a/src/dapper-dot-net/Properties/Settings.settings +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - <?xml version="1.0" encoding="utf-16"?> -<SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> - <ConnectionString>Data Source=.;Initial Catalog=tempdb;Integrated Security=True</ConnectionString> - <ProviderName>System.Data.SqlClient</ProviderName> -</SerializableConnectionString> - Data Source=.;Initial Catalog=tempdb;Integrated Security=True - - - \ No newline at end of file diff --git a/src/dapper-dot-net/SqlMapper.cs b/src/dapper-dot-net/SqlMapper.cs deleted file mode 100644 index b1328332e..000000000 --- a/src/dapper-dot-net/SqlMapper.cs +++ /dev/null @@ -1,2160 +0,0 @@ -#define CSHARP30 - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Data.SqlClient; -using System.Reflection.Emit; -using System.Collections.Concurrent; -using System.Data; -using System.Reflection; -using System.Text.RegularExpressions; -using System.Threading; -using Microsoft.SqlServer.Server; -using System.Dynamic; -using System.Collections; - -namespace SqlMapper -{ - /// - /// Dapper, a light weight object mapper for ADO.NET - /// - public static partial class SqlMapper - { - /// - /// Implement this interface to pass an arbitrary db specific set of parameters to Dapper - /// - public interface IDynamicParameters - { - /// - /// Add all the parameters needed to the command just before it executes - /// - /// The raw command prior to execution - /// Information about the query - void AddParameters(IDbCommand command, Identity identity); - } - static Link> bindByNameCache; - static Action GetBindByName(Type commandType) - { - if (commandType == null) return null; // GIGO - Action action; - if (Link>.TryGet(bindByNameCache, commandType, out action)) - { - return action; - } - var prop = commandType.GetProperty("BindByName", BindingFlags.Public | BindingFlags.Instance); - action = null; - ParameterInfo[] indexers; - MethodInfo setter; - if (prop != null && prop.CanWrite && prop.PropertyType == typeof(bool) - && ((indexers = prop.GetIndexParameters()) == null || indexers.Length == 0) - && (setter = prop.GetSetMethod()) != null - ) - { - var method = new DynamicMethod(commandType.Name + "_BindByName", null, new Type[] { typeof(IDbCommand), typeof(bool) }); - var il = method.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Castclass, commandType); - il.Emit(OpCodes.Ldarg_1); - il.EmitCall(OpCodes.Callvirt, setter, null); - il.Emit(OpCodes.Ret); - action = (Action)method.CreateDelegate(typeof(Action)); - } - // cache it - Link>.TryAdd(ref bindByNameCache, commandType, ref action); - return action; - } - /// - /// This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - /// and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - /// equality. The type is fully thread-safe. - /// - class Link where TKey : class - { - public static bool TryGet(Link link, TKey key, out TValue value) - { - while (link != null) - { - if ((object)key == (object)link.Key) - { - value = link.Value; - return true; - } - link = link.Tail; - } - value = default(TValue); - return false; - } - public static bool TryAdd(ref Link head, TKey key, ref TValue value) - { - bool tryAgain; - do - { - var snapshot = Interlocked.CompareExchange(ref head, null, null); - TValue found; - if (TryGet(snapshot, key, out found)) - { // existing match; report the existing value instead - value = found; - return false; - } - var newNode = new Link(key, value, snapshot); - // did somebody move our cheese? - tryAgain = Interlocked.CompareExchange(ref head, newNode, snapshot) != snapshot; - } while (tryAgain); - return true; - } - private Link(TKey key, TValue value, Link tail) - { - Key = key; - Value = value; - Tail = tail; - } - public TKey Key { get; private set; } - public TValue Value { get; private set; } - public Link Tail { get; private set; } - } - class CacheInfo - { - public Func Deserializer { get; set; } - public Func[] OtherDeserializers { get; set; } - public Action ParamReader { get; set; } - private int hitCount; - public int GetHitCount() { return Interlocked.CompareExchange(ref hitCount, 0, 0); } - public void RecordHit() { Interlocked.Increment(ref hitCount); } - } - - /// - /// Called if the query cache is purged via PurgeQueryCache - /// - public static event EventHandler QueryCachePurged; - private static void OnQueryCachePurged() - { - var handler = QueryCachePurged; - if (handler != null) handler(null, EventArgs.Empty); - } -#if CSHARP30 - private static readonly Dictionary _queryCache = new Dictionary(); - // note: conflicts between readers and writers are so short-lived that it isn't worth the overhead of - // ReaderWriterLockSlim etc; a simple lock is faster - private static void SetQueryCache(Identity key, CacheInfo value) - { - lock (_queryCache) { _queryCache[key] = value; } - } - private static bool TryGetQueryCache(Identity key, out CacheInfo value) - { - lock (_queryCache) { return _queryCache.TryGetValue(key, out value); } - } - public static void PurgeQueryCache() - { - lock (_queryCache) - { - _queryCache.Clear(); - } - OnQueryCachePurged(); - } -#else - static readonly System.Collections.Concurrent.ConcurrentDictionary _queryCache = new System.Collections.Concurrent.ConcurrentDictionary(); - private static void SetQueryCache(Identity key, CacheInfo value) - { - if (Interlocked.Increment(ref collect) == COLLECT_PER_ITEMS) - { - CollectCacheGarbage(); - } - _queryCache[key] = value; - } - - private static void CollectCacheGarbage() - { - try - { - foreach (var pair in _queryCache) - { - if (pair.Value.GetHitCount() <= COLLECT_HIT_COUNT_MIN) - { - CacheInfo cache; - _queryCache.TryRemove(pair.Key, out cache); - } - } - } - - finally - { - Interlocked.Exchange(ref collect, 0); - } - } - - private const int COLLECT_PER_ITEMS = 1000, COLLECT_HIT_COUNT_MIN = 0; - private static int collect; - private static bool TryGetQueryCache(Identity key, out CacheInfo value) - { - if (_queryCache.TryGetValue(key, out value)) - { - value.RecordHit(); - return true; - } - value = null; - return false; - } - - /// - /// Purge the query cache - /// - public static void PurgeQueryCache() - { - _queryCache.Clear(); - OnQueryCachePurged(); - } - - /// - /// Return a count of all the cached queries by dapper - /// - /// - public static int GetCachedSQLCount() - { - return _queryCache.Count; - } - - /// - /// Return a list of all the queries cached by dapper - /// - /// - /// - public static IEnumerable> GetCachedSQL(int ignoreHitCountAbove = int.MaxValue) - { - var data = _queryCache.Select(pair => Tuple.Create(pair.Key.connectionString, pair.Key.sql, pair.Value.GetHitCount())); - if (ignoreHitCountAbove < int.MaxValue) data = data.Where(tuple => tuple.Item3 <= ignoreHitCountAbove); - return data; - } - - /// - /// Deep diagnostics only: find any hash collisions in the cache - /// - /// - public static IEnumerable> GetHashCollissions() - { - var counts = new Dictionary(); - foreach (var key in _queryCache.Keys) - { - int count; - if (!counts.TryGetValue(key.hashCode, out count)) - { - counts.Add(key.hashCode, 1); - } - else - { - counts[key.hashCode] = count + 1; - } - } - return from pair in counts - where pair.Value > 1 - select Tuple.Create(pair.Key, pair.Value); - - } -#endif - - - static readonly Dictionary typeMap; - - static SqlMapper() - { - typeMap = new Dictionary(); - typeMap[typeof(byte)] = DbType.Byte; - typeMap[typeof(sbyte)] = DbType.SByte; - typeMap[typeof(short)] = DbType.Int16; - typeMap[typeof(ushort)] = DbType.UInt16; - typeMap[typeof(int)] = DbType.Int32; - typeMap[typeof(uint)] = DbType.UInt32; - typeMap[typeof(long)] = DbType.Int64; - typeMap[typeof(ulong)] = DbType.UInt64; - typeMap[typeof(float)] = DbType.Single; - typeMap[typeof(double)] = DbType.Double; - typeMap[typeof(decimal)] = DbType.Decimal; - typeMap[typeof(bool)] = DbType.Boolean; - typeMap[typeof(string)] = DbType.String; - typeMap[typeof(char)] = DbType.StringFixedLength; - typeMap[typeof(Guid)] = DbType.Guid; - typeMap[typeof(DateTime)] = DbType.DateTime; - typeMap[typeof(DateTimeOffset)] = DbType.DateTimeOffset; - typeMap[typeof(byte[])] = DbType.Binary; - typeMap[typeof(byte?)] = DbType.Byte; - typeMap[typeof(sbyte?)] = DbType.SByte; - typeMap[typeof(short?)] = DbType.Int16; - typeMap[typeof(ushort?)] = DbType.UInt16; - typeMap[typeof(int?)] = DbType.Int32; - typeMap[typeof(uint?)] = DbType.UInt32; - typeMap[typeof(long?)] = DbType.Int64; - typeMap[typeof(ulong?)] = DbType.UInt64; - typeMap[typeof(float?)] = DbType.Single; - typeMap[typeof(double?)] = DbType.Double; - typeMap[typeof(decimal?)] = DbType.Decimal; - typeMap[typeof(bool?)] = DbType.Boolean; - typeMap[typeof(char?)] = DbType.StringFixedLength; - typeMap[typeof(Guid?)] = DbType.Guid; - typeMap[typeof(DateTime?)] = DbType.DateTime; - typeMap[typeof(DateTimeOffset?)] = DbType.DateTimeOffset; - } - - private const string LinqBinary = "System.Data.Linq.Binary"; - private static DbType LookupDbType(Type type, string name) - { - DbType dbType; - var nullUnderlyingType = Nullable.GetUnderlyingType(type); - if (nullUnderlyingType != null) type = nullUnderlyingType; - if (type.IsEnum) - { - type = Enum.GetUnderlyingType(type); - } - if (typeMap.TryGetValue(type, out dbType)) - { - return dbType; - } - if (type.FullName == LinqBinary) - { - return DbType.Binary; - } - if (typeof(IEnumerable).IsAssignableFrom(type)) - { - // use xml to denote its a list, hacky but will work on any DB - return DbType.Xml; - } - - - throw new NotSupportedException(string.Format("The member {0} of type {1} cannot be used as a parameter value", name, type)); - } - - /// - /// Identity of a cached query in Dapper, used for extensability - /// - public class Identity : IEquatable - { - internal Identity ForGrid(Type primaryType, int gridIndex) - { - return new Identity(sql, commandType, connectionString, primaryType, parametersType, null, gridIndex); - } - - internal Identity ForGrid(Type primaryType, Type[] otherTypes, int gridIndex) - { - return new Identity(sql, commandType, connectionString, primaryType, parametersType, otherTypes, gridIndex); - } - /// - /// Create an identity for use with DynamicParameters, internal use only - /// - /// - /// - public Identity ForDynamicParameters(Type type) - { - return new Identity(sql, commandType, connectionString, this.type, type, null, -1); - } - - internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, Type[] otherTypes) - : this(sql, commandType, connection.ConnectionString, type, parametersType, otherTypes, 0) - { } - private Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex) - { - this.sql = sql; - this.commandType = commandType; - this.connectionString = connectionString; - this.type = type; - this.parametersType = parametersType; - this.gridIndex = gridIndex; - unchecked - { - hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this - hashCode = hashCode * 23 + commandType.GetHashCode(); - hashCode = hashCode * 23 + gridIndex.GetHashCode(); - hashCode = hashCode * 23 + (sql == null ? 0 : sql.GetHashCode()); - hashCode = hashCode * 23 + (type == null ? 0 : type.GetHashCode()); - if (otherTypes != null) - { - foreach (var t in otherTypes) - { - hashCode = hashCode * 23 + (t == null ? 0 : t.GetHashCode()); - } - } - hashCode = hashCode * 23 + (connectionString == null ? 0 : connectionString.GetHashCode()); - hashCode = hashCode * 23 + (parametersType == null ? 0 : parametersType.GetHashCode()); - } - } - - /// - /// - /// - /// - /// - public override bool Equals(object obj) - { - return Equals(obj as Identity); - } - /// - /// The sql - /// - public readonly string sql; - /// - /// The command type - /// - public readonly CommandType? commandType; - - /// - /// - /// - public readonly int hashCode, gridIndex; - private readonly Type type; - /// - /// - /// - public readonly string connectionString; - /// - /// - /// - public readonly Type parametersType; - /// - /// - /// - /// - public override int GetHashCode() - { - return hashCode; - } - /// - /// Compare 2 Identity objects - /// - /// - /// - public bool Equals(Identity other) - { - return - other != null && - gridIndex == other.gridIndex && - type == other.type && - sql == other.sql && - commandType == other.commandType && - connectionString == other.connectionString && - parametersType == other.parametersType; - } - } - -#if CSHARP30 - /// - /// Execute parameterized SQL - /// - /// Number of rows affected - public static int Execute(this IDbConnection cnn, string sql, object param = null) - { - return Execute(cnn, sql, param, null, null, null); - } - /// - /// Executes a query, returning the data typed as per T - /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new get new object - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, object param=null) - { - return Query(cnn, sql, param, null, true, null, null); - } - -#endif - /// - /// Execute parameterized SQL - /// - /// Number of rows affected - public static int Execute( -#if CSHARP30 - this IDbConnection cnn, string sql, object param=null, IDbTransaction transaction=null, int? commandTimeout=null, CommandType? commandType=null -#else -this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - IEnumerable multiExec = (object)param as IEnumerable; - Identity identity; - CacheInfo info = null; - if (multiExec != null && !(multiExec is string)) - { - bool isFirst = true; - int total = 0; - using (var cmd = SetupCommand(cnn, transaction, sql, null, null, commandTimeout, commandType)) - { - - string masterSql = null; - foreach (var obj in multiExec) - { - if (isFirst) - { - masterSql = cmd.CommandText; - isFirst = false; - identity = new Identity(sql, cmd.CommandType, cnn, null, obj.GetType(), null); - info = GetCacheInfo(identity); - } - else - { - cmd.CommandText = masterSql; // because we do magic replaces on "in" etc - cmd.Parameters.Clear(); // current code is Add-tastic - } - info.ParamReader(cmd, obj); - total += cmd.ExecuteNonQuery(); - } - } - return total; - } - - // nice and simple - if ((object)param != null) - { - identity = new Identity(sql, commandType, cnn, null, (object)param == null ? null : ((object)param).GetType(), null); - info = GetCacheInfo(identity); - } - return ExecuteCommand(cnn, transaction, sql, (object)param == null ? null : info.ParamReader, (object)param, commandTimeout, commandType); - } -#if !CSHARP30 - /// - /// Return a list of dynamic objects, reader is closed after the call - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) - { - return Query(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType); - } -#endif - - /// - /// Executes a query, returning the data typed as per T - /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is - /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). - /// - public static IEnumerable Query( -#if CSHARP30 - this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - var data = QueryInternal(cnn, sql, param as object, transaction, commandTimeout, commandType); - return buffered ? data.ToList() : data; - } - - /// - /// Execute a command that returns multiple result sets, and access each in turn - /// - public static GridReader QueryMultiple( -#if CSHARP30 - this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - Identity identity = new Identity(sql, commandType, cnn, typeof(GridReader), (object)param == null ? null : ((object)param).GetType(), null); - CacheInfo info = GetCacheInfo(identity); - - IDbCommand cmd = null; - IDataReader reader = null; - try - { - cmd = SetupCommand(cnn, transaction, sql, info.ParamReader, (object)param, commandTimeout, commandType); - reader = cmd.ExecuteReader(); - return new GridReader(cmd, reader, identity); - } - catch - { - if (reader != null) reader.Dispose(); - if (cmd != null) cmd.Dispose(); - throw; - } - } - - /// - /// Return a typed list of objects, reader is closed after the call - /// - private static IEnumerable QueryInternal(this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType) - { - var identity = new Identity(sql, commandType, cnn, typeof(T), param == null ? null : param.GetType(), null); - var info = GetCacheInfo(identity); - - using (var cmd = SetupCommand(cnn, transaction, sql, info.ParamReader, param, commandTimeout, commandType)) - { - using (var reader = cmd.ExecuteReader()) - { - Func> cacheDeserializer = () => { - info.Deserializer = GetDeserializer(typeof(T), reader, 0, -1, false); - SetQueryCache(identity, info); - return info.Deserializer; - }; - - if (info.Deserializer == null) - { - cacheDeserializer(); - } - - var deserializer = info.Deserializer; - - while (reader.Read()) - { - object next; - try - { - next = deserializer(reader); - } - catch (DataException) - { - // give it another shot, in case the underlying schema changed - deserializer = cacheDeserializer(); - next = deserializer(reader); - } - yield return (T)next; - } - - } - } - } - - /// - /// Maps a query to objects - /// - /// The first type in the recordset - /// The second type in the recordset - /// The return type - /// - /// - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout - /// Is it a stored proc or a batch? - /// - public static IEnumerable Query( -#if CSHARP30 - this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Maps a query to objects - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout - /// - /// - public static IEnumerable Query( -#if CSHARP30 - this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with 4 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query( -#if CSHARP30 - this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType -#else -this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -#endif -) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } -#if !CSHARP30 - /// - /// Perform a multi mapping query with 5 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); - } -#endif - class DontMap { } - static IEnumerable MultiMap( - this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType) - { - var results = MultiMapImpl(cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null); - return buffered ? results.ToList() : results; - } - - - static IEnumerable MultiMapImpl(this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, string splitOn, int? commandTimeout, CommandType? commandType, IDataReader reader, Identity identity) - { - identity = identity ?? new Identity(sql, commandType, cnn, typeof(TFirst), (object)param == null ? null : ((object)param).GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth) }); - CacheInfo cinfo = GetCacheInfo(identity); - - IDbCommand ownedCommand = null; - IDataReader ownedReader = null; - - try - { - if (reader == null) - { - ownedCommand = SetupCommand(cnn, transaction, sql, cinfo.ParamReader, (object)param, commandTimeout, commandType); - ownedReader = ownedCommand.ExecuteReader(); - reader = ownedReader; - } - Func deserializer = null; - Func[] otherDeserializers = null; - - Action cacheDeserializers = () => { - var deserializers = GenerateDeserializers(new Type[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth) }, splitOn, reader); - deserializer = cinfo.Deserializer = deserializers[0]; - otherDeserializers = cinfo.OtherDeserializers = deserializers.Skip(1).ToArray(); - SetQueryCache(identity, cinfo); - }; - - if ((deserializer = cinfo.Deserializer) == null || (otherDeserializers = cinfo.OtherDeserializers) == null) - { - cacheDeserializers(); - } - - Func mapIt = GenerateMapper(deserializer, otherDeserializers, map); - - if (mapIt != null) - { - while (reader.Read()) - { - TReturn next; - try - { - next = mapIt(reader); - } - catch (DataException) - { - cacheDeserializers(); - mapIt = GenerateMapper(deserializer, otherDeserializers, map); - next = mapIt(reader); - } - yield return next; - } - } - } - finally - { - try - { - if (ownedReader != null) - { - ownedReader.Dispose(); - } - } - finally - { - if (ownedCommand != null) - { - ownedCommand.Dispose(); - } - } - } - } - - private static Func GenerateMapper(Func deserializer, Func[] otherDeserializers, object map) - { - switch (otherDeserializers.Length) - { - case 1: - return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r)); - case 2: - return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r)); - case 3: - return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r)); -#if !CSHARP30 - case 4: - return r => ((Func)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r)); -#endif - default: - throw new NotSupportedException(); - } - } - - private static Func[] GenerateDeserializers(Type[] types, string splitOn, IDataReader reader) - { - int current = 0; - var splits = splitOn.Split(',').ToArray(); - var splitIndex = 0; - - Func nextSplit = type => { - var currentSplit = splits[splitIndex]; - if (splits.Length > splitIndex + 1) - { - splitIndex++; - } - - bool skipFirst = false; - int startingPos = current + 1; - // if our current type has the split, skip the first time you see it. - if (type != typeof(Object)) - { - var props = GetSettableProps(type); - var fields = GetSettableFields(type); - - foreach (var name in props.Select(p => p.Name).Concat(fields.Select(f => f.Name))) - { - if (string.Equals(name, currentSplit, StringComparison.OrdinalIgnoreCase)) - { - skipFirst = true; - startingPos = current; - break; - } - } - - } - - int pos; - for (pos = startingPos; pos < reader.FieldCount; pos++) - { - // some people like ID some id ... assuming case insensitive splits for now - if (splitOn == "*") - { - break; - } - if (string.Equals(reader.GetName(pos), currentSplit, StringComparison.OrdinalIgnoreCase)) - { - if (skipFirst) - { - skipFirst = false; - } - else - { - break; - } - } - } - current = pos; - return pos; - }; - - var deserializers = new List>(); - int split = 0; - bool first = true; - foreach (var type in types) - { - if (type != typeof(DontMap)) - { - int next = nextSplit(type); - deserializers.Add(GetDeserializer(type, reader, split, next - split, /* returnNullIfFirstMissing: */ !first)); - first = false; - split = next; - } - } - - return deserializers.ToArray(); - } - - private static CacheInfo GetCacheInfo(Identity identity) - { - CacheInfo info; - if (!TryGetQueryCache(identity, out info)) - { - info = new CacheInfo(); - if (identity.parametersType != null) - { - if (typeof(IDynamicParameters).IsAssignableFrom(identity.parametersType)) - { - info.ParamReader = (cmd, obj) => { (obj as IDynamicParameters).AddParameters(cmd, identity); }; - } - else - { - info.ParamReader = CreateParamInfoGenerator(identity); - } - } - SetQueryCache(identity, info); - } - return info; - } - - private static Func GetDeserializer(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing) - { -#if !CSHARP30 - // dynamic is passed in as Object ... by c# design - if (type == typeof(object) - || type == typeof(FastExpando)) - { - return GetDynamicDeserializer(reader, startBound, length, returnNullIfFirstMissing); - } -#endif - - if (!(typeMap.ContainsKey(type) || type.FullName == LinqBinary)) - { - return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing); - } - - return GetStructDeserializer(type, startBound); - - } -#if !CSHARP30 - private class FastExpando : System.Dynamic.DynamicObject, IDictionary - { - IDictionary data; - - public static FastExpando Attach(IDictionary data) - { - return new FastExpando { data = data }; - } - - public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value) - { - data[binder.Name] = value; - return true; - } - - public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result) - { - return data.TryGetValue(binder.Name, out result); - } - - public override IEnumerable GetDynamicMemberNames() - { - return data.Keys; - } - - #region IDictionary Members - - void IDictionary.Add(string key, object value) - { - throw new NotImplementedException(); - } - - bool IDictionary.ContainsKey(string key) - { - return data.ContainsKey(key); - } - - ICollection IDictionary.Keys - { - get { return data.Keys; } - } - - bool IDictionary.Remove(string key) - { - throw new NotImplementedException(); - } - - bool IDictionary.TryGetValue(string key, out object value) - { - return data.TryGetValue(key, out value); - } - - ICollection IDictionary.Values - { - get { return data.Values; } - } - - object IDictionary.this[string key] - { - get - { - return data[key]; - } - set - { - if (!data.ContainsKey(key)) - { - throw new NotImplementedException(); - } - data[key] = value; - } - } - - #endregion - - #region ICollection> Members - - void ICollection>.Add(KeyValuePair item) - { - throw new NotImplementedException(); - } - - void ICollection>.Clear() - { - throw new NotImplementedException(); - } - - bool ICollection>.Contains(KeyValuePair item) - { - return data.Contains(item); - } - - void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) - { - data.CopyTo(array, arrayIndex); - } - - int ICollection>.Count - { - get { return data.Count; } - } - - bool ICollection>.IsReadOnly - { - get { return true; } - } - - bool ICollection>.Remove(KeyValuePair item) - { - throw new NotImplementedException(); - } - - #endregion - - #region IEnumerable> Members - - IEnumerator> IEnumerable>.GetEnumerator() - { - return data.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - IEnumerator IEnumerable.GetEnumerator() - { - return data.GetEnumerator(); - } - - #endregion - } - - - private static Func GetDynamicDeserializer(IDataRecord reader, int startBound, int length, bool returnNullIfFirstMissing) - { - var fieldCount = reader.FieldCount; - if (length == -1) - { - length = fieldCount - startBound; - } - - if (fieldCount <= startBound) - { - throw new ArgumentException("When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id", "splitOn"); - } - - return - r => { - IDictionary row = new Dictionary(length); - for (var i = startBound; i < startBound + length; i++) - { - var tmp = r.GetValue(i); - tmp = tmp == DBNull.Value ? null : tmp; - row[r.GetName(i)] = tmp; - if (returnNullIfFirstMissing && i == startBound && tmp == null) - { - return null; - } - } - //we know this is an object so it will not box - return FastExpando.Attach(row); - }; - } -#endif - /// - /// Internal use only - /// - /// - /// - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This method is for internal usage only", false)] - public static char ReadChar(object value) - { - if (value == null || value is DBNull) throw new ArgumentNullException("value"); - string s = value as string; - if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", "value"); - return s[0]; - } - - /// - /// Internal use only - /// - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This method is for internal usage only", false)] - public static char? ReadNullableChar(object value) - { - if (value == null || value is DBNull) return null; - string s = value as string; - if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", "value"); - return s[0]; - } - /// - /// Internal use only - /// - [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This method is for internal usage only", true)] - public static void PackListParameters(IDbCommand command, string namePrefix, object value) - { - // initially we tried TVP, however it performs quite poorly. - // keep in mind SQL support up to 2000 params easily in sp_executesql, needing more is rare - - var list = value as IEnumerable; - var count = 0; - - if (list != null) - { - bool isString = value is IEnumerable; - foreach (var item in list) - { - count++; - var listParam = command.CreateParameter(); - listParam.ParameterName = namePrefix + count; - listParam.Value = item ?? DBNull.Value; - if (isString) - { - listParam.Size = 4000; - if (item != null && ((string)item).Length > 4000) - { - listParam.Size = -1; - } - } - command.Parameters.Add(listParam); - } - - if (count == 0) - { - command.CommandText = Regex.Replace(command.CommandText, @"[?@:]" + Regex.Escape(namePrefix), "(SELECT NULL WHERE 1 = 0)"); - } - else - { - command.CommandText = Regex.Replace(command.CommandText, @"[?@:]" + Regex.Escape(namePrefix), match => { - var grp = match.Value; - var sb = new StringBuilder("(").Append(grp).Append(1); - for (int i = 2; i <= count; i++) - { - sb.Append(',').Append(grp).Append(i); - } - return sb.Append(')').ToString(); - }); - } - } - - } - - private static IEnumerable FilterParameters(IEnumerable parameters, string sql) - { - return parameters.Where(p => Regex.IsMatch(sql, "[@:]" + p.Name + "([^a-zA-Z0-9_]+|$)", RegexOptions.IgnoreCase | RegexOptions.Multiline)); - } - - /// - /// Internal use only - /// - public static Action CreateParamInfoGenerator(Identity identity) - { - Type type = identity.parametersType; - bool filterParams = identity.commandType.GetValueOrDefault(CommandType.Text) == CommandType.Text; - - var dm = new DynamicMethod(string.Format("ParamInfo{0}", Guid.NewGuid()), null, new[] { typeof(IDbCommand), typeof(object) }, type, true); - - var il = dm.GetILGenerator(); - - il.DeclareLocal(type); // 0 - bool haveInt32Arg1 = false; - il.Emit(OpCodes.Ldarg_1); // stack is now [untyped-param] - il.Emit(OpCodes.Unbox_Any, type); // stack is now [typed-param] - il.Emit(OpCodes.Stloc_0);// stack is now empty - - il.Emit(OpCodes.Ldarg_0); // stack is now [command] - il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetProperty("Parameters").GetGetMethod(), null); // stack is now [parameters] - - IEnumerable props = type.GetProperties().OrderBy(p => p.Name); - if (filterParams) - { - props = FilterParameters(props, identity.sql); - } - foreach (var prop in props) - { - if (filterParams) - { - if (identity.sql.IndexOf("@" + prop.Name, StringComparison.InvariantCultureIgnoreCase) < 0 - && identity.sql.IndexOf(":" + prop.Name, StringComparison.InvariantCultureIgnoreCase) < 0) - { // can't see the parameter in the text (even in a comment, etc) - burn it with fire - continue; - } - } - if (prop.PropertyType == typeof(DbString)) - { - il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [typed-param] - il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [dbstring] - il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [dbstring] [command] - il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [dbstring] [command] [name] - il.EmitCall(OpCodes.Callvirt, typeof(DbString).GetMethod("AddParameter"), null); // stack is now [parameters] - continue; - } - DbType dbType = LookupDbType(prop.PropertyType, prop.Name); - if (dbType == DbType.Xml) - { - // this actually represents special handling for list types; - il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [command] - il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [command] [name] - il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [command] [name] [typed-param] - il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [command] [name] [typed-value] - if (prop.PropertyType.IsValueType) - { - il.Emit(OpCodes.Box, prop.PropertyType); // stack is [parameters] [command] [name] [boxed-value] - } - il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod("PackListParameters"), null); // stack is [parameters] - continue; - } - il.Emit(OpCodes.Dup); // stack is now [parameters] [parameters] - - il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [parameters] [command] - il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetMethod("CreateParameter"), null);// stack is now [parameters] [parameters] [parameter] - - il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] - il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("ParameterName").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] - - il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] - EmitInt32(il, (int)dbType);// stack is now [parameters] [parameters] [parameter] [parameter] [db-type] - - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("DbType").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] - - il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] - EmitInt32(il, (int)ParameterDirection.Input);// stack is now [parameters] [parameters] [parameter] [parameter] [dir] - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("Direction").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] - - il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] - il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [parameters] [parameter] [parameter] [typed-param] - il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [parameters] [parameter] [parameter] [typed-value] - bool checkForNull = true; - if (prop.PropertyType.IsValueType) - { - il.Emit(OpCodes.Box, prop.PropertyType); // stack is [parameters] [parameters] [parameter] [parameter] [boxed-value] - if (Nullable.GetUnderlyingType(prop.PropertyType) == null) - { // struct but not Nullable; boxed value cannot be null - checkForNull = false; - } - } - if (checkForNull) - { - if (dbType == DbType.String && !haveInt32Arg1) - { - il.DeclareLocal(typeof(int)); - haveInt32Arg1 = true; - } - // relative stack: [boxed value] - il.Emit(OpCodes.Dup);// relative stack: [boxed value] [boxed value] - Label notNull = il.DefineLabel(); - Label? allDone = dbType == DbType.String ? il.DefineLabel() : (Label?)null; - il.Emit(OpCodes.Brtrue_S, notNull); - // relative stack [boxed value = null] - il.Emit(OpCodes.Pop); // relative stack empty - il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value")); // relative stack [DBNull] - if (dbType == DbType.String) - { - EmitInt32(il, 0); - il.Emit(OpCodes.Stloc_1); - } - if (allDone != null) il.Emit(OpCodes.Br_S, allDone.Value); - il.MarkLabel(notNull); - if (prop.PropertyType == typeof(string)) - { - il.Emit(OpCodes.Dup); // [string] [string] - il.EmitCall(OpCodes.Callvirt, typeof(string).GetProperty("Length").GetGetMethod(), null); // [string] [length] - EmitInt32(il, 4000); // [string] [length] [4000] - il.Emit(OpCodes.Cgt); // [string] [0 or 1] - Label isLong = il.DefineLabel(), lenDone = il.DefineLabel(); - il.Emit(OpCodes.Brtrue_S, isLong); - EmitInt32(il, 4000); // [string] [4000] - il.Emit(OpCodes.Br_S, lenDone); - il.MarkLabel(isLong); - EmitInt32(il, -1); // [string] [-1] - il.MarkLabel(lenDone); - il.Emit(OpCodes.Stloc_1); // [string] - } - if (prop.PropertyType.FullName == LinqBinary) - { - il.EmitCall(OpCodes.Callvirt, prop.PropertyType.GetMethod("ToArray", BindingFlags.Public | BindingFlags.Instance), null); - } - if (allDone != null) il.MarkLabel(allDone.Value); - // relative stack [boxed value or DBNull] - } - il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("Value").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] - - if (prop.PropertyType == typeof(string)) - { - var endOfSize = il.DefineLabel(); - // don't set if 0 - il.Emit(OpCodes.Ldloc_1); // [parameters] [parameters] [parameter] [size] - il.Emit(OpCodes.Brfalse_S, endOfSize); // [parameters] [parameters] [parameter] - - il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] - il.Emit(OpCodes.Ldloc_1); // stack is now [parameters] [parameters] [parameter] [parameter] [size] - il.EmitCall(OpCodes.Callvirt, typeof(IDbDataParameter).GetProperty("Size").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] - - il.MarkLabel(endOfSize); - } - - il.EmitCall(OpCodes.Callvirt, typeof(IList).GetMethod("Add"), null); // stack is now [parameters] - il.Emit(OpCodes.Pop); // IList.Add returns the new index (int); we don't care - } - // stack is currently [command] - il.Emit(OpCodes.Pop); // stack is now empty - il.Emit(OpCodes.Ret); - return (Action)dm.CreateDelegate(typeof(Action)); - } - - private static IDbCommand SetupCommand(IDbConnection cnn, IDbTransaction transaction, string sql, Action paramReader, object obj, int? commandTimeout, CommandType? commandType) - { - var cmd = cnn.CreateCommand(); - var bindByName = GetBindByName(cmd.GetType()); - if (bindByName != null) bindByName(cmd, true); - cmd.Transaction = transaction; - cmd.CommandText = sql; - if (commandTimeout.HasValue) - cmd.CommandTimeout = commandTimeout.Value; - if (commandType.HasValue) - cmd.CommandType = commandType.Value; - if (paramReader != null) - { - paramReader(cmd, obj); - } - return cmd; - } - - - private static int ExecuteCommand(IDbConnection cnn, IDbTransaction transaction, string sql, Action paramReader, object obj, int? commandTimeout, CommandType? commandType) - { - using (var cmd = SetupCommand(cnn, transaction, sql, paramReader, obj, commandTimeout, commandType)) - { - return cmd.ExecuteNonQuery(); - } - } - - private static Func GetStructDeserializer(Type type, int index) - { - // no point using special per-type handling here; it boils down to the same, plus not all are supported anyway (see: SqlDataReader.GetChar - not supported!) -#pragma warning disable 618 - if (type == typeof(char)) - { // this *does* need special handling, though - return r => SqlMapper.ReadChar(r.GetValue(index)); - } - if (type == typeof(char?)) - { - return r => SqlMapper.ReadNullableChar(r.GetValue(index)); - } - if (type.FullName == LinqBinary) - { - return r => Activator.CreateInstance(type, r.GetValue(index)); - } -#pragma warning restore 618 - return r => { - var val = r.GetValue(index); - return val is DBNull ? null : val; - }; - } - - static readonly MethodInfo - enumParse = typeof(Enum).GetMethod("Parse", new Type[] { typeof(Type), typeof(string), typeof(bool) }), - getItem = typeof(IDataRecord).GetProperties(BindingFlags.Instance | BindingFlags.Public) - .Where(p => p.GetIndexParameters().Any() && p.GetIndexParameters()[0].ParameterType == typeof(int)) - .Select(p => p.GetGetMethod()).First(); - - class PropInfo - { - public string Name { get; set; } - public MethodInfo Setter { get; set; } - public Type Type { get; set; } - } - - static List GetSettableProps(Type t) - { - return t - .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) - .Select(p => new PropInfo { - Name = p.Name, - Setter = p.DeclaringType == t ? p.GetSetMethod(true) : p.DeclaringType.GetProperty(p.Name).GetSetMethod(true), - Type = p.PropertyType - }) - .Where(info => info.Setter != null) - .ToList(); - } - - static List GetSettableFields(Type t) - { - return t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToList(); - } - - /// - /// Internal use only - /// - /// - /// - /// - /// - /// - /// - public static Func GetTypeDeserializer( -#if CSHARP30 - Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing -#else -Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false -#endif -) - { - var dm = new DynamicMethod(string.Format("Deserialize{0}", Guid.NewGuid()), typeof(object), new[] { typeof(IDataReader) }, true); - - var il = dm.GetILGenerator(); - il.DeclareLocal(typeof(int)); - il.DeclareLocal(type); - bool haveEnumLocal = false; - il.Emit(OpCodes.Ldc_I4_0); - il.Emit(OpCodes.Stloc_0); - var properties = GetSettableProps(type); - var fields = GetSettableFields(type); - if (length == -1) - { - length = reader.FieldCount - startBound; - } - - if (reader.FieldCount <= startBound) - { - throw new ArgumentException("When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id", "splitOn"); - } - - var names = new List(); - - for (int i = startBound; i < startBound + length; i++) - { - names.Add(reader.GetName(i)); - } - - var setters = ( - from n in names - let prop = properties.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.Ordinal)) // property case sensitive first - ?? properties.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.OrdinalIgnoreCase)) // property case insensitive second - let field = prop != null ? null : (fields.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.Ordinal)) // field case sensitive third - ?? fields.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.OrdinalIgnoreCase))) // field case insensitive fourth - select new { Name = n, Property = prop, Field = field } - ).ToList(); - - int index = startBound; - - if (type.IsValueType) - { - il.Emit(OpCodes.Ldloca_S, (byte)1); - il.Emit(OpCodes.Initobj, type); - } - else - { - il.Emit(OpCodes.Newobj, type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); - il.Emit(OpCodes.Stloc_1); - } - il.BeginExceptionBlock(); - if (type.IsValueType) - { - il.Emit(OpCodes.Ldloca_S, (byte)1);// [target] - } - else - { - il.Emit(OpCodes.Ldloc_1);// [target] - } - - // stack is now [target] - - bool first = true; - var allDone = il.DefineLabel(); - foreach (var item in setters) - { - if (item.Property != null || item.Field != null) - { - il.Emit(OpCodes.Dup); // stack is now [target][target] - Label isDbNullLabel = il.DefineLabel(); - Label finishLabel = il.DefineLabel(); - - il.Emit(OpCodes.Ldarg_0); // stack is now [target][target][reader] - EmitInt32(il, index); // stack is now [target][target][reader][index] - il.Emit(OpCodes.Dup);// stack is now [target][target][reader][index][index] - il.Emit(OpCodes.Stloc_0);// stack is now [target][target][reader][index] - il.Emit(OpCodes.Callvirt, getItem); // stack is now [target][target][value-as-object] - - Type memberType = item.Property != null ? item.Property.Type : item.Field.FieldType; - - if (memberType == typeof(char) || memberType == typeof(char?)) - { - il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod( - memberType == typeof(char) ? "ReadChar" : "ReadNullableChar", BindingFlags.Static | BindingFlags.Public), null); // stack is now [target][target][typed-value] - } - else - { - il.Emit(OpCodes.Dup); // stack is now [target][target][value][value] - il.Emit(OpCodes.Isinst, typeof(DBNull)); // stack is now [target][target][value-as-object][DBNull or null] - il.Emit(OpCodes.Brtrue_S, isDbNullLabel); // stack is now [target][target][value-as-object] - - // unbox nullable enums as the primitive, i.e. byte etc - - var nullUnderlyingType = Nullable.GetUnderlyingType(memberType); - var unboxType = nullUnderlyingType != null && nullUnderlyingType.IsEnum ? nullUnderlyingType : memberType; - - if (unboxType.IsEnum) - { - if (!haveEnumLocal) - { - il.DeclareLocal(typeof(string)); - haveEnumLocal = true; - } - - Label isNotString = il.DefineLabel(); - il.Emit(OpCodes.Dup); // stack is now [target][target][value][value] - il.Emit(OpCodes.Isinst, typeof(string)); // stack is now [target][target][value-as-object][string or null] - il.Emit(OpCodes.Dup);// stack is now [target][target][value-as-object][string or null][string or null] - il.Emit(OpCodes.Stloc_2); // stack is now [target][target][value-as-object][string or null] - il.Emit(OpCodes.Brfalse_S, isNotString); // stack is now [target][target][value-as-object] - - il.Emit(OpCodes.Pop); // stack is now [target][target] - - - il.Emit(OpCodes.Ldtoken, unboxType); // stack is now [target][target][enum-type-token] - il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);// stack is now [target][target][enum-type] - il.Emit(OpCodes.Ldloc_2); // stack is now [target][target][enum-type][string] - il.Emit(OpCodes.Ldc_I4_1); // stack is now [target][target][enum-type][string][true] - il.EmitCall(OpCodes.Call, enumParse, null); // stack is now [target][target][enum-as-object] - - il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] - - if (nullUnderlyingType != null) - { - il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType })); - } - if (item.Property != null) - { - il.Emit(OpCodes.Callvirt, item.Property.Setter); // stack is now [target] - } - else - { - il.Emit(OpCodes.Stfld, item.Field); // stack is now [target] - } - il.Emit(OpCodes.Br_S, finishLabel); - - - il.MarkLabel(isNotString); - } - if (memberType.FullName == LinqBinary) - { - il.Emit(OpCodes.Unbox_Any, typeof(byte[])); // stack is now [target][target][byte-array] - il.Emit(OpCodes.Newobj, memberType.GetConstructor(new Type[] { typeof(byte[]) }));// stack is now [target][target][binary] - } - else - { - il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] - } - if (nullUnderlyingType != null && nullUnderlyingType.IsEnum) - { - il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType })); - } - } - if (item.Property != null) - { - if (type.IsValueType) - { - il.Emit(OpCodes.Call, item.Property.Setter); // stack is now [target] - } - else - { - il.Emit(OpCodes.Callvirt, item.Property.Setter); // stack is now [target] - } - } - else - { - il.Emit(OpCodes.Stfld, item.Field); // stack is now [target] - } - - il.Emit(OpCodes.Br_S, finishLabel); // stack is now [target] - - il.MarkLabel(isDbNullLabel); // incoming stack: [target][target][value] - - il.Emit(OpCodes.Pop); // stack is now [target][target] - il.Emit(OpCodes.Pop); // stack is now [target] - - if (first && returnNullIfFirstMissing) - { - il.Emit(OpCodes.Pop); - il.Emit(OpCodes.Ldnull); // stack is now [null] - il.Emit(OpCodes.Stloc_1); - il.Emit(OpCodes.Br, allDone); - } - - il.MarkLabel(finishLabel); - } - first = false; - index += 1; - } - if (type.IsValueType) - { - il.Emit(OpCodes.Pop); - } - else - { - il.Emit(OpCodes.Stloc_1); // stack is empty - } - il.MarkLabel(allDone); - il.BeginCatchBlock(typeof(Exception)); // stack is Exception - il.Emit(OpCodes.Ldloc_0); // stack is Exception, index - il.Emit(OpCodes.Ldarg_0); // stack is Exception, index, reader - il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod("ThrowDataException"), null); - il.EndExceptionBlock(); - - il.Emit(OpCodes.Ldloc_1); // stack is [rval] - if (type.IsValueType) - { - il.Emit(OpCodes.Box, type); - } - il.Emit(OpCodes.Ret); - - return (Func)dm.CreateDelegate(typeof(Func)); - } - - /// - /// Throws a data exception, only used internally - /// - /// - /// - /// - public static void ThrowDataException(Exception ex, int index, IDataReader reader) - { - string name = "(n/a)", value = "(n/a)"; - if (reader != null && index >= 0 && index < reader.FieldCount) - { - name = reader.GetName(index); - object val = reader.GetValue(index); - if (val == null || val is DBNull) - { - value = ""; - } - else - { - value = Convert.ToString(val) + " - " + Type.GetTypeCode(val.GetType()); - } - } - throw new DataException(string.Format("Error parsing column {0} ({1}={2})", index, name, value), ex); - } - private static void EmitInt32(ILGenerator il, int value) - { - switch (value) - { - case -1: il.Emit(OpCodes.Ldc_I4_M1); break; - case 0: il.Emit(OpCodes.Ldc_I4_0); break; - case 1: il.Emit(OpCodes.Ldc_I4_1); break; - case 2: il.Emit(OpCodes.Ldc_I4_2); break; - case 3: il.Emit(OpCodes.Ldc_I4_3); break; - case 4: il.Emit(OpCodes.Ldc_I4_4); break; - case 5: il.Emit(OpCodes.Ldc_I4_5); break; - case 6: il.Emit(OpCodes.Ldc_I4_6); break; - case 7: il.Emit(OpCodes.Ldc_I4_7); break; - case 8: il.Emit(OpCodes.Ldc_I4_8); break; - default: - if (value >= -128 && value <= 127) - { - il.Emit(OpCodes.Ldc_I4_S, (sbyte)value); - } - else - { - il.Emit(OpCodes.Ldc_I4, value); - } - break; - } - } - - /// - /// The grid reader provides interfaces for reading multiple result sets from a Dapper query - /// - public class GridReader : IDisposable - { - private IDataReader reader; - private IDbCommand command; - private Identity identity; - - internal GridReader(IDbCommand command, IDataReader reader, Identity identity) - { - this.command = command; - this.reader = reader; - this.identity = identity; - } - /// - /// Read the next grid of results - /// - public IEnumerable Read() - { - if (reader == null) throw new ObjectDisposedException(GetType().Name); - if (consumed) throw new InvalidOperationException("Each grid can only be iterated once"); - var typedIdentity = identity.ForGrid(typeof(T), gridIndex); - CacheInfo cache = GetCacheInfo(typedIdentity); - var deserializer = cache.Deserializer; - - Func> deserializerGenerator = () => { - deserializer = GetDeserializer(typeof(T), reader, 0, -1, false); - cache.Deserializer = deserializer; - return deserializer; - }; - - if (deserializer == null) - { - deserializer = deserializerGenerator(); - } - consumed = true; - return ReadDeferred(gridIndex, deserializer, typedIdentity, deserializerGenerator); - } - - private IEnumerable MultiReadInternal(object func, string splitOn) - { - - var identity = this.identity.ForGrid(typeof(TReturn), new Type[] { - typeof(TFirst), - typeof(TSecond), - typeof(TThird), - typeof(TFourth), - typeof(TFifth) - }, gridIndex); - try - { - foreach (var r in SqlMapper.MultiMapImpl(null, null, func, null, null, splitOn, null, null, reader, identity)) - { - yield return r; - } - } - finally - { - NextResult(); - } - } - - /// - /// Read multiple objects from a single recordset on the grid - /// - /// - /// - /// - /// - /// - /// -#if CSHARP30 - public IEnumerable Read(Func func, string splitOn) -#else - public IEnumerable Read(Func func, string splitOn = "id") -#endif - { - return MultiReadInternal(func, splitOn); - } - - /// - /// Read multiple objects from a single recordset on the grid - /// - /// - /// - /// - /// - /// - /// - /// -#if CSHARP30 - public IEnumerable Read(Func func, string splitOn) -#else - public IEnumerable Read(Func func, string splitOn = "id") -#endif - { - return MultiReadInternal(func, splitOn); - } - - /// - /// Read multiple objects from a single record set on the grid - /// - /// - /// - /// - /// - /// - /// - /// - /// -#if CSHARP30 - public IEnumerable Read(Func func, string splitOn) -#else - public IEnumerable Read(Func func, string splitOn = "id") -#endif - { - return MultiReadInternal(func, splitOn); - } - -#if !CSHARP30 - /// - /// Read multiple objects from a single record set on the grid - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public IEnumerable Read(Func func, string splitOn = "id") - { - return MultiReadInternal(func, splitOn); - } -#endif - - private IEnumerable ReadDeferred(int index, Func deserializer, Identity typedIdentity, Func> deserializerGenerator) - { - try - { - while (index == gridIndex && reader.Read()) - { - object next; - try - { - next = deserializer(reader); - } - catch (DataException) - { - deserializer = deserializerGenerator(); - next = deserializer(reader); - } - yield return (T)next; - } - } - finally // finally so that First etc progresses things even when multiple rows - { - if (index == gridIndex) - { - NextResult(); - } - } - } - private int gridIndex; - private bool consumed; - private void NextResult() - { - if (reader.NextResult()) - { - gridIndex++; - consumed = false; - } - else - { - Dispose(); - } - - } - /// - /// Dispose the grid, closing and disposing both the underlying reader and command. - /// - public void Dispose() - { - if (reader != null) - { - reader.Dispose(); - reader = null; - } - if (command != null) - { - command.Dispose(); - command = null; - } - } - } - } - - /// - /// A bag of parameters that can be passed to the Dapper Query and Execute methods - /// - public class DynamicParameters : SqlMapper.IDynamicParameters - { - static Dictionary> paramReaderCache = new Dictionary>(); - - Dictionary parameters = new Dictionary(); - List templates; - - class ParamInfo - { - public string Name { get; set; } - public object Value { get; set; } - public ParameterDirection ParameterDirection { get; set; } - public DbType? DbType { get; set; } - public int? Size { get; set; } - public IDbDataParameter AttachedParam { get; set; } - } - - /// - /// construct a dynamic parameter bag - /// - public DynamicParameters() { } - /// - /// construct a dynamic parameter bag - /// - /// can be an anonymous type of a DynamicParameters bag - public DynamicParameters(object template) - { - if (template != null) - { - AddDynamicParams(template); - } - } - - /// - /// Append a whole object full of params to the dynamic - /// EG: AddParams(new {A = 1, B = 2}) // will add property A and B to the dynamic - /// - /// - public void AddDynamicParams( -#if CSHARP30 - object param -#else -dynamic param -#endif -) - { - object obj = param as object; - - if (obj != null) - { - var subDynamic = obj as DynamicParameters; - - if (subDynamic == null) - { - templates = templates ?? new List(); - templates.Add(obj); - } - else - { - if (subDynamic.parameters != null) - { - foreach (var kvp in subDynamic.parameters) - { - parameters.Add(kvp.Key, kvp.Value); - } - } - - if (subDynamic.templates != null) - { - foreach (var t in subDynamic.templates) - { - templates.Add(t); - } - } - } - } - } - - /// - /// Add a parameter to this dynamic parameter list - /// - /// - /// - /// - /// - /// - public void Add( -#if CSHARP30 - string name, object value, DbType? dbType, ParameterDirection? direction, int? size -#else -string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null -#endif -) - { - parameters[Clean(name)] = new ParamInfo() { Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input, DbType = dbType, Size = size }; - } - - static string Clean(string name) - { - if (!string.IsNullOrEmpty(name)) - { - switch (name[0]) - { - case '@': - case ':': - case '?': - return name.Substring(1); - } - } - return name; - } - - void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Identity identity) - { - if (templates != null) - { - foreach (var template in templates) - { - var newIdent = identity.ForDynamicParameters(template.GetType()); - Action appender; - - lock (paramReaderCache) - { - if (!paramReaderCache.TryGetValue(newIdent, out appender)) - { - appender = SqlMapper.CreateParamInfoGenerator(newIdent); - paramReaderCache[newIdent] = appender; - } - } - - appender(command, template); - } - } - - foreach (var param in parameters.Values) - { - string name = Clean(param.Name); - bool add = !command.Parameters.Contains(name); - IDbDataParameter p; - if (add) - { - p = command.CreateParameter(); - p.ParameterName = name; - } - else - { - p = (IDbDataParameter)command.Parameters[name]; - } - var val = param.Value; - p.Value = val ?? DBNull.Value; - p.Direction = param.ParameterDirection; - var s = val as string; - if (s != null) - { - if (s.Length <= 4000) - { - p.Size = 4000; - } - } - if (param.Size != null) - { - p.Size = param.Size.Value; - } - if (param.DbType != null) - { - p.DbType = param.DbType.Value; - } - if (add) - { - command.Parameters.Add(p); - } - param.AttachedParam = p; - } - } - - /// - /// Get the value of a parameter - /// - /// - /// - /// The value, note DBNull.Value is not returned, instead the value is returned as null - public T Get(string name) - { - var val = parameters[Clean(name)].AttachedParam.Value; - if (val == DBNull.Value) - { - if (default(T) != null) - { - throw new ApplicationException("Attempting to cast a DBNull to a non nullable type!"); - } - return default(T); - } - return (T)val; - } - } - - /// - /// This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar - /// - public sealed class DbString - { - /// - /// Create a new DbString - /// - public DbString() { Length = -1; } - /// - /// Ansi vs Unicode - /// - public bool IsAnsi { get; set; } - /// - /// Fixed length - /// - public bool IsFixedLength { get; set; } - /// - /// Length of the string -1 for max - /// - public int Length { get; set; } - /// - /// The value of the string - /// - public string Value { get; set; } - /// - /// Add the parameter to the command... internal use only - /// - /// - /// - public void AddParameter(IDbCommand command, string name) - { - if (IsFixedLength && Length == -1) - { - throw new InvalidOperationException("If specifying IsFixedLength, a Length must also be specified"); - } - var param = command.CreateParameter(); - param.ParameterName = name; - param.Value = (object)Value ?? DBNull.Value; - if (Length == -1 && Value != null && Value.Length <= 4000) - { - param.Size = 4000; - } - else - { - param.Size = Length; - } - param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String); - command.Parameters.Add(param); - } - } - -} diff --git a/src/dapper-dot-net/SqlMapper.csproj b/src/dapper-dot-net/SqlMapper.csproj deleted file mode 100644 index 13390da91..000000000 --- a/src/dapper-dot-net/SqlMapper.csproj +++ /dev/null @@ -1,130 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {A2A80512-11F4-4028-A995-505463632C84} - Exe - Properties - SqlMapper - Smackdown - 512 - v4.5.1 - - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - bin\x86\Signed\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - false - - - - ..\..\lib\ServiceStack.Interfaces.dll - - - - - - - - - - - - - - - - True - True - Model.edmx - - - True - True - DataClasses.dbml - - - - - - - - True - True - Settings.settings - - - - - - - - EntityModelCodeGenerator - Model.Designer.cs - - - MSLinqToSQLGenerator - DataClasses.designer.cs - Designer - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - DataClasses.dbml - - - - - {1887DC99-9139-43E3-A7AA-6D74714B3A5D} - ServiceStack.OrmLite.SqlServer - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - \ No newline at end of file diff --git a/src/dapper-dot-net/SqlMapper.sln b/src/dapper-dot-net/SqlMapper.sln deleted file mode 100644 index 72de0d1d0..000000000 --- a/src/dapper-dot-net/SqlMapper.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlMapper", "SqlMapper.csproj", "{A2A80512-11F4-4028-A995-505463632C84}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A2A80512-11F4-4028-A995-505463632C84}.Debug|x86.ActiveCfg = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Debug|x86.Build.0 = Debug|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Release|x86.ActiveCfg = Release|x86 - {A2A80512-11F4-4028-A995-505463632C84}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/dapper-dot-net/Tests.cs b/src/dapper-dot-net/Tests.cs deleted file mode 100644 index e19a9e171..000000000 --- a/src/dapper-dot-net/Tests.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Data.SqlClient; - -namespace SqlMapper -{ - static class TestAssertions - { - - public static void IsEquals(this T obj, T other) - { - if (!obj.Equals(other)) - { - throw new ApplicationException(string.Format("{0} should be equals to {1}", obj, other)); - } - } - - public static void IsSequenceEqual(this IEnumerable obj, IEnumerable other) - { - if (!obj.SequenceEqual(other)) - { - throw new ApplicationException(string.Format("{0} should be equals to {1}", obj, other)); - } - } - - public static void IsFalse(this bool b) - { - if (b) - { - throw new ApplicationException("Expected false"); - } - } - - public static void IsNull(this object obj) - { - if (obj != null) - { - throw new ApplicationException("Expected null"); - } - } - - } - - class Tests - { - - SqlConnection connection = Program.GetOpenConnection(); - - public void SelectListInt() - { - connection.Query("select 1 union all select 2 union all select 3") - .IsSequenceEqual(new[] { 1, 2, 3 }); - } - - public void PassInIntArray() - { - connection.Query("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 }.AsEnumerable() }) - .IsSequenceEqual(new[] { 1, 2, 3 }); - } - - - public void TestDoubleParam() - { - connection.Query("select @d", new { d = 0.1d }).First() - .IsEquals(0.1d); - } - - public void TestBoolParam() - { - connection.Query("select @b", new { b = false }).First() - .IsFalse(); - } - - public void TestStrings() - { - connection.Query(@"select 'a' a union select 'b'") - .IsSequenceEqual(new[] { "a", "b" }); - } - - public class Dog - { - public int? Age { get; set; } - public Guid Id { get; set; } - public string Name { get; set; } - public float? Weight { get; set; } - - public int IgnoredProperty { get { return 1; } } - } - - public void TestStrongType() - { - var guid = Guid.NewGuid(); - var dog = connection.Query("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid }); - - dog.Count() - .IsEquals(1); - - dog.First().Age - .IsNull(); - - dog.First().Id - .IsEquals(guid); - } - - //public void TestExpando() - //{ - // var rows = connection.Query("select 1 A, 2 B union all select 3, 4"); - - // ((int)rows[0].A) - // .IsEquals(1); - - // ((int)rows[0].B) - // .IsEquals(2); - - // ((int)rows[1].A) - // .IsEquals(3); - - // ((int)rows[1].B) - // .IsEquals(4); - //} - - public void TestStringList() - { - connection.Query("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new[] { "a", "b", "c" } }) - .IsSequenceEqual(new[] {"a","b","c"}); - } - - public void TestExecuteCommand() - { - connection.Execute(@" - set nocount on - create table #t(i int) - set nocount off - insert #t - select @a a union all select @b - set nocount on - drop table #t", new {a=1, b=2 }).IsEquals(2); - } - - public void TestMassiveStrings() - { - var str = new string('X', 20000); - connection.Query("select @a", new { a = str }).First() - .IsEquals(str); - } - - } -} diff --git a/src/dapper-dot-net/app.config b/src/dapper-dot-net/app.config deleted file mode 100644 index f403a216d..000000000 --- a/src/dapper-dot-net/app.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/packages/MySql.Data.6.9.5/CHANGES b/src/packages/MySql.Data.6.9.5/CHANGES deleted file mode 100644 index 7358d4428..000000000 --- a/src/packages/MySql.Data.6.9.5/CHANGES +++ /dev/null @@ -1,46 +0,0 @@ -6.9.5 -- Disabled installation on-demand in Installer (Oracle Bug #19670596). -- Fix for Generated SQL requests column that doesn't exist in LINQ to Entities (MySql bug #72004, Oracle bug #19681348). -- Fix for MySQL Connector/NET generates incorrect SQL for LINQ 'StartsWith' queries (MySql bug #72058, Oracle bug #19680236). -- Fix for Exception when using IEnumerable.Contains(model.property) in Where predicate (MySql bug #73643, Oracle bug #19690370). -- Fix for Generated Sql does not contain ORDER BY statement whose is requested by LINQ (MySql bug #73549, Oracle bug #19698010). -- Fix for Web providers registration in machine.config (removed v20 suffix) (MySQL Bug #74080, Oracle Bug #19715398) -- Fix for Error of "Every derived table must have an alias" in LINQ to Entities when using EF6 + DbFirst + View + Take - (MySql Bug #72148, Oracle bug #19356006). -- Fix for 'the method or operation is not implemented' when using linq with orderby (MySQL Bug #70722, Oracle Bug #19681723). -- Fix for Exception "The given key was not present in the dictionary" when using utf16le charset in a query. (MySql #72737, Oracle Bug #19355906) -- Fix for Memory leak in a loop opening a connection to the database and executing a command (MySql Bug #73122, Oracle Bug #19467233). -- Fix for Multiple issues caused by trailing and leading white space character in params using MySql Membership Provider (MySql Bug #73411, Oracle Bug #19453313) -- Fix for bad assumption leads to modify query adding CALL statement to the beginning of the sql query even when CommandType.Text is specified (MySql Bug #72736, Oracle Bug #19325120). - - -6.9.4 -- Added a new plugin for MySql Fabric 1.5 support - - -6.9.3 -- Fix for Web Parts Personalization provider -- Fix for changing the PK between two int columns (MySql Bug #71418, Oracle bug #18923294). -- Fix for Error when Calling MySqlConnection.GetSchema("PROCEDURES WITH PARAMETERS", ...) (Oracle bug #19285959). -- Fix for EF provider reports ManifestProviderToken = 5.6 for server 5.7 (Oracle bug #19453814). -- Fix for Fluent API DbModelBuilder.HasColumnType is ignored in EF6 (Oracle bug #19456229). -- Fix for Setting a PK GUID identity in Code First in EF6 no longer works in Server 5.7 (Oracle bug #19456452). -- Non PKs declared as Identity GUID have no GUID autogenerated (Oracle bug #19456415). - - -6.9.2 -- Add async/await compatible methods -- Fix for Unable to read geometry column when it has been set with a SRID value. (MySql Bug #71869, Oracle Bug #19137999) -- Fix for Exception adding a new column to an existing model as identity and PK fails when applying the migration (MySql Bug #71418, Oracle bug #18923294). -- Added SiteMap and Personalization configuration web providers to MySql.Web Nuget Package. - - -6.9.1 -- Fix for Exception of "duplicate entry" in MySqlSessionProvider (MySql Bug #70409, Oracle bug #18657550). - - -6.9.0 -- Added implementation of MySQLPersonalizationProvider. -- Added SiteMap Web provider. -- Added Simple Membership Web Provider. -- Fix for open sockets connections left when connection open fails, the error happens when the client try to get a connection when the max number of connections is reached in the server. (MySql #72025, Oracle Bug #18665388). diff --git a/src/packages/MySql.Data.6.9.5/Readme.txt b/src/packages/MySql.Data.6.9.5/Readme.txt deleted file mode 100644 index a1f1be55e..000000000 --- a/src/packages/MySql.Data.6.9.5/Readme.txt +++ /dev/null @@ -1,15 +0,0 @@ -Connector/Net 6.9 Release Notes ------------------------------------- - -Welcome to the release notes for Connector/Net 6.9 - -What's new in 6.9 --------------------- - -- Simple Membership Web Provider -- Site Map Web Provider -- Personalization Web Provider -- MySql Fabric support - - -Be sure and check the documentation for more information on these new features. \ No newline at end of file diff --git a/src/packages/MySql.Data.6.9.5/content/app.config.transform b/src/packages/MySql.Data.6.9.5/content/app.config.transform deleted file mode 100644 index 5fc726c03..000000000 --- a/src/packages/MySql.Data.6.9.5/content/app.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/packages/MySql.Data.6.9.5/content/web.config.transform b/src/packages/MySql.Data.6.9.5/content/web.config.transform deleted file mode 100644 index 5fc726c03..000000000 --- a/src/packages/MySql.Data.6.9.5/content/web.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/packages/MySql.Data.6.9.5/lib/net20-cf/MySql.Data.CF.dll b/src/packages/MySql.Data.6.9.5/lib/net20-cf/MySql.Data.CF.dll deleted file mode 100644 index dc18abf84..000000000 Binary files a/src/packages/MySql.Data.6.9.5/lib/net20-cf/MySql.Data.CF.dll and /dev/null differ diff --git a/src/packages/MySql.Data.6.9.5/lib/net20/MySql.Data.dll b/src/packages/MySql.Data.6.9.5/lib/net20/MySql.Data.dll deleted file mode 100644 index 5534f2b75..000000000 Binary files a/src/packages/MySql.Data.6.9.5/lib/net20/MySql.Data.dll and /dev/null differ diff --git a/src/packages/MySql.Data.6.9.5/lib/net40/MySql.Data.dll b/src/packages/MySql.Data.6.9.5/lib/net40/MySql.Data.dll deleted file mode 100644 index 87317ec63..000000000 Binary files a/src/packages/MySql.Data.6.9.5/lib/net40/MySql.Data.dll and /dev/null differ diff --git a/src/packages/MySql.Data.6.9.5/lib/net45/MySql.Data.dll b/src/packages/MySql.Data.6.9.5/lib/net45/MySql.Data.dll deleted file mode 100644 index 95a2d9bfc..000000000 Binary files a/src/packages/MySql.Data.6.9.5/lib/net45/MySql.Data.dll and /dev/null differ diff --git a/src/packages/NUnit.2.6.3/lib/nunit.framework.dll b/src/packages/NUnit.2.6.3/lib/nunit.framework.dll deleted file mode 100644 index 780727f21..000000000 Binary files a/src/packages/NUnit.2.6.3/lib/nunit.framework.dll and /dev/null differ diff --git a/src/packages/NUnit.2.6.3/lib/nunit.framework.xml b/src/packages/NUnit.2.6.3/lib/nunit.framework.xml deleted file mode 100644 index f40847c7a..000000000 --- a/src/packages/NUnit.2.6.3/lib/nunit.framework.xml +++ /dev/null @@ -1,10960 +0,0 @@ - - - - nunit.framework - - - - - The different targets a test action attribute can be applied to - - - - - Default target, which is determined by where the action attribute is attached - - - - - Target a individual test case - - - - - Target a suite of test cases - - - - - Delegate used by tests that execute code and - capture any thrown exception. - - - - - The Assert class contains a collection of static methods that - implement the most common assertions used in NUnit. - - - - - We don't actually want any instances of this object, but some people - like to inherit from it to add other static methods. Hence, the - protected constructor disallows any instances of this object. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Throws a with the message and arguments - that are passed in. This allows a test to be cut short, with a result - of success returned to NUnit. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws a with the message and arguments - that are passed in. This allows a test to be cut short, with a result - of success returned to NUnit. - - The message to initialize the with. - - - - Throws a with the message and arguments - that are passed in. This allows a test to be cut short, with a result - of success returned to NUnit. - - - - - Throws an with the message and arguments - that are passed in. This is used by the other Assert functions. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws an with the message that is - passed in. This is used by the other Assert functions. - - The message to initialize the with. - - - - Throws an . - This is used by the other Assert functions. - - - - - Throws an with the message and arguments - that are passed in. This causes the test to be reported as ignored. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws an with the message that is - passed in. This causes the test to be reported as ignored. - - The message to initialize the with. - - - - Throws an . - This causes the test to be reported as ignored. - - - - - Throws an with the message and arguments - that are passed in. This causes the test to be reported as inconclusive. - - The message to initialize the with. - Arguments to be used in formatting the message - - - - Throws an with the message that is - passed in. This causes the test to be reported as inconclusive. - - The message to initialize the with. - - - - Throws an . - This causes the test to be reported as Inconclusive. - - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - The message that will be displayed on failure - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that the code represented by a delegate throws an exception - that satisfies the constraint provided. - - A TestDelegate to be executed - A ThrowsConstraint used in the test - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - Used as a synonym for That in rare cases where a private setter - causes a Visual Basic compilation error. - - The actual value to test - A Constraint to be applied - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - Used as a synonym for That in rare cases where a private setter - causes a Visual Basic compilation error. - - The actual value to test - A Constraint to be applied - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - Used as a synonym for That in rare cases where a private setter - causes a Visual Basic compilation error. - - - This method is provided for use by VB developers needing to test - the value of properties with private setters. - - The actual value to test - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - A constraint to be satisfied by the exception - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - A constraint to be satisfied by the exception - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws a particular exception when called. - - A constraint to be satisfied by the exception - A TestDelegate - - - - Verifies that a delegate throws a particular exception when called. - - The exception Type expected - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - The exception Type expected - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws a particular exception when called. - - The exception Type expected - A TestDelegate - - - - Verifies that a delegate throws a particular exception when called. - - Type of the expected exception - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws a particular exception when called. - - Type of the expected exception - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws a particular exception when called. - - Type of the expected exception - A TestDelegate - - - - Verifies that a delegate throws an exception when called - and returns it. - - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws an exception when called - and returns it. - - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws an exception when called - and returns it. - - A TestDelegate - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate throws an exception of a certain Type - or one derived from it when called and returns it. - - The expected Exception Type - A TestDelegate - - - - Verifies that a delegate does not throw an exception - - A TestDelegate - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Verifies that a delegate does not throw an exception. - - A TestDelegate - The message that will be displayed on failure - - - - Verifies that a delegate does not throw an exception. - - A TestDelegate - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - The message to display in case of failure - - - - Asserts that a condition is false. If the condition is true the method throws - an . - - The evaluated condition - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is not equal to null - If the object is null then an - is thrown. - - The object that is to be tested - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - The message to display in case of failure - - - - Verifies that the object that is passed in is equal to null - If the object is not null then an - is thrown. - - The object that is to be tested - - - - Verifies that two ints are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two ints are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two ints are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two longs are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two longs are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two longs are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two unsigned ints are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two unsigned ints are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two unsigned ints are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two unsigned longs are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two unsigned longs are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two unsigned longs are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two decimals are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two decimals are equal. If they are not, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two decimals are equal. If they are not, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - - - - Verifies that two doubles are equal considering a delta. If the - expected value is infinity then the delta value is ignored. If - they are not equal then an is - thrown. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - - - - Verifies that two objects are equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are not equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two objects are equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are not equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - - - - Verifies that two objects are equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are not equal an is thrown. - - The value that is expected - The actual value - - - - Verifies that two ints are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two ints are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two ints are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two longs are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two longs are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two longs are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two unsigned ints are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two unsigned ints are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two unsigned ints are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two unsigned longs are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two unsigned longs are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two unsigned longs are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two decimals are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two decimals are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two decimals are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two floats are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two floats are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two floats are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two doubles are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two doubles are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - The message to display in case of failure - - - - Verifies that two doubles are not equal. If they are equal, then an - is thrown. - - The expected value - The actual value - - - - Verifies that two objects are not equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that two objects are not equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are equal an is thrown. - - The value that is expected - The actual value - The message to display in case of failure - - - - Verifies that two objects are not equal. Two objects are considered - equal if both are null, or if both have the same value. NUnit - has special semantics for some object types. - If they are equal an is thrown. - - The value that is expected - The actual value - - - - Asserts that two objects refer to the same object. If they - are not the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that two objects refer to the same object. If they - are not the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - - - - Asserts that two objects refer to the same object. If they - are not the same an is thrown. - - The expected object - The actual object - - - - Asserts that two objects do not refer to the same object. If they - are the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that two objects do not refer to the same object. If they - are the same an is thrown. - - The expected object - The actual object - The message to display in case of failure - - - - Asserts that two objects do not refer to the same object. If they - are the same an is thrown. - - The expected object - The actual object - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - The message to display in case of failure - - - - Verifies that the double that is passed in is an NaN value. - If the object is not NaN then an - is thrown. - - The value that is to be tested - - - - Assert that a string is empty - that is equal to string.Empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is empty - that is equal to string.Empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is empty - that is equal to string.Empty - - The string to be tested - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing ICollection - - - - Assert that a string is not empty - that is not equal to string.Empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is not empty - that is not equal to string.Empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is not empty - that is not equal to string.Empty - - The string to be tested - - - - Assert that an array, list or other collection is not empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that an array, list or other collection is not empty - - An array, list or other collection implementing ICollection - The message to display in case of failure - - - - Assert that an array, list or other collection is not empty - - An array, list or other collection implementing ICollection - - - - Assert that a string is either null or equal to string.Empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is either null or equal to string.Empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is either null or equal to string.Empty - - The string to be tested - - - - Assert that a string is not null or empty - - The string to be tested - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Assert that a string is not null or empty - - The string to be tested - The message to display in case of failure - - - - Assert that a string is not null or empty - - The string to be tested - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - The message to display in case of failure - - - - Asserts that an object may not be assigned a value of a given Type. - - The expected Type. - The object under examination - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - The message to display in case of failure - - - - Asserts that an object is not an instance of a given type. - - The expected Type - The object being examined - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than the second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - The message to display in case of failure - - - - Verifies that the first value is greater than or equal tothe second - value. If it is not, then an - is thrown. - - The first value, expected to be greater - The second value, expected to be less - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - The message to display in case of failure - - - - Verifies that the first value is less than or equal to the second - value. If it is not, then an - is thrown. - - The first value, expected to be less - The second value, expected to be greater - - - - Asserts that an object is contained in a list. - - The expected object - The list to be examined - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Asserts that an object is contained in a list. - - The expected object - The list to be examined - The message to display in case of failure - - - - Asserts that an object is contained in a list. - - The expected object - The list to be examined - - - - Helper for Assert.AreEqual(double expected, double actual, ...) - allowing code generation to work consistently. - - The expected value - The actual value - The maximum acceptable difference between the - the expected and the actual - The message to display in case of failure - Array of objects to be used in formatting the message - - - - Gets the number of assertions executed so far and - resets the counter to zero. - - - - - AssertionHelper is an optional base class for user tests, - allowing the use of shorter names for constraints and - asserts and avoiding conflict with the definition of - , from which it inherits much of its - behavior, in certain mock object frameworks. - - - - - Helper class with properties and methods that supply - a number of constraints used in Asserts. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding only if a specified number of them succeed. - - - - - Returns a new PropertyConstraintExpression, which will either - test for the existence of the named property on the object - being tested or apply any following constraint to that property. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a constraint that tests two items for equality - - - - - Returns a constraint that tests that two references are the same object - - - - - Returns a constraint that tests whether the - actual value is greater than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a collection containing the same elements as the - collection supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a subset of the collection supplied as an argument. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new ContainsConstraint. This constraint - will, in turn, make use of the appropriate second-level - constraint, depending on the type of the actual argument. - This overload is only used if the item sought is a string, - since any other type implies that we are looking for a - collection member. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the regular expression supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the regular expression supplied as an argument. - - - - - Returns a constraint that fails if the actual - value matches the pattern supplied as an argument. - - - - - Returns a constraint that tests whether the path provided - is the same as an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the actual value falls - within a specified range. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if at least one of them succeeds. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them fail. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Length property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Count property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Message property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the InnerException property of the object being tested. - - - - - Returns a constraint that tests for null - - - - - Returns a constraint that tests for True - - - - - Returns a constraint that tests for False - - - - - Returns a constraint that tests for a positive value - - - - - Returns a constraint that tests for a negative value - - - - - Returns a constraint that tests for NaN - - - - - Returns a constraint that tests for empty - - - - - Returns a constraint that tests whether a collection - contains all unique items. - - - - - Returns a constraint that tests whether an object graph is serializable in binary format. - - - - - Returns a constraint that tests whether an object graph is serializable in xml format. - - - - - Returns a constraint that tests whether a collection is ordered - - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. Works - identically to Assert.That. - - The actual value to test - A Constraint to be applied - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. Works - identically to Assert.That. - - The actual value to test - A Constraint to be applied - The message to be displayed in case of failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. Works - identically to Assert.That. - - The actual value to test - A Constraint to be applied - The message to be displayed in case of failure - Arguments to use in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . Works Identically to - . - - The evaluated condition - The message to display if the condition is false - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . Works Identically to - . - - The evaluated condition - The message to display if the condition is false - - - - Asserts that a condition is true. If the condition is false the method throws - an . Works Identically to . - - The evaluated condition - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - The message that will be displayed on failure - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an assertion exception on failure. - - The actual value to test - A Constraint to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that the code represented by a delegate throws an exception - that satisfies the constraint provided. - - A TestDelegate to be executed - A ThrowsConstraint used in the test - - - - Returns a ListMapper based on a collection. - - The original collection - - - - - Provides static methods to express the assumptions - that must be met for a test to give a meaningful - result. If an assumption is not met, the test - should produce an inconclusive result. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - Arguments to be used in formatting the message - - - - Asserts that a condition is true. If the condition is false the method throws - an . - - The evaluated condition - The message to display if the condition is false - - - - Asserts that a condition is true. If the condition is false the - method throws an . - - The evaluated condition - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - An ActualValueDelegate returning the value to be tested - The message that will be displayed on failure - - - - Apply a constraint to an actual value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - An ActualValueDelegate returning the value to be tested - A Constraint expression to be applied - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - - - - Apply a constraint to a referenced value, succeeding if the constraint - is satisfied and throwing an InconclusiveException on failure. - - A Constraint expression to be applied - The actual value to test - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that the code represented by a delegate throws an exception - that satisfies the constraint provided. - - A TestDelegate to be executed - A ThrowsConstraint used in the test - - - - Waits for pending asynchronous operations to complete, if appropriate, - and returns a proper result of the invocation by unwrapping task results - - The raw result of the method invocation - The unwrapped result, if necessary - - - - A set of Assert methods operationg on one or more collections - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Asserts that all items contained in collection are of the type specified by expectedType. - - IEnumerable containing objects to be considered - System.Type that all objects in collection must be instances of - - - - Asserts that all items contained in collection are of the type specified by expectedType. - - IEnumerable containing objects to be considered - System.Type that all objects in collection must be instances of - The message that will be displayed on failure - - - - Asserts that all items contained in collection are of the type specified by expectedType. - - IEnumerable containing objects to be considered - System.Type that all objects in collection must be instances of - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that all items contained in collection are not equal to null. - - IEnumerable containing objects to be considered - - - - Asserts that all items contained in collection are not equal to null. - - IEnumerable containing objects to be considered - The message that will be displayed on failure - - - - Asserts that all items contained in collection are not equal to null. - - IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Ensures that every object contained in collection exists within the collection - once and only once. - - IEnumerable of objects to be considered - - - - Ensures that every object contained in collection exists within the collection - once and only once. - - IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Ensures that every object contained in collection exists within the collection - once and only once. - - IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are exactly equal. The collections must have the same count, - and contain the exact same objects in the same order. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are not exactly equal. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are not exactly equal. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - - - - Asserts that expected and actual are not exactly equal. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are not exactly equal. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - - - - Asserts that expected and actual are not exactly equal. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are not exactly equal. - If comparer is not null then it will be used to compare the objects. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The IComparer to use in comparing objects from each IEnumerable - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that expected and actual are not equivalent. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - - - - Asserts that expected and actual are not equivalent. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - - - - Asserts that expected and actual are not equivalent. - - The first IEnumerable of objects to be considered - The second IEnumerable of objects to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that collection contains actual as an item. - - IEnumerable of objects to be considered - Object to be found within collection - - - - Asserts that collection contains actual as an item. - - IEnumerable of objects to be considered - Object to be found within collection - The message that will be displayed on failure - - - - Asserts that collection contains actual as an item. - - IEnumerable of objects to be considered - Object to be found within collection - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that collection does not contain actual as an item. - - IEnumerable of objects to be considered - Object that cannot exist within collection - - - - Asserts that collection does not contain actual as an item. - - IEnumerable of objects to be considered - Object that cannot exist within collection - The message that will be displayed on failure - - - - Asserts that collection does not contain actual as an item. - - IEnumerable of objects to be considered - Object that cannot exist within collection - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that superset is not a subject of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - - - - Asserts that superset is not a subject of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - - - - Asserts that superset is not a subject of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Asserts that superset is a subset of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - - - - Asserts that superset is a subset of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - - - - Asserts that superset is a subset of subset. - - The IEnumerable superset to be considered - The IEnumerable subset to be considered - The message that will be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - - - - Assert that an array,list or other collection is empty - - An array, list or other collection implementing IEnumerable - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is empty - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - - - - Assert that an array,list or other collection is empty - - An array, list or other collection implementing IEnumerable - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - The message to be displayed on failure - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - A custom comparer to perform the comparisons - The message to be displayed on failure - Arguments to be used in formatting the message - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - A custom comparer to perform the comparisons - The message to be displayed on failure - - - - Assert that an array, list or other collection is ordered - - An array, list or other collection implementing IEnumerable - A custom comparer to perform the comparisons - - - - Helper class with properties and methods that supply - a number of constraints used in Asserts. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Summary description for DirectoryAssert - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - We don't actually want any instances of this object, but some people - like to inherit from it to add other static methods. Hence, the - protected constructor disallows any instances of this object. - - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are not equal - - - - Verifies that two directories are equal. Two directories are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - The message to display if directories are not equal - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory containing the value that is expected - A directory containing the actual value - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are equal - Arguments to be used in formatting the message - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - The message to display if directories are equal - - - - Asserts that two directories are not equal. If they are equal - an is thrown. - - A directory path string containing the value that is expected - A directory path string containing the actual value - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is empty. If it is not empty - an is thrown. - - A directory to search - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - Arguments to be used in formatting the message - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - The message to display if directories are not equal - - - - Asserts that the directory is not empty. If it is empty - an is thrown. - - A directory to search - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path contains actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - Arguments to be used in formatting the message - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - The message to display if directory is not within the path - - - - Asserts that path does not contain actual as a subdirectory or - an is thrown. - - A directory to search - sub-directory asserted to exist under directory - - - - Summary description for FileAssert. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - We don't actually want any instances of this object, but some people - like to inherit from it to add other static methods. Hence, the - protected constructor disallows any instances of this object. - - - - - Verifies that two Streams are equal. Two Streams are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The expected Stream - The actual Stream - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Verifies that two Streams are equal. Two Streams are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The expected Stream - The actual Stream - The message to display if objects are not equal - - - - Verifies that two Streams are equal. Two Streams are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The expected Stream - The actual Stream - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if objects are not equal - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - A file containing the value that is expected - A file containing the actual value - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if objects are not equal - - - - Verifies that two files are equal. Two files are considered - equal if both are null, or if both have the same value byte for byte. - If they are not equal an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - - - - Asserts that two Streams are not equal. If they are equal - an is thrown. - - The expected Stream - The actual Stream - The message to be displayed when the two Stream are the same. - Arguments to be used in formatting the message - - - - Asserts that two Streams are not equal. If they are equal - an is thrown. - - The expected Stream - The actual Stream - The message to be displayed when the Streams are the same. - - - - Asserts that two Streams are not equal. If they are equal - an is thrown. - - The expected Stream - The actual Stream - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - A file containing the value that is expected - A file containing the actual value - The message to display if objects are not equal - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - A file containing the value that is expected - A file containing the actual value - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if Streams are not equal - Arguments to be used in formatting the message - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - The message to display if objects are not equal - - - - Asserts that two files are not equal. If they are equal - an is thrown. - - The path to a file containing the value that is expected - The path to a file containing the actual value - - - - GlobalSettings is a place for setting default values used - by the framework in performing asserts. - - - - - Default tolerance for floating point equality - - - - - Class used to guard against unexpected argument values - by throwing an appropriate exception. - - - - - Throws an exception if an argument is null - - The value to be tested - The name of the argument - - - - Throws an exception if a string argument is null or empty - - The value to be tested - The name of the argument - - - - Helper class with properties and methods that supply - a number of constraints used in Asserts. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding only if a specified number of them succeed. - - - - - Returns a new PropertyConstraintExpression, which will either - test for the existence of the named property on the object - being tested or apply any following constraint to that property. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if at least one of them succeeds. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them fail. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Length property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Count property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Message property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the InnerException property of the object being tested. - - - - - Interface implemented by a user fixture in order to - validate any expected exceptions. It is only called - for test methods marked with the ExpectedException - attribute. - - - - - Method to handle an expected exception - - The exception to be handled - - - - Helper class with properties and methods that supply - a number of constraints used in Asserts. - - - - - Returns a constraint that tests two items for equality - - - - - Returns a constraint that tests that two references are the same object - - - - - Returns a constraint that tests whether the - actual value is greater than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a collection containing the same elements as the - collection supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a subset of the collection supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the regular expression supplied as an argument. - - - - - Returns a constraint that tests whether the path provided - is the same as an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the actual value falls - within a specified range. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a constraint that tests for null - - - - - Returns a constraint that tests for True - - - - - Returns a constraint that tests for False - - - - - Returns a constraint that tests for a positive value - - - - - Returns a constraint that tests for a negative value - - - - - Returns a constraint that tests for NaN - - - - - Returns a constraint that tests for empty - - - - - Returns a constraint that tests whether a collection - contains all unique items. - - - - - Returns a constraint that tests whether an object graph is serializable in binary format. - - - - - Returns a constraint that tests whether an object graph is serializable in xml format. - - - - - Returns a constraint that tests whether a collection is ordered - - - - - The ITestCaseData interface is implemented by a class - that is able to return complete testcases for use by - a parameterized test method. - - NOTE: This interface is used in both the framework - and the core, even though that results in two different - types. However, sharing the source code guarantees that - the various implementations will be compatible and that - the core is able to reflect successfully over the - framework implementations of ITestCaseData. - - - - - Gets the argument list to be provided to the test - - - - - Gets the expected result - - - - - Indicates whether a result has been specified. - This is necessary because the result may be - null, so it's value cannot be checked. - - - - - Gets the expected exception Type - - - - - Gets the FullName of the expected exception - - - - - Gets the name to be used for the test - - - - - Gets the description of the test - - - - - Gets a value indicating whether this is ignored. - - true if ignored; otherwise, false. - - - - Gets a value indicating whether this is explicit. - - true if explicit; otherwise, false. - - - - Gets the ignore reason. - - The ignore reason. - - - - The Iz class is a synonym for Is intended for use in VB, - which regards Is as a keyword. - - - - - The List class is a helper class with properties and methods - that supply a number of constraints used with lists and collections. - - - - - List.Map returns a ListMapper, which can be used to map - the original collection to another collection. - - - - - - - ListMapper is used to transform a collection used as an actual argument - producing another collection to be used in the assertion. - - - - - Construct a ListMapper based on a collection - - The collection to be transformed - - - - Produces a collection containing all the values of a property - - The collection of property values - - - - - Randomizer returns a set of random values in a repeatable - way, to allow re-running of tests if necessary. - - - - - Get a randomizer for a particular member, returning - one that has already been created if it exists. - This ensures that the same values are generated - each time the tests are reloaded. - - - - - Get a randomizer for a particular parameter, returning - one that has already been created if it exists. - This ensures that the same values are generated - each time the tests are reloaded. - - - - - Construct a randomizer using a random seed - - - - - Construct a randomizer using a specified seed - - - - - Return an array of random doubles between 0.0 and 1.0. - - - - - - - Return an array of random doubles with values in a specified range. - - - - - Return an array of random ints with values in a specified range. - - - - - Get a random seed for use in creating a randomizer. - - - - - The SpecialValue enum is used to represent TestCase arguments - that cannot be used as arguments to an Attribute. - - - - - Null represents a null value, which cannot be used as an - argument to an attribute under .NET 1.x - - - - - Basic Asserts on strings. - - - - - The Equals method throws an AssertionException. This is done - to make sure there is no mistake by calling this function. - - - - - - - override the default ReferenceEquals to throw an AssertionException. This - implementation makes sure there is no mistake in calling this function - as part of Assert. - - - - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - - - - Asserts that a string is not found within another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string is found within another string. - - The expected string - The string to be examined - - - - Asserts that a string starts with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string starts with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string starts with another string. - - The expected string - The string to be examined - - - - Asserts that a string does not start with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string does not start with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string does not start with another string. - - The expected string - The string to be examined - - - - Asserts that a string ends with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string ends with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string ends with another string. - - The expected string - The string to be examined - - - - Asserts that a string does not end with another string. - - The expected string - The string to be examined - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string does not end with another string. - - The expected string - The string to be examined - The message to display in case of failure - - - - Asserts that a string does not end with another string. - - The expected string - The string to be examined - - - - Asserts that two strings are equal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that two strings are equal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - - - - Asserts that two strings are equal, without regard to case. - - The expected string - The actual string - - - - Asserts that two strings are not equal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that two strings are Notequal, without regard to case. - - The expected string - The actual string - The message to display in case of failure - - - - Asserts that two strings are not equal, without regard to case. - - The expected string - The actual string - - - - Asserts that a string matches an expected regular expression pattern. - - The regex pattern to be matched - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string matches an expected regular expression pattern. - - The regex pattern to be matched - The actual string - The message to display in case of failure - - - - Asserts that a string matches an expected regular expression pattern. - - The regex pattern to be matched - The actual string - - - - Asserts that a string does not match an expected regular expression pattern. - - The regex pattern to be used - The actual string - The message to display in case of failure - Arguments used in formatting the message - - - - Asserts that a string does not match an expected regular expression pattern. - - The regex pattern to be used - The actual string - The message to display in case of failure - - - - Asserts that a string does not match an expected regular expression pattern. - - The regex pattern to be used - The actual string - - - - The TestCaseData class represents a set of arguments - and other parameter info to be used for a parameterized - test case. It provides a number of instance modifiers - for use in initializing the test case. - - Note: Instance modifiers are getters that return - the same instance after modifying it's state. - - - - - The argument list to be provided to the test - - - - - The expected result to be returned - - - - - Set to true if this has an expected result - - - - - The expected exception Type - - - - - The FullName of the expected exception - - - - - The name to be used for the test - - - - - The description of the test - - - - - A dictionary of properties, used to add information - to tests without requiring the class to change. - - - - - If true, indicates that the test case is to be ignored - - - - - If true, indicates that the test case is marked explicit - - - - - The reason for ignoring a test case - - - - - Initializes a new instance of the class. - - The arguments. - - - - Initializes a new instance of the class. - - The argument. - - - - Initializes a new instance of the class. - - The first argument. - The second argument. - - - - Initializes a new instance of the class. - - The first argument. - The second argument. - The third argument. - - - - Sets the expected result for the test - - The expected result - A modified TestCaseData - - - - Sets the expected exception type for the test - - Type of the expected exception. - The modified TestCaseData instance - - - - Sets the expected exception type for the test - - FullName of the expected exception. - The modified TestCaseData instance - - - - Sets the name of the test case - - The modified TestCaseData instance - - - - Sets the description for the test case - being constructed. - - The description. - The modified TestCaseData instance. - - - - Applies a category to the test - - - - - - - Applies a named property to the test - - - - - - - - Applies a named property to the test - - - - - - - - Applies a named property to the test - - - - - - - - Ignores this TestCase. - - - - - - Ignores this TestCase, specifying the reason. - - The reason. - - - - - Marks this TestCase as Explicit - - - - - - Marks this TestCase as Explicit, specifying the reason. - - The reason. - - - - - Gets the argument list to be provided to the test - - - - - Gets the expected result - - - - - Returns true if the result has been set - - - - - Gets the expected exception Type - - - - - Gets the FullName of the expected exception - - - - - Gets the name to be used for the test - - - - - Gets the description of the test - - - - - Gets a value indicating whether this is ignored. - - true if ignored; otherwise, false. - - - - Gets a value indicating whether this is explicit. - - true if explicit; otherwise, false. - - - - Gets the ignore reason. - - The ignore reason. - - - - Gets a list of categories associated with this test. - - - - - Gets the property dictionary for this test - - - - - Provide the context information of the current test - - - - - Constructs a TestContext using the provided context dictionary - - A context dictionary - - - - Get the current test context. This is created - as needed. The user may save the context for - use within a test, but it should not be used - outside the test for which it is created. - - - - - Gets a TestAdapter representing the currently executing test in this context. - - - - - Gets a ResultAdapter representing the current result for the test - executing in this context. - - - - - Gets the directory containing the current test assembly. - - - - - Gets the directory to be used for outputing files created - by this test run. - - - - - TestAdapter adapts a Test for consumption by - the user test code. - - - - - Constructs a TestAdapter for this context - - The context dictionary - - - - The name of the test. - - - - - The FullName of the test - - - - - The properties of the test. - - - - - ResultAdapter adapts a TestResult for consumption by - the user test code. - - - - - Construct a ResultAdapter for a context - - The context holding the result - - - - The TestState of current test. This maps to the ResultState - used in nunit.core and is subject to change in the future. - - - - - The TestStatus of current test. This enum will be used - in future versions of NUnit and so is to be preferred - to the TestState value. - - - - - Provides details about a test - - - - - Creates an instance of TestDetails - - The fixture that the test is a member of, if available. - The method that implements the test, if available. - The full name of the test. - A string representing the type of test, e.g. "Test Case". - Indicates if the test represents a suite of tests. - - - - The fixture that the test is a member of, if available. - - - - - The method that implements the test, if available. - - - - - The full name of the test. - - - - - A string representing the type of test, e.g. "Test Case". - - - - - Indicates if the test represents a suite of tests. - - - - - The ResultState enum indicates the result of running a test - - - - - The result is inconclusive - - - - - The test was not runnable. - - - - - The test has been skipped. - - - - - The test has been ignored. - - - - - The test succeeded - - - - - The test failed - - - - - The test encountered an unexpected exception - - - - - The test was cancelled by the user - - - - - The TestStatus enum indicates the result of running a test - - - - - The test was inconclusive - - - - - The test has skipped - - - - - The test succeeded - - - - - The test failed - - - - - Helper class with static methods used to supply constraints - that operate on strings. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that fails if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the Regex pattern supplied as an argument. - - - - - Returns a constraint that fails if the actual - value matches the pattern supplied as an argument. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - TextMessageWriter writes constraint descriptions and messages - in displayable form as a text stream. It tailors the display - of individual message components to form the standard message - format of NUnit assertion failure messages. - - - - - MessageWriter is the abstract base for classes that write - constraint descriptions and messages in some form. The - class has separate methods for writing various components - of a message, allowing implementations to tailor the - presentation as needed. - - - - - Construct a MessageWriter given a culture - - - - - Method to write single line message with optional args, usually - written to precede the general failure message. - - The message to be written - Any arguments used in formatting the message - - - - Method to write single line message with optional args, usually - written to precede the general failure message, at a givel - indentation level. - - The indentation level of the message - The message to be written - Any arguments used in formatting the message - - - - Display Expected and Actual lines for a constraint. This - is called by MessageWriter's default implementation of - WriteMessageTo and provides the generic two-line display. - - The constraint that failed - - - - Display Expected and Actual lines for given values. This - method may be called by constraints that need more control over - the display of actual and expected values than is provided - by the default implementation. - - The expected value - The actual value causing the failure - - - - Display Expected and Actual lines for given values, including - a tolerance value on the Expected line. - - The expected value - The actual value causing the failure - The tolerance within which the test was made - - - - Display the expected and actual string values on separate lines. - If the mismatch parameter is >=0, an additional line is displayed - line containing a caret that points to the mismatch point. - - The expected string value - The actual string value - The point at which the strings don't match or -1 - If true, case is ignored in locating the point where the strings differ - If true, the strings should be clipped to fit the line - - - - Writes the text for a connector. - - The connector. - - - - Writes the text for a predicate. - - The predicate. - - - - Writes the text for an expected value. - - The expected value. - - - - Writes the text for a modifier - - The modifier. - - - - Writes the text for an actual value. - - The actual value. - - - - Writes the text for a generalized value. - - The value. - - - - Writes the text for a collection value, - starting at a particular point, to a max length - - The collection containing elements to write. - The starting point of the elements to write - The maximum number of elements to write - - - - Abstract method to get the max line length - - - - - Prefix used for the expected value line of a message - - - - - Prefix used for the actual value line of a message - - - - - Length of a message prefix - - - - - Construct a TextMessageWriter - - - - - Construct a TextMessageWriter, specifying a user message - and optional formatting arguments. - - - - - - - Method to write single line message with optional args, usually - written to precede the general failure message, at a givel - indentation level. - - The indentation level of the message - The message to be written - Any arguments used in formatting the message - - - - Display Expected and Actual lines for a constraint. This - is called by MessageWriter's default implementation of - WriteMessageTo and provides the generic two-line display. - - The constraint that failed - - - - Display Expected and Actual lines for given values. This - method may be called by constraints that need more control over - the display of actual and expected values than is provided - by the default implementation. - - The expected value - The actual value causing the failure - - - - Display Expected and Actual lines for given values, including - a tolerance value on the expected line. - - The expected value - The actual value causing the failure - The tolerance within which the test was made - - - - Display the expected and actual string values on separate lines. - If the mismatch parameter is >=0, an additional line is displayed - line containing a caret that points to the mismatch point. - - The expected string value - The actual string value - The point at which the strings don't match or -1 - If true, case is ignored in string comparisons - If true, clip the strings to fit the max line length - - - - Writes the text for a connector. - - The connector. - - - - Writes the text for a predicate. - - The predicate. - - - - Write the text for a modifier. - - The modifier. - - - - Writes the text for an expected value. - - The expected value. - - - - Writes the text for an actual value. - - The actual value. - - - - Writes the text for a generalized value. - - The value. - - - - Writes the text for a collection value, - starting at a particular point, to a max length - - The collection containing elements to write. - The starting point of the elements to write - The maximum number of elements to write - - - - Write the generic 'Expected' line for a constraint - - The constraint that failed - - - - Write the generic 'Expected' line for a given value - - The expected value - - - - Write the generic 'Expected' line for a given value - and tolerance. - - The expected value - The tolerance within which the test was made - - - - Write the generic 'Actual' line for a constraint - - The constraint for which the actual value is to be written - - - - Write the generic 'Actual' line for a given value - - The actual value causing a failure - - - - Gets or sets the maximum line length for this writer - - - - - Helper class with properties and methods that supply - constraints that operate on exceptions. - - - - - Creates a constraint specifying the exact type of exception expected - - - - - Creates a constraint specifying the exact type of exception expected - - - - - Creates a constraint specifying the type of exception expected - - - - - Creates a constraint specifying the type of exception expected - - - - - Creates a constraint specifying an expected exception - - - - - Creates a constraint specifying an exception with a given InnerException - - - - - Creates a constraint specifying an expected TargetInvocationException - - - - - Creates a constraint specifying an expected TargetInvocationException - - - - - Creates a constraint specifying an expected TargetInvocationException - - - - - Creates a constraint specifying that no exception is thrown - - - - - Attribute used to apply a category to a test - - - - - The name of the category - - - - - Construct attribute for a given category based on - a name. The name may not contain the characters ',', - '+', '-' or '!'. However, this is not checked in the - constructor since it would cause an error to arise at - as the test was loaded without giving a clear indication - of where the problem is located. The error is handled - in NUnitFramework.cs by marking the test as not - runnable. - - The name of the category - - - - Protected constructor uses the Type name as the name - of the category. - - - - - The name of the category - - - - - Used to mark a field for use as a datapoint when executing a theory - within the same fixture that requires an argument of the field's Type. - - - - - Used to mark an array as containing a set of datapoints to be used - executing a theory within the same fixture that requires an argument - of the Type of the array elements. - - - - - Attribute used to provide descriptive text about a - test case or fixture. - - - - - Construct the attribute - - Text describing the test - - - - Gets the test description - - - - - Enumeration indicating how the expected message parameter is to be used - - - - Expect an exact match - - - Expect a message containing the parameter string - - - Match the regular expression provided as a parameter - - - Expect a message that starts with the parameter string - - - - ExpectedExceptionAttribute - - - - - - Constructor for a non-specific exception - - - - - Constructor for a given type of exception - - The type of the expected exception - - - - Constructor for a given exception name - - The full name of the expected exception - - - - Gets or sets the expected exception type - - - - - Gets or sets the full Type name of the expected exception - - - - - Gets or sets the expected message text - - - - - Gets or sets the user message displayed in case of failure - - - - - Gets or sets the type of match to be performed on the expected message - - - - - Gets the name of a method to be used as an exception handler - - - - - ExplicitAttribute marks a test or test fixture so that it will - only be run if explicitly executed from the gui or command line - or if it is included by use of a filter. The test will not be - run simply because an enclosing suite is run. - - - - - Default constructor - - - - - Constructor with a reason - - The reason test is marked explicit - - - - The reason test is marked explicit - - - - - Attribute used to mark a test that is to be ignored. - Ignored tests result in a warning message when the - tests are run. - - - - - Constructs the attribute without giving a reason - for ignoring the test. - - - - - Constructs the attribute giving a reason for ignoring the test - - The reason for ignoring the test - - - - The reason for ignoring a test - - - - - Abstract base for Attributes that are used to include tests - in the test run based on environmental settings. - - - - - Constructor with no included items specified, for use - with named property syntax. - - - - - Constructor taking one or more included items - - Comma-delimited list of included items - - - - Name of the item that is needed in order for - a test to run. Multiple itemss may be given, - separated by a comma. - - - - - Name of the item to be excluded. Multiple items - may be given, separated by a comma. - - - - - The reason for including or excluding the test - - - - - PlatformAttribute is used to mark a test fixture or an - individual method as applying to a particular platform only. - - - - - Constructor with no platforms specified, for use - with named property syntax. - - - - - Constructor taking one or more platforms - - Comma-deliminted list of platforms - - - - CultureAttribute is used to mark a test fixture or an - individual method as applying to a particular Culture only. - - - - - Constructor with no cultures specified, for use - with named property syntax. - - - - - Constructor taking one or more cultures - - Comma-deliminted list of cultures - - - - Marks a test to use a combinatorial join of any argument data - provided. NUnit will create a test case for every combination of - the arguments provided. This can result in a large number of test - cases and so should be used judiciously. This is the default join - type, so the attribute need not be used except as documentation. - - - - - PropertyAttribute is used to attach information to a test as a name/value pair.. - - - - - Construct a PropertyAttribute with a name and string value - - The name of the property - The property value - - - - Construct a PropertyAttribute with a name and int value - - The name of the property - The property value - - - - Construct a PropertyAttribute with a name and double value - - The name of the property - The property value - - - - Constructor for derived classes that set the - property dictionary directly. - - - - - Constructor for use by derived classes that use the - name of the type as the property name. Derived classes - must ensure that the Type of the property value is - a standard type supported by the BCL. Any custom - types will cause a serialization Exception when - in the client. - - - - - Gets the property dictionary for this attribute - - - - - Default constructor - - - - - Marks a test to use pairwise join of any argument data provided. - NUnit will attempt too excercise every pair of argument values at - least once, using as small a number of test cases as it can. With - only two arguments, this is the same as a combinatorial join. - - - - - Default constructor - - - - - Marks a test to use a sequential join of any argument data - provided. NUnit will use arguements for each parameter in - sequence, generating test cases up to the largest number - of argument values provided and using null for any arguments - for which it runs out of values. Normally, this should be - used with the same number of arguments for each parameter. - - - - - Default constructor - - - - - Summary description for MaxTimeAttribute. - - - - - Construct a MaxTimeAttribute, given a time in milliseconds. - - The maximum elapsed time in milliseconds - - - - RandomAttribute is used to supply a set of random values - to a single parameter of a parameterized test. - - - - - ValuesAttribute is used to provide literal arguments for - an individual parameter of a test. - - - - - Abstract base class for attributes that apply to parameters - and supply data for the parameter. - - - - - Gets the data to be provided to the specified parameter - - - - - The collection of data to be returned. Must - be set by any derived attribute classes. - We use an object[] so that the individual - elements may have their type changed in GetData - if necessary. - - - - - Construct with one argument - - - - - - Construct with two arguments - - - - - - - Construct with three arguments - - - - - - - - Construct with an array of arguments - - - - - - Get the collection of values to be used as arguments - - - - - Construct a set of doubles from 0.0 to 1.0, - specifying only the count. - - - - - - Construct a set of doubles from min to max - - - - - - - - Construct a set of ints from min to max - - - - - - - - Get the collection of values to be used as arguments - - - - - RangeAttribute is used to supply a range of values to an - individual parameter of a parameterized test. - - - - - Construct a range of ints using default step of 1 - - - - - - - Construct a range of ints specifying the step size - - - - - - - - Construct a range of longs - - - - - - - - Construct a range of doubles - - - - - - - - Construct a range of floats - - - - - - - - RepeatAttribute may be applied to test case in order - to run it multiple times. - - - - - Construct a RepeatAttribute - - The number of times to run the test - - - - RequiredAddinAttribute may be used to indicate the names of any addins - that must be present in order to run some or all of the tests in an - assembly. If the addin is not loaded, the entire assembly is marked - as NotRunnable. - - - - - Initializes a new instance of the class. - - The required addin. - - - - Gets the name of required addin. - - The required addin name. - - - - Summary description for SetCultureAttribute. - - - - - Construct given the name of a culture - - - - - - Summary description for SetUICultureAttribute. - - - - - Construct given the name of a culture - - - - - - SetUpAttribute is used in a TestFixture to identify a method - that is called immediately before each test is run. It is - also used in a SetUpFixture to identify the method that is - called once, before any of the subordinate tests are run. - - - - - Attribute used to mark a class that contains one-time SetUp - and/or TearDown methods that apply to all the tests in a - namespace or an assembly. - - - - - Attribute used to mark a static (shared in VB) property - that returns a list of tests. - - - - - Attribute used in a TestFixture to identify a method that is - called immediately after each test is run. It is also used - in a SetUpFixture to identify the method that is called once, - after all subordinate tests have run. In either case, the method - is guaranteed to be called, even if an exception is thrown. - - - - - Provide actions to execute before and after tests. - - - - - When implemented by an attribute, this interface implemented to provide actions to execute before and after tests. - - - - - Executed before each test is run - - Provides details about the test that is going to be run. - - - - Executed after each test is run - - Provides details about the test that has just been run. - - - - Provides the target for the action attribute - - The target for the action attribute - - - - Adding this attribute to a method within a - class makes the method callable from the NUnit test runner. There is a property - called Description which is optional which you can provide a more detailed test - description. This class cannot be inherited. - - - - [TestFixture] - public class Fixture - { - [Test] - public void MethodToTest() - {} - - [Test(Description = "more detailed description")] - publc void TestDescriptionMethod() - {} - } - - - - - - Descriptive text for this test - - - - - TestCaseAttribute is used to mark parameterized test cases - and provide them with their arguments. - - - - - Construct a TestCaseAttribute with a list of arguments. - This constructor is not CLS-Compliant - - - - - - Construct a TestCaseAttribute with a single argument - - - - - - Construct a TestCaseAttribute with a two arguments - - - - - - - Construct a TestCaseAttribute with a three arguments - - - - - - - - Gets the list of arguments to a test case - - - - - Gets or sets the expected result. Use - ExpectedResult by preference. - - The result. - - - - Gets or sets the expected result. - - The result. - - - - Gets a flag indicating whether an expected - result has been set. - - - - - Gets a list of categories associated with this test; - - - - - Gets or sets the category associated with this test. - May be a single category or a comma-separated list. - - - - - Gets or sets the expected exception. - - The expected exception. - - - - Gets or sets the name the expected exception. - - The expected name of the exception. - - - - Gets or sets the expected message of the expected exception - - The expected message of the exception. - - - - Gets or sets the type of match to be performed on the expected message - - - - - Gets or sets the description. - - The description. - - - - Gets or sets the name of the test. - - The name of the test. - - - - Gets or sets the ignored status of the test - - - - - Gets or sets the ignored status of the test - - - - - Gets or sets the explicit status of the test - - - - - Gets or sets the reason for not running the test - - - - - Gets or sets the reason for not running the test. - Set has the side effect of marking the test as ignored. - - The ignore reason. - - - - FactoryAttribute indicates the source to be used to - provide test cases for a test method. - - - - - Construct with the name of the data source, which must - be a property, field or method of the test class itself. - - An array of the names of the factories that will provide data - - - - Construct with a Type, which must implement IEnumerable - - The Type that will provide data - - - - Construct with a Type and name. - that don't support params arrays. - - The Type that will provide data - The name of the method, property or field that will provide data - - - - The name of a the method, property or fiend to be used as a source - - - - - A Type to be used as a source - - - - - Gets or sets the category associated with this test. - May be a single category or a comma-separated list. - - - - - [TestFixture] - public class ExampleClass - {} - - - - - Default constructor - - - - - Construct with a object[] representing a set of arguments. - In .NET 2.0, the arguments may later be separated into - type arguments and constructor arguments. - - - - - - Descriptive text for this fixture - - - - - Gets and sets the category for this fixture. - May be a comma-separated list of categories. - - - - - Gets a list of categories for this fixture - - - - - The arguments originally provided to the attribute - - - - - Gets or sets a value indicating whether this should be ignored. - - true if ignore; otherwise, false. - - - - Gets or sets the ignore reason. May set Ignored as a side effect. - - The ignore reason. - - - - Get or set the type arguments. If not set - explicitly, any leading arguments that are - Types are taken as type arguments. - - - - - Attribute used to identify a method that is - called before any tests in a fixture are run. - - - - - Attribute used to identify a method that is called after - all the tests in a fixture have run. The method is - guaranteed to be called, even if an exception is thrown. - - - - - Adding this attribute to a method within a - class makes the method callable from the NUnit test runner. There is a property - called Description which is optional which you can provide a more detailed test - description. This class cannot be inherited. - - - - [TestFixture] - public class Fixture - { - [Test] - public void MethodToTest() - {} - - [Test(Description = "more detailed description")] - publc void TestDescriptionMethod() - {} - } - - - - - - Used on a method, marks the test with a timeout value in milliseconds. - The test will be run in a separate thread and is cancelled if the timeout - is exceeded. Used on a method or assembly, sets the default timeout - for all contained test methods. - - - - - Construct a TimeoutAttribute given a time in milliseconds - - The timeout value in milliseconds - - - - Marks a test that must run in the STA, causing it - to run in a separate thread if necessary. - - On methods, you may also use STAThreadAttribute - to serve the same purpose. - - - - - Construct a RequiresSTAAttribute - - - - - Marks a test that must run in the MTA, causing it - to run in a separate thread if necessary. - - On methods, you may also use MTAThreadAttribute - to serve the same purpose. - - - - - Construct a RequiresMTAAttribute - - - - - Marks a test that must run on a separate thread. - - - - - Construct a RequiresThreadAttribute - - - - - Construct a RequiresThreadAttribute, specifying the apartment - - - - - ValueSourceAttribute indicates the source to be used to - provide data for one parameter of a test method. - - - - - Construct with the name of the factory - for use with languages - that don't support params arrays. - - The name of the data source to be used - - - - Construct with a Type and name - for use with languages - that don't support params arrays. - - The Type that will provide data - The name of the method, property or field that will provide data - - - - The name of a the method, property or fiend to be used as a source - - - - - A Type to be used as a source - - - - - AllItemsConstraint applies another constraint to each - item in a collection, succeeding if they all succeed. - - - - - Abstract base class used for prefixes - - - - - The Constraint class is the base of all built-in constraints - within NUnit. It provides the operator overloads used to combine - constraints. - - - - - The IConstraintExpression interface is implemented by all - complete and resolvable constraints and expressions. - - - - - Return the top-level constraint for this expression - - - - - - Static UnsetObject used to detect derived constraints - failing to set the actual value. - - - - - The actual value being tested against a constraint - - - - - The display name of this Constraint for use by ToString() - - - - - Argument fields used by ToString(); - - - - - The builder holding this constraint - - - - - Construct a constraint with no arguments - - - - - Construct a constraint with one argument - - - - - Construct a constraint with two arguments - - - - - Sets the ConstraintBuilder holding this constraint - - - - - Write the failure message to the MessageWriter provided - as an argument. The default implementation simply passes - the constraint and the actual value to the writer, which - then displays the constraint description and the value. - - Constraints that need to provide additional details, - such as where the error occured can override this. - - The MessageWriter on which to display the message - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Test whether the constraint is satisfied by an - ActualValueDelegate that returns the value to be tested. - The default implementation simply evaluates the delegate - but derived classes may override it to provide for delayed - processing. - - An - True for success, false for failure - - - - Test whether the constraint is satisfied by a given reference. - The default implementation simply dereferences the value but - derived classes may override it to provide for delayed processing. - - A reference to the value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Default override of ToString returns the constraint DisplayName - followed by any arguments within angle brackets. - - - - - - Returns the string representation of this constraint - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if the - argument constraint is not satisfied. - - - - - Returns a DelayedConstraint with the specified delay time. - - The delay in milliseconds. - - - - - Returns a DelayedConstraint with the specified delay time - and polling interval. - - The delay in milliseconds. - The interval at which to test the constraint. - - - - - The display name of this Constraint for use by ToString(). - The default value is the name of the constraint with - trailing "Constraint" removed. Derived classes may set - this to another name in their constructors. - - - - - Returns a ConstraintExpression by appending And - to the current constraint. - - - - - Returns a ConstraintExpression by appending And - to the current constraint. - - - - - Returns a ConstraintExpression by appending Or - to the current constraint. - - - - - Class used to detect any derived constraints - that fail to set the actual value in their - Matches override. - - - - - The base constraint - - - - - Construct given a base constraint - - - - - - Construct an AllItemsConstraint on top of an existing constraint - - - - - - Apply the item constraint to each item in the collection, - failing if any item fails. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - AndConstraint succeeds only if both members succeed. - - - - - BinaryConstraint is the abstract base of all constraints - that combine two other constraints in some fashion. - - - - - The first constraint being combined - - - - - The second constraint being combined - - - - - Construct a BinaryConstraint from two other constraints - - The first constraint - The second constraint - - - - Create an AndConstraint from two other constraints - - The first constraint - The second constraint - - - - Apply both member constraints to an actual value, succeeding - succeeding only if both of them succeed. - - The actual value - True if the constraints both succeeded - - - - Write a description for this contraint to a MessageWriter - - The MessageWriter to receive the description - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - AssignableFromConstraint is used to test that an object - can be assigned from a given Type. - - - - - TypeConstraint is the abstract base for constraints - that take a Type as their expected value. - - - - - The expected Type used by the constraint - - - - - Construct a TypeConstraint for a given Type - - - - - - Write the actual value for a failing constraint test to a - MessageWriter. TypeConstraints override this method to write - the name of the type. - - The writer on which the actual value is displayed - - - - Construct an AssignableFromConstraint for the type provided - - - - - - Test whether an object can be assigned from the specified type - - The object to be tested - True if the object can be assigned a value of the expected Type, otherwise false. - - - - Write a description of this constraint to a MessageWriter - - The MessageWriter to use - - - - AssignableToConstraint is used to test that an object - can be assigned to a given Type. - - - - - Construct an AssignableToConstraint for the type provided - - - - - - Test whether an object can be assigned to the specified type - - The object to be tested - True if the object can be assigned a value of the expected Type, otherwise false. - - - - Write a description of this constraint to a MessageWriter - - The MessageWriter to use - - - - AttributeConstraint tests that a specified attribute is present - on a Type or other provider and that the value of the attribute - satisfies some other constraint. - - - - - Constructs an AttributeConstraint for a specified attriute - Type and base constraint. - - - - - - - Determines whether the Type or other provider has the - expected attribute and if its value matches the - additional constraint specified. - - - - - Writes a description of the attribute to the specified writer. - - - - - Writes the actual value supplied to the specified writer. - - - - - Returns a string representation of the constraint. - - - - - AttributeExistsConstraint tests for the presence of a - specified attribute on a Type. - - - - - Constructs an AttributeExistsConstraint for a specific attribute Type - - - - - - Tests whether the object provides the expected attribute. - - A Type, MethodInfo, or other ICustomAttributeProvider - True if the expected attribute is present, otherwise false - - - - Writes the description of the constraint to the specified writer - - - - - BasicConstraint is the abstract base for constraints that - perform a simple comparison to a constant value. - - - - - Initializes a new instance of the class. - - The expected. - The description. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - BinarySerializableConstraint tests whether - an object is serializable in binary format. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation - - - - - CollectionConstraint is the abstract base class for - constraints that operate on collections. - - - - - Construct an empty CollectionConstraint - - - - - Construct a CollectionConstraint - - - - - - Determines whether the specified enumerable is empty. - - The enumerable. - - true if the specified enumerable is empty; otherwise, false. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Protected method to be implemented by derived classes - - - - - - - CollectionContainsConstraint is used to test whether a collection - contains an expected object as a member. - - - - - CollectionItemsEqualConstraint is the abstract base class for all - collection constraints that apply some notion of item equality - as a part of their operation. - - - - - Construct an empty CollectionConstraint - - - - - Construct a CollectionConstraint - - - - - - Flag the constraint to use the supplied EqualityAdapter. - NOTE: For internal use only. - - The EqualityAdapter to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied Comparison object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Compares two collection members for equality - - - - - Return a new CollectionTally for use in making tests - - The collection to be included in the tally - - - - Flag the constraint to ignore case and return self. - - - - - Construct a CollectionContainsConstraint - - - - - - Test whether the expected item is contained in the collection - - - - - - - Write a descripton of the constraint to a MessageWriter - - - - - - CollectionEquivalentCOnstraint is used to determine whether two - collections are equivalent. - - - - - Construct a CollectionEquivalentConstraint - - - - - - Test whether two collections are equivalent - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - CollectionOrderedConstraint is used to test whether a collection is ordered. - - - - - Construct a CollectionOrderedConstraint - - - - - Modifies the constraint to use an IComparer and returns self. - - - - - Modifies the constraint to use an IComparer<T> and returns self. - - - - - Modifies the constraint to use a Comparison<T> and returns self. - - - - - Modifies the constraint to test ordering by the value of - a specified property and returns self. - - - - - Test whether the collection is ordered - - - - - - - Write a description of the constraint to a MessageWriter - - - - - - Returns the string representation of the constraint. - - - - - - If used performs a reverse comparison - - - - - CollectionSubsetConstraint is used to determine whether - one collection is a subset of another - - - - - Construct a CollectionSubsetConstraint - - The collection that the actual value is expected to be a subset of - - - - Test whether the actual collection is a subset of - the expected collection provided. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - CollectionTally counts (tallies) the number of - occurences of each object in one or more enumerations. - - - - - Construct a CollectionTally object from a comparer and a collection - - - - - Try to remove an object from the tally - - The object to remove - True if successful, false if the object was not found - - - - Try to remove a set of objects from the tally - - The objects to remove - True if successful, false if any object was not found - - - - The number of objects remaining in the tally - - - - - ComparisonAdapter class centralizes all comparisons of - values in NUnit, adapting to the use of any provided - IComparer, IComparer<T> or Comparison<T> - - - - - Returns a ComparisonAdapter that wraps an IComparer - - - - - Returns a ComparisonAdapter that wraps an IComparer<T> - - - - - Returns a ComparisonAdapter that wraps a Comparison<T> - - - - - Compares two objects - - - - - Gets the default ComparisonAdapter, which wraps an - NUnitComparer object. - - - - - Construct a ComparisonAdapter for an IComparer - - - - - Compares two objects - - - - - - - - Construct a default ComparisonAdapter - - - - - ComparisonAdapter<T> extends ComparisonAdapter and - allows use of an IComparer<T> or Comparison<T> - to actually perform the comparison. - - - - - Construct a ComparisonAdapter for an IComparer<T> - - - - - Compare a Type T to an object - - - - - Construct a ComparisonAdapter for a Comparison<T> - - - - - Compare a Type T to an object - - - - - Abstract base class for constraints that compare values to - determine if one is greater than, equal to or less than - the other. This class supplies the Using modifiers. - - - - - ComparisonAdapter to be used in making the comparison - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - - - Modifies the constraint to use an IComparer and returns self - - - - - Modifies the constraint to use an IComparer<T> and returns self - - - - - Modifies the constraint to use a Comparison<T> and returns self - - - - - Delegate used to delay evaluation of the actual value - to be used in evaluating a constraint - - - - - ConstraintBuilder maintains the stacks that are used in - processing a ConstraintExpression. An OperatorStack - is used to hold operators that are waiting for their - operands to be reognized. a ConstraintStack holds - input constraints as well as the results of each - operator applied. - - - - - Initializes a new instance of the class. - - - - - Appends the specified operator to the expression by first - reducing the operator stack and then pushing the new - operator on the stack. - - The operator to push. - - - - Appends the specified constraint to the expresson by pushing - it on the constraint stack. - - The constraint to push. - - - - Sets the top operator right context. - - The right context. - - - - Reduces the operator stack until the topmost item - precedence is greater than or equal to the target precedence. - - The target precedence. - - - - Resolves this instance, returning a Constraint. If the builder - is not currently in a resolvable state, an exception is thrown. - - The resolved constraint - - - - Gets a value indicating whether this instance is resolvable. - - - true if this instance is resolvable; otherwise, false. - - - - - OperatorStack is a type-safe stack for holding ConstraintOperators - - - - - Initializes a new instance of the class. - - The builder. - - - - Pushes the specified operator onto the stack. - - The op. - - - - Pops the topmost operator from the stack. - - - - - - Gets a value indicating whether this is empty. - - true if empty; otherwise, false. - - - - Gets the topmost operator without modifying the stack. - - The top. - - - - ConstraintStack is a type-safe stack for holding Constraints - - - - - Initializes a new instance of the class. - - The builder. - - - - Pushes the specified constraint. As a side effect, - the constraint's builder field is set to the - ConstraintBuilder owning this stack. - - The constraint. - - - - Pops this topmost constrait from the stack. - As a side effect, the constraint's builder - field is set to null. - - - - - - Gets a value indicating whether this is empty. - - true if empty; otherwise, false. - - - - Gets the topmost constraint without modifying the stack. - - The topmost constraint - - - - ConstraintExpression represents a compound constraint in the - process of being constructed from a series of syntactic elements. - - Individual elements are appended to the expression as they are - reognized. Once an actual Constraint is appended, the expression - returns a resolvable Constraint. - - - - - ConstraintExpressionBase is the abstract base class for the - ConstraintExpression class, which represents a - compound constraint in the process of being constructed - from a series of syntactic elements. - - NOTE: ConstraintExpressionBase is separate because the - ConstraintExpression class was generated in earlier - versions of NUnit. The two classes may be combined - in a future version. - - - - - The ConstraintBuilder holding the elements recognized so far - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the - class passing in a ConstraintBuilder, which may be pre-populated. - - The builder. - - - - Returns a string representation of the expression as it - currently stands. This should only be used for testing, - since it has the side-effect of resolving the expression. - - - - - - Appends an operator to the expression and returns the - resulting expression itself. - - - - - Appends a self-resolving operator to the expression and - returns a new ResolvableConstraintExpression. - - - - - Appends a constraint to the expression and returns that - constraint, which is associated with the current state - of the expression being built. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the - class passing in a ConstraintBuilder, which may be pre-populated. - - The builder. - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding only if a specified number of them succeed. - - - - - Returns a new PropertyConstraintExpression, which will either - test for the existence of the named property on the object - being tested or apply any following constraint to that property. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns a new AttributeConstraint checking for the - presence of a particular attribute on an object. - - - - - Returns the constraint provided as an argument - used to allow custom - custom constraints to easily participate in the syntax. - - - - - Returns the constraint provided as an argument - used to allow custom - custom constraints to easily participate in the syntax. - - - - - Returns a constraint that tests two items for equality - - - - - Returns a constraint that tests that two references are the same object - - - - - Returns a constraint that tests whether the - actual value is greater than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is greater than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the - actual value is less than or equal to the suppled argument - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual - value is of the exact type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is of the type supplied as an argument or a derived type. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is assignable from the type supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a collection containing the same elements as the - collection supplied as an argument. - - - - - Returns a constraint that tests whether the actual value - is a subset of the collection supplied as an argument. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new CollectionContainsConstraint checking for the - presence of a particular object in the collection. - - - - - Returns a new ContainsConstraint. This constraint - will, in turn, make use of the appropriate second-level - constraint, depending on the type of the actual argument. - This overload is only used if the item sought is a string, - since any other type implies that we are looking for a - collection member. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value contains the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value starts with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value ends with the substring supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the regular expression supplied as an argument. - - - - - Returns a constraint that succeeds if the actual - value matches the regular expression supplied as an argument. - - - - - Returns a constraint that tests whether the path provided - is the same as an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the path provided - is the same path or under an expected path after canonicalization. - - - - - Returns a constraint that tests whether the actual value falls - within a specified range. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression that negates any - following constraint. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them succeed. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if at least one of them succeeds. - - - - - Returns a ConstraintExpression, which will apply - the following constraint to all members of a collection, - succeeding if all of them fail. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Length property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Count property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the Message property of the object being tested. - - - - - Returns a new ConstraintExpression, which will apply the following - constraint to the InnerException property of the object being tested. - - - - - With is currently a NOP - reserved for future use. - - - - - Returns a constraint that tests for null - - - - - Returns a constraint that tests for True - - - - - Returns a constraint that tests for False - - - - - Returns a constraint that tests for a positive value - - - - - Returns a constraint that tests for a negative value - - - - - Returns a constraint that tests for NaN - - - - - Returns a constraint that tests for empty - - - - - Returns a constraint that tests whether a collection - contains all unique items. - - - - - Returns a constraint that tests whether an object graph is serializable in binary format. - - - - - Returns a constraint that tests whether an object graph is serializable in xml format. - - - - - Returns a constraint that tests whether a collection is ordered - - - - - ContainsConstraint tests a whether a string contains a substring - or a collection contains an object. It postpones the decision of - which test to use until the type of the actual argument is known. - This allows testing whether a string is contained in a collection - or as a substring of another string using the same syntax. - - - - - Initializes a new instance of the class. - - The expected. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied Comparison object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to ignore case and return self. - - - - - Applies a delay to the match so that a match can be evaluated in the future. - - - - - Creates a new DelayedConstraint - - The inner constraint two decorate - The time interval after which the match is performed - If the value of is less than 0 - - - - Creates a new DelayedConstraint - - The inner constraint two decorate - The time interval after which the match is performed - The time interval used for polling - If the value of is less than 0 - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for if the base constraint fails, false if it succeeds - - - - Test whether the constraint is satisfied by a delegate - - The delegate whose value is to be tested - True for if the base constraint fails, false if it succeeds - - - - Test whether the constraint is satisfied by a given reference. - Overridden to wait for the specified delay period before - calling the base constraint with the dereferenced value. - - A reference to the value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a MessageWriter. - - The writer on which the actual value is displayed - - - - Returns the string representation of the constraint. - - - - - EmptyCollectionConstraint tests whether a collection is empty. - - - - - Check that the collection is empty - - - - - - - Write the constraint description to a MessageWriter - - - - - - EmptyConstraint tests a whether a string or collection is empty, - postponing the decision about which test is applied until the - type of the actual argument is known. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - EmptyDirectoryConstraint is used to test that a directory is empty - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - EmptyStringConstraint tests whether a string is empty. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - EndsWithConstraint can test whether a string ends - with an expected substring. - - - - - StringConstraint is the abstract base for constraints - that operate on strings. It supports the IgnoreCase - modifier for string operations. - - - - - The expected value - - - - - Indicates whether tests should be case-insensitive - - - - - Constructs a StringConstraint given an expected value - - The expected value - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Test whether the constraint is satisfied by a given string - - The string to be tested - True for success, false for failure - - - - Modify the constraint to ignore case in matching. - - - - - Initializes a new instance of the class. - - The expected string - - - - Test whether the constraint is matched by the actual value. - This is a template method, which calls the IsMatch method - of the derived class. - - - - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - EqualConstraint is able to compare an actual value with the - expected value provided in its constructor. Two objects are - considered equal if both are null, or if both have the same - value. NUnit has special semantics for some object types. - - - - - If true, strings in error messages will be clipped - - - - - NUnitEqualityComparer used to test equality. - - - - - Initializes a new instance of the class. - - The expected value. - - - - Flag the constraint to use a tolerance when determining equality. - - Tolerance value to be used - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied Comparison object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Flag the constraint to use the supplied IEqualityComparer object. - - The IComparer object to use. - Self. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write a failure message. Overridden to provide custom - failure messages for EqualConstraint. - - The MessageWriter to write to - - - - Write description of this constraint - - The MessageWriter to write to - - - - Display the failure information for two collections that did not match. - - The MessageWriter on which to display - The expected collection. - The actual collection - The depth of this failure in a set of nested collections - - - - Displays a single line showing the types and sizes of the expected - and actual enumerations, collections or arrays. If both are identical, - the value is only shown once. - - The MessageWriter on which to display - The expected collection or array - The actual collection or array - The indentation level for the message line - - - - Displays a single line showing the point in the expected and actual - arrays at which the comparison failed. If the arrays have different - structures or dimensions, both values are shown. - - The MessageWriter on which to display - The expected array - The actual array - Index of the failure point in the underlying collections - The indentation level for the message line - - - - Display the failure information for two IEnumerables that did not match. - - The MessageWriter on which to display - The expected enumeration. - The actual enumeration - The depth of this failure in a set of nested collections - - - - Flag the constraint to ignore case and return self. - - - - - Flag the constraint to suppress string clipping - and return self. - - - - - Flag the constraint to compare arrays as collections - and return self. - - - - - Switches the .Within() modifier to interpret its tolerance as - a distance in representable values (see remarks). - - Self. - - Ulp stands for "unit in the last place" and describes the minimum - amount a given value can change. For any integers, an ulp is 1 whole - digit. For floating point values, the accuracy of which is better - for smaller numbers and worse for larger numbers, an ulp depends - on the size of the number. Using ulps for comparison of floating - point results instead of fixed tolerances is safer because it will - automatically compensate for the added inaccuracy of larger numbers. - - - - - Switches the .Within() modifier to interpret its tolerance as - a percentage that the actual values is allowed to deviate from - the expected value. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in days. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in hours. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in minutes. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in seconds. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in milliseconds. - - Self - - - - Causes the tolerance to be interpreted as a TimeSpan in clock ticks. - - Self - - - - EqualityAdapter class handles all equality comparisons - that use an IEqualityComparer, IEqualityComparer<T> - or a ComparisonAdapter. - - - - - Compares two objects, returning true if they are equal - - - - - Returns true if the two objects can be compared by this adapter. - The base adapter cannot handle IEnumerables except for strings. - - - - - Returns an EqualityAdapter that wraps an IComparer. - - - - - Returns an EqualityAdapter that wraps an IEqualityComparer. - - - - - Returns an EqualityAdapter that wraps an IEqualityComparer<T>. - - - - - Returns an EqualityAdapter that wraps an IComparer<T>. - - - - - Returns an EqualityAdapter that wraps a Comparison<T>. - - - - - EqualityAdapter that wraps an IComparer. - - - - - Returns true if the two objects can be compared by this adapter. - Generic adapter requires objects of the specified type. - - - - - EqualityAdapter that wraps an IComparer. - - - - - EqualityAdapterList represents a list of EqualityAdapters - in a common class across platforms. - - - - - ExactCountConstraint applies another constraint to each - item in a collection, succeeding only if a specified - number of items succeed. - - - - - Construct an ExactCountConstraint on top of an existing constraint - - - - - - - Apply the item constraint to each item in the collection, - succeeding only if the expected number of items pass. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - ExactTypeConstraint is used to test that an object - is of the exact type provided in the constructor - - - - - Construct an ExactTypeConstraint for a given Type - - The expected Type. - - - - Test that an object is of the exact type specified - - The actual value. - True if the tested object is of the exact type provided, otherwise false. - - - - Write the description of this constraint to a MessageWriter - - The MessageWriter to use - - - - ExceptionTypeConstraint is a special version of ExactTypeConstraint - used to provided detailed info about the exception thrown in - an error message. - - - - - Constructs an ExceptionTypeConstraint - - - - - Write the actual value for a failing constraint test to a - MessageWriter. Overriden to write additional information - in the case of an Exception. - - The MessageWriter to use - - - - FailurePoint class represents one point of failure - in an equality test. - - - - - The location of the failure - - - - - The expected value - - - - - The actual value - - - - - Indicates whether the expected value is valid - - - - - Indicates whether the actual value is valid - - - - - FailurePointList represents a set of FailurePoints - in a cross-platform way. - - - - - FalseConstraint tests that the actual value is false - - - - - Initializes a new instance of the class. - - - - Helper routines for working with floating point numbers - - - The floating point comparison code is based on this excellent article: - http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm - - - "ULP" means Unit in the Last Place and in the context of this library refers to - the distance between two adjacent floating point numbers. IEEE floating point - numbers can only represent a finite subset of natural numbers, with greater - accuracy for smaller numbers and lower accuracy for very large numbers. - - - If a comparison is allowed "2 ulps" of deviation, that means the values are - allowed to deviate by up to 2 adjacent floating point values, which might be - as low as 0.0000001 for small numbers or as high as 10.0 for large numbers. - - - - - Compares two floating point values for equality - First floating point value to be compared - Second floating point value t be compared - - Maximum number of representable floating point values that are allowed to - be between the left and the right floating point values - - True if both numbers are equal or close to being equal - - - Floating point values can only represent a finite subset of natural numbers. - For example, the values 2.00000000 and 2.00000024 can be stored in a float, - but nothing inbetween them. - - - This comparison will count how many possible floating point values are between - the left and the right number. If the number of possible values between both - numbers is less than or equal to maxUlps, then the numbers are considered as - being equal. - - - Implementation partially follows the code outlined here: - http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ - - - - - Compares two double precision floating point values for equality - First double precision floating point value to be compared - Second double precision floating point value t be compared - - Maximum number of representable double precision floating point values that are - allowed to be between the left and the right double precision floating point values - - True if both numbers are equal or close to being equal - - - Double precision floating point values can only represent a limited series of - natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004 - can be stored in a double, but nothing inbetween them. - - - This comparison will count how many possible double precision floating point - values are between the left and the right number. If the number of possible - values between both numbers is less than or equal to maxUlps, then the numbers - are considered as being equal. - - - Implementation partially follows the code outlined here: - http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ - - - - - - Reinterprets the memory contents of a floating point value as an integer value - - - Floating point value whose memory contents to reinterpret - - - The memory contents of the floating point value interpreted as an integer - - - - - Reinterprets the memory contents of a double precision floating point - value as an integer value - - - Double precision floating point value whose memory contents to reinterpret - - - The memory contents of the double precision floating point value - interpreted as an integer - - - - - Reinterprets the memory contents of an integer as a floating point value - - Integer value whose memory contents to reinterpret - - The memory contents of the integer value interpreted as a floating point value - - - - - Reinterprets the memory contents of an integer value as a double precision - floating point value - - Integer whose memory contents to reinterpret - - The memory contents of the integer interpreted as a double precision - floating point value - - - - Union of a floating point variable and an integer - - - The union's value as a floating point variable - - - The union's value as an integer - - - The union's value as an unsigned integer - - - Union of a double precision floating point variable and a long - - - The union's value as a double precision floating point variable - - - The union's value as a long - - - The union's value as an unsigned long - - - - Tests whether a value is greater than the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Tests whether a value is greater than or equal to the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - InstanceOfTypeConstraint is used to test that an object - is of the same type provided or derived from it. - - - - - Construct an InstanceOfTypeConstraint for the type provided - - The expected Type - - - - Test whether an object is of the specified type or a derived type - - The object to be tested - True if the object is of the provided type or derives from it, otherwise false. - - - - Write a description of this constraint to a MessageWriter - - The MessageWriter to use - - - - Tests whether a value is less than the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Tests whether a value is less than or equal to the value supplied to its constructor - - - - - The value against which a comparison is to be made - - - - - Initializes a new instance of the class. - - The expected value. - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Static methods used in creating messages - - - - - Static string used when strings are clipped - - - - - Returns the representation of a type as used in NUnitLite. - This is the same as Type.ToString() except for arrays, - which are displayed with their declared sizes. - - - - - - - Converts any control characters in a string - to their escaped representation. - - The string to be converted - The converted string - - - - Return the a string representation for a set of indices into an array - - Array of indices for which a string is needed - - - - Get an array of indices representing the point in a enumerable, - collection or array corresponding to a single int index into the - collection. - - The collection to which the indices apply - Index in the collection - Array of indices - - - - Clip a string to a given length, starting at a particular offset, returning the clipped - string with ellipses representing the removed parts - - The string to be clipped - The maximum permitted length of the result string - The point at which to start clipping - The clipped string - - - - Clip the expected and actual strings in a coordinated fashion, - so that they may be displayed together. - - - - - - - - - Shows the position two strings start to differ. Comparison - starts at the start index. - - The expected string - The actual string - The index in the strings at which comparison should start - Boolean indicating whether case should be ignored - -1 if no mismatch found, or the index where mismatch found - - - - NaNConstraint tests that the actual value is a double or float NaN - - - - - Test that the actual value is an NaN - - - - - - - Write the constraint description to a specified writer - - - - - - NoItemConstraint applies another constraint to each - item in a collection, failing if any of them succeeds. - - - - - Construct a NoItemConstraint on top of an existing constraint - - - - - - Apply the item constraint to each item in the collection, - failing if any item fails. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - NotConstraint negates the effect of some other constraint - - - - - Initializes a new instance of the class. - - The base constraint to be negated. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for if the base constraint fails, false if it succeeds - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a MessageWriter. - - The writer on which the actual value is displayed - - - - NullConstraint tests that the actual value is null - - - - - Initializes a new instance of the class. - - - - - NullEmptyStringConstraint tests whether a string is either null or empty. - - - - - Constructs a new NullOrEmptyStringConstraint - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - The Numerics class contains common operations on numeric values. - - - - - Checks the type of the object, returning true if - the object is a numeric type. - - The object to check - true if the object is a numeric type - - - - Checks the type of the object, returning true if - the object is a floating point numeric type. - - The object to check - true if the object is a floating point numeric type - - - - Checks the type of the object, returning true if - the object is a fixed point numeric type. - - The object to check - true if the object is a fixed point numeric type - - - - Test two numeric values for equality, performing the usual numeric - conversions and using a provided or default tolerance. If the tolerance - provided is Empty, this method may set it to a default tolerance. - - The expected value - The actual value - A reference to the tolerance in effect - True if the values are equal - - - - Compare two numeric values, performing the usual numeric conversions. - - The expected value - The actual value - The relationship of the values to each other - - - - NUnitComparer encapsulates NUnit's default behavior - in comparing two objects. - - - - - Compares two objects - - - - - - - - Returns the default NUnitComparer. - - - - - Generic version of NUnitComparer - - - - - - Compare two objects of the same type - - - - - NUnitEqualityComparer encapsulates NUnit's handling of - equality tests between objects. - - - - - - - - - - Compares two objects for equality within a tolerance - - The first object to compare - The second object to compare - The tolerance to use in the comparison - - - - - If true, all string comparisons will ignore case - - - - - If true, arrays will be treated as collections, allowing - those of different dimensions to be compared - - - - - Comparison objects used in comparisons for some constraints. - - - - - List of points at which a failure occured. - - - - - RecursionDetector used to check for recursion when - evaluating self-referencing enumerables. - - - - - Compares two objects for equality within a tolerance, setting - the tolerance to the actual tolerance used if an empty - tolerance is supplied. - - - - - Helper method to compare two arrays - - - - - Method to compare two DirectoryInfo objects - - first directory to compare - second directory to compare - true if equivalent, false if not - - - - Returns the default NUnitEqualityComparer - - - - - Gets and sets a flag indicating whether case should - be ignored in determining equality. - - - - - Gets and sets a flag indicating that arrays should be - compared as collections, without regard to their shape. - - - - - Gets the list of external comparers to be used to - test for equality. They are applied to members of - collections, in place of NUnit's own logic. - - - - - Gets the list of failure points for the last Match performed. - The list consists of objects to be interpreted by the caller. - This generally means that the caller may only make use of - objects it has placed on the list at a particular depthy. - - - - - RecursionDetector detects when a comparison - between two enumerables has reached a point - where the same objects that were previously - compared are again being compared. This allows - the caller to stop the comparison if desired. - - - - - Check whether two objects have previously - been compared, returning true if they have. - The two objects are remembered, so that a - second call will always return true. - - - - - OrConstraint succeeds if either member succeeds - - - - - Create an OrConstraint from two other constraints - - The first constraint - The second constraint - - - - Apply the member constraints to an actual value, succeeding - succeeding as soon as one of them succeeds. - - The actual value - True if either constraint succeeded - - - - Write a description for this contraint to a MessageWriter - - The MessageWriter to receive the description - - - - PathConstraint serves as the abstract base of constraints - that operate on paths and provides several helper methods. - - - - - The expected path used in the constraint - - - - - Flag indicating whether a caseInsensitive comparison should be made - - - - - Construct a PathConstraint for a give expected path - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Returns true if the expected path and actual path match - - - - - Returns the string representation of this constraint - - - - - Transform the provided path to its canonical form so that it - may be more easily be compared with other paths. - - The original path - The path in canonical form - - - - Test whether one path in canonical form is under another. - - The first path - supposed to be the parent path - The second path - supposed to be the child path - Indicates whether case should be ignored - - - - - Modifies the current instance to be case-insensitve - and returns it. - - - - - Modifies the current instance to be case-sensitve - and returns it. - - - - - Predicate constraint wraps a Predicate in a constraint, - returning success if the predicate is true. - - - - - Construct a PredicateConstraint from a predicate - - - - - Determines whether the predicate succeeds when applied - to the actual value. - - - - - Writes the description to a MessageWriter - - - - - PropertyConstraint extracts a named property and uses - its value as the actual value for a chained constraint. - - - - - Initializes a new instance of the class. - - The name. - The constraint to apply to the property. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation of the constraint. - - - - - - PropertyExistsConstraint tests that a named property - exists on the object provided through Match. - - Originally, PropertyConstraint provided this feature - in addition to making optional tests on the vaue - of the property. The two constraints are now separate. - - - - - Initializes a new instance of the class. - - The name of the property. - - - - Test whether the property exists for a given object - - The object to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. - - The writer on which the actual value is displayed - - - - Returns the string representation of the constraint. - - - - - - RangeConstraint tests whether two values are within a - specified range. - - - - - Initializes a new instance of the class. - - From. - To. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - RegexConstraint can test whether a string matches - the pattern provided. - - - - - Initializes a new instance of the class. - - The pattern. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - ResolvableConstraintExpression is used to represent a compound - constraint being constructed at a point where the last operator - may either terminate the expression or may have additional - qualifying constraints added to it. - - It is used, for example, for a Property element or for - an Exception element, either of which may be optionally - followed by constraints that apply to the property or - exception. - - - - - Create a new instance of ResolvableConstraintExpression - - - - - Create a new instance of ResolvableConstraintExpression, - passing in a pre-populated ConstraintBuilder. - - - - - Resolve the current expression to a Constraint - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied only if both - argument constraints are satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if either - of the argument constraints is satisfied. - - - - - This operator creates a constraint that is satisfied if the - argument constraint is not satisfied. - - - - - Appends an And Operator to the expression - - - - - Appends an Or operator to the expression. - - - - - ReusableConstraint wraps a constraint expression after - resolving it so that it can be reused consistently. - - - - - Construct a ReusableConstraint from a constraint expression - - The expression to be resolved and reused - - - - Converts a constraint to a ReusableConstraint - - The constraint to be converted - A ReusableConstraint - - - - Returns the string representation of the constraint. - - A string representing the constraint - - - - Resolves the ReusableConstraint by returning the constraint - that it originally wrapped. - - A resolved constraint - - - - SameAsConstraint tests whether an object is identical to - the object passed to its constructor - - - - - Initializes a new instance of the class. - - The expected object. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Summary description for SamePathConstraint. - - - - - Initializes a new instance of the class. - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The expected path - The actual path - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - SamePathOrUnderConstraint tests that one path is under another - - - - - Initializes a new instance of the class. - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The expected path - The actual path - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - SomeItemsConstraint applies another constraint to each - item in a collection, succeeding if any of them succeeds. - - - - - Construct a SomeItemsConstraint on top of an existing constraint - - - - - - Apply the item constraint to each item in the collection, - succeeding if any item succeeds. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - StartsWithConstraint can test whether a string starts - with an expected substring. - - - - - Initializes a new instance of the class. - - The expected string - - - - Test whether the constraint is matched by the actual value. - This is a template method, which calls the IsMatch method - of the derived class. - - - - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - SubPathConstraint tests that the actual path is under the expected path - - - - - Initializes a new instance of the class. - - The expected path - - - - Test whether the constraint is satisfied by a given value - - The expected path - The actual path - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - SubstringConstraint can test whether a string contains - the expected substring. - - - - - Initializes a new instance of the class. - - The expected. - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - ThrowsConstraint is used to test the exception thrown by - a delegate by applying a constraint to it. - - - - - Initializes a new instance of the class, - using a constraint to be applied to the exception. - - A constraint to apply to the caught exception. - - - - Executes the code of the delegate and captures any exception. - If a non-null base constraint was provided, it applies that - constraint to the exception. - - A delegate representing the code to be tested - True if an exception is thrown and the constraint succeeds, otherwise false - - - - Converts an ActualValueDelegate to a TestDelegate - before calling the primary overload. - - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation of this constraint - - - - - Get the actual exception thrown - used by Assert.Throws. - - - - - ThrowsNothingConstraint tests that a delegate does not - throw an exception. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True if no exception is thrown, otherwise false - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. Overridden in ThrowsNothingConstraint to write - information about the exception that was actually caught. - - The writer on which the actual value is displayed - - - - The Tolerance class generalizes the notion of a tolerance - within which an equality test succeeds. Normally, it is - used with numeric types, but it can be used with any - type that supports taking a difference between two - objects and comparing that difference to a value. - - - - - Constructs a linear tolerance of a specdified amount - - - - - Constructs a tolerance given an amount and ToleranceMode - - - - - Tests that the current Tolerance is linear with a - numeric value, throwing an exception if it is not. - - - - - Returns an empty Tolerance object, equivalent to - specifying no tolerance. In most cases, it results - in an exact match but for floats and doubles a - default tolerance may be used. - - - - - Returns a zero Tolerance object, equivalent to - specifying an exact match. - - - - - Gets the ToleranceMode for the current Tolerance - - - - - Gets the value of the current Tolerance instance. - - - - - Returns a new tolerance, using the current amount as a percentage. - - - - - Returns a new tolerance, using the current amount in Ulps. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of days. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of hours. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of minutes. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of seconds. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of milliseconds. - - - - - Returns a new tolerance with a TimeSpan as the amount, using - the current amount as a number of clock ticks. - - - - - Returns true if the current tolerance is empty. - - - - - Modes in which the tolerance value for a comparison can be interpreted. - - - - - The tolerance was created with a value, without specifying - how the value would be used. This is used to prevent setting - the mode more than once and is generally changed to Linear - upon execution of the test. - - - - - The tolerance is used as a numeric range within which - two compared values are considered to be equal. - - - - - Interprets the tolerance as the percentage by which - the two compared values my deviate from each other. - - - - - Compares two values based in their distance in - representable numbers. - - - - - TrueConstraint tests that the actual value is true - - - - - Initializes a new instance of the class. - - - - - UniqueItemsConstraint tests whether all the items in a - collection are unique. - - - - - Check that all items are unique. - - - - - - - Write a description of this constraint to a MessageWriter - - - - - - XmlSerializableConstraint tests whether - an object is serializable in XML format. - - - - - Test whether the constraint is satisfied by a given value - - The value to be tested - True for success, false for failure - - - - Write the constraint description to a MessageWriter - - The writer on which the description is displayed - - - - Write the actual value for a failing constraint test to a - MessageWriter. The default implementation simply writes - the raw value of actual, leaving it to the writer to - perform any formatting. - - The writer on which the actual value is displayed - - - - Returns the string representation of this constraint - - - - - Represents a constraint that succeeds if all the - members of a collection match a base constraint. - - - - - Abstract base for operators that indicate how to - apply a constraint to items in a collection. - - - - - PrefixOperator takes a single constraint and modifies - it's action in some way. - - - - - The ConstraintOperator class is used internally by a - ConstraintBuilder to represent an operator that - modifies or combines constraints. - - Constraint operators use left and right precedence - values to determine whether the top operator on the - stack should be reduced before pushing a new operator. - - - - - The precedence value used when the operator - is about to be pushed to the stack. - - - - - The precedence value used when the operator - is on the top of the stack. - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - The syntax element preceding this operator - - - - - The syntax element folowing this operator - - - - - The precedence value used when the operator - is about to be pushed to the stack. - - - - - The precedence value used when the operator - is on the top of the stack. - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - Returns the constraint created by applying this - prefix to another constraint. - - - - - - - Constructs a CollectionOperator - - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - they all succeed. - - - - - Operator that requires both it's arguments to succeed - - - - - Abstract base class for all binary operators - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - Abstract method that produces a constraint by applying - the operator to its left and right constraint arguments. - - - - - Gets the left precedence of the operator - - - - - Gets the right precedence of the operator - - - - - Construct an AndOperator - - - - - Apply the operator to produce an AndConstraint - - - - - Operator that tests for the presence of a particular attribute - on a type and optionally applies further tests to the attribute. - - - - - Abstract base class for operators that are able to reduce to a - constraint whether or not another syntactic element follows. - - - - - Construct an AttributeOperator for a particular Type - - The Type of attribute tested - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - Represents a constraint that succeeds if the specified - count of members of a collection match a base constraint. - - - - - Construct an ExactCountOperator for a specified count - - The expected count - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - none of them succeed. - - - - - Represents a constraint that succeeds if none of the - members of a collection match a base constraint. - - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - none of them succeed. - - - - - Negates the test of the constraint it wraps. - - - - - Constructs a new NotOperator - - - - - Returns a NotConstraint applied to its argument. - - - - - Operator that requires at least one of it's arguments to succeed - - - - - Construct an OrOperator - - - - - Apply the operator to produce an OrConstraint - - - - - Operator used to test for the presence of a named Property - on an object and optionally apply further tests to the - value of that property. - - - - - Constructs a PropOperator for a particular named property - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - - Gets the name of the property to which the operator applies - - - - - Represents a constraint that succeeds if any of the - members of a collection match a base constraint. - - - - - Returns a constraint that will apply the argument - to the members of a collection, succeeding if - any of them succeed. - - - - - Operator that tests that an exception is thrown and - optionally applies further tests to the exception. - - - - - Construct a ThrowsOperator - - - - - Reduce produces a constraint from the operator and - any arguments. It takes the arguments from the constraint - stack and pushes the resulting constraint on it. - - - - - Represents a constraint that simply wraps the - constraint provided as an argument, without any - further functionality, but which modifes the - order of evaluation because of its precedence. - - - - - Constructor for the WithOperator - - - - - Returns a constraint that wraps its argument - - - - - Thrown when an assertion failed. - - - - The error message that explains - the reason for the exception - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - Thrown when an assertion failed. - - - - - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - Thrown when a test executes inconclusively. - - - - The error message that explains - the reason for the exception - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - Thrown when an assertion failed. - - - - - - - The error message that explains - the reason for the exception - The exception that caused the - current exception - - - - Serialization Constructor - - - - - - - - - - - Compares two objects of a given Type for equality within a tolerance - - The first object to compare - The second object to compare - The tolerance to use in the comparison - - - - diff --git a/src/packages/NUnit.2.6.3/license.txt b/src/packages/NUnit.2.6.3/license.txt deleted file mode 100644 index b12903afb..000000000 --- a/src/packages/NUnit.2.6.3/license.txt +++ /dev/null @@ -1,15 +0,0 @@ -Copyright 2002-2013 Charlie Poole -Copyright 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov -Copyright 2000-2002 Philip A. Craig - -This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required. - -Portions Copyright 2002-2013 Charlie Poole or Copyright 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright 2000-2002 Philip A. Craig - -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. diff --git a/src/packages/Npgsql.2.2.3/lib/net20/Mono.Security.dll b/src/packages/Npgsql.2.2.3/lib/net20/Mono.Security.dll deleted file mode 100644 index 5173f0dc4..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/Mono.Security.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net20/Npgsql.dll b/src/packages/Npgsql.2.2.3/lib/net20/Npgsql.dll deleted file mode 100644 index 2b5b522cf..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/Npgsql.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net20/Npgsql.xml b/src/packages/Npgsql.2.2.3/lib/net20/Npgsql.xml deleted file mode 100644 index fd155d2e9..000000000 --- a/src/packages/Npgsql.2.2.3/lib/net20/Npgsql.xml +++ /dev/null @@ -1,7569 +0,0 @@ - - - - Npgsql - - - - - Handles serialisation of .NET array or IEnumeration to pg format. - Arrays of arrays, enumerations of enumerations, arrays of enumerations etc. - are treated as multi-dimensional arrays (in much the same manner as an array of arrays - is used to emulate multi-dimensional arrays in languages that lack native support for them). - If such an enumeration of enumerations is "jagged" (as opposed to rectangular, cuboid, - hypercuboid, hyperhypercuboid, etc) then this class will "correctly" serialise it, but pg - will raise an error as it doesn't allow jagged arrays. - - - - - Create an ArrayNativeToBackendTypeConverter with the element converter passed - - The that would be used to serialise the element type. - - - - Serialise the enumeration or array. - - - - - Convert a System.Array to PG binary format. - Write the array header and prepare to write array data to the stream. - - - - - Append all array data to the binary stream. - - - - - Handles parsing of pg arrays into .NET arrays. - - - - - Takes a string representation of a pg 1-dimensional array - (or a 1-dimensional row within an n-dimensional array) - and allows enumeration of the string represenations of each items. - - - - - Takes a string representation of a pg n-dimensional array - and allows enumeration of the string represenations of the next - lower level of rows (which in turn can be taken as (n-1)-dimensional arrays. - - - - - Takes an ArrayList which may be an ArrayList of ArrayLists, an ArrayList of ArrayLists of ArrayLists - and so on and enumerates the items that aren't ArrayLists (the leaf nodes if we think of the ArrayList - passed as a tree). Simply uses the ArrayLists' own IEnumerators to get that of the next, - pushing them onto a stack until we hit something that isn't an ArrayList. - ArrayList to enumerate - IEnumerable - - - - - Create a new ArrayBackendToNativeTypeConverter - - for the element type. - - - - Creates an array from pg text representation. - - - - - Creates an array list from pg represenation of an array. - Multidimensional arrays are treated as ArrayLists of ArrayLists - - - - - Creates an n-dimensional array from an ArrayList of ArrayLists or - a 1-dimensional array from something else. - - to convert - Type of the elements in the list - produced. - - - - Creates an n-dimensional System.Array from PG binary representation. - This function reads the array header and sets up an n-dimensional System.Array object to hold its data. - PopulateArrayFromBinaryArray() is then called to carry out array population. - - - - - Recursively populates an array from PB binary data representation. - - - - - Takes an array of ints and treats them like the limits of a set of counters. - Retains a matching set of ints that is set to all zeros on the first ++ - On a ++ it increments the "right-most" int. If that int reaches it's - limit it is set to zero and the one before it is incremented, and so on. - - Making this a more general purpose class is pretty straight-forward, but we'll just put what we need here. - - - - - Implements a bit string; a collection of zero or more bits which can each be 1 or 0. - BitString's behave as a list of bools, though like most strings and unlike most collections the position - tends to be of as much significance as the value. - BitStrings are often used as masks, and are commonly cast to and from other values. - - - - - Represents the empty string. - - - - - Create a BitString from an enumeration of boolean values. The BitString will contain - those booleans in the order they came in. - - The boolean values. - - - - Creates a BitString filled with a given number of true or false values. - - The value to fill the string with. - The number of bits to fill. - - - - Creats a bitstring from a string. - The string to copy from. - - - - - - Creates a single-bit element from a boolean value. - - The bool value which determines whether - the bit is 1 or 0. - - - - Creates a bitstring from an unsigned integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - This method is not CLS Compliant, and may not be available to some languages. - - - - Creates a bitstring from an integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - - - - Finds the first instance of a given value - - The value - whether true or false - to search for. - The index of the value found, or -1 if none are present. - - - - True if there is at least one bit with the value looked for. - - The value - true or false - to detect. - True if at least one bit was the same as item, false otherwise. - - - - Copies the bitstring to an array of bools. - - The boolean array to copy to. - The index in the array to start copying from. - - - - Returns an enumerator that enumerates through the string. - - The enumerator. - - - - Creats a bitstring by concatenating another onto this one. - - The string to append to this one. - The combined strings. - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string. - The length of the string to return, must be greater than zero, and may not be - so large that the start + length exceeds the bounds of this instance. - The Bitstring identified - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string, - the rest of the string is returned. - The Bitstring identified - - - - A logical and between this string and another. The two strings must be the same length. - - Another BitString to AND with this one. - A bitstring with 1 where both BitStrings had 1 and 0 otherwise. - - - - A logical or between this string and another. The two strings must be the same length. - - Another BitString to OR with this one. - A bitstring with 1 where either BitString had 1 and 0 otherwise. - - - - A logical xor between this string and another. The two strings must be the same length. - - Another BitString to XOR with this one. - A bitstring with 1 where one BitStrings and the other had 0, - and 0 where they both had 1 or both had 0. - - - - A bitstring that is the logical inverse of this one. - - A bitstring of the same length as this with 1 where this has 0 and vice-versa. - - - - Shifts the string operand bits to the left, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the left. - A left-shifted bitstring. - The behaviour of LShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a right-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. - - - - - Shifts the string operand bits to the right, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the right. - A right-shifted bitstring. - The behaviour of RShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a left-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. It also performs - a logical shift, rather than an arithmetic shift, so it always sets the vacated bit positions to zero - (like PostgreSQL and like .NET for unsigned integers but not for signed integers). - - - - - Returns true if the this string is identical to the argument passed. - - - - - Compares two strings. Strings are compared as strings, so while 0 being less than 1 will - mean a comparison between two strings of the same size is the same as treating them as numbers, - in the case of two strings of differing lengths the comparison starts at the right-most (most significant) - bit, and if all bits of the shorter string are exhausted without finding a comparison, then the larger - string is deemed to be greater than the shorter (0010 is greater than 0001 but less than 00100). - - Another string to compare with this one. - A value if the two strings are identical, an integer less - than zero if this is less than the argument, and an integer greater - than zero otherwise. - - - - Compares the string with another object. - - The object to compare with. - If the object is null then this string is considered greater. If the object is another BitString - then they are compared as in the explicit comparison for BitStrings - in any other case a is thrown. - - - - Compares this BitString with an object for equality. - - - - - Returns a code for use in hashing operations. - - - - - Returns a string representation of the BitString. - - - A string which can contain a letter and optionally a number which sets a minimum size for the string - returned. In each case using the lower-case form of the letter will result in a lower-case string - being returned. - - - B - A string of 1s and 0s. - - - X - An hexadecimal string (will result in an error unless the string's length is divisible by 4). - - - G - A string of 1s and 0s in single-quotes preceded by 'B' (Postgres bit string literal syntax). - - Y - An hexadecimal string in single-quotes preceded by 'X' (Postgres bit literal syntax, will result in an error unless the string's length is divisible by 4. - - C - The format produced by format-string "Y" if legal, otherwise that produced by format-string "G". - E - The most compact safe representation for Postgres. If single bit will be either a 0 or a 1. Otherwise if it - can be that produce by format string "Y" it will, otherwise if there are less than 9bits in length it will be that - produced by format-string "G". For longer strings that cannot be represented in hexadecimal it will be a string - representing the first part of the string in format "Y" followed by the PostgreSQL concatenation operator, followed - by the final bits in the format "G". E.g. "X'13DCE'||B'110'" - If format is empty or null, it is treated as if "B" had been passed (the default repreesentation, and that - generally used by PostgreSQL for display). - - The formatted string. - - - - Returns a string representation for the Bitstring - - A string containing '0' and '1' characters. - - - - Returns the same string as . formatProvider is ignored. - - - - - Parses a string to produce a BitString. Most formats that can be produced by - can be accepted, but hexadecimal - can be interpreted with the preceding X' to mark the following characters as - being hexadecimal rather than binary. - - - - - Performs a logical AND on the two operands. - - - - - Performs a logcial OR on the two operands. - - - - - Perofrms a logical EXCLUSIVE-OR on the two operands - - - - - Performs a logical NOT on the operand. - - - - - Concatenates the operands. - - - - - Left-shifts the string BitString. - - - - - Right-shifts the string BitString. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Interprets the bitstring as a series of bits in an encoded character string, - encoded according to the Encoding passed, and returns that string. - The bitstring must contain a whole number of octets(bytes) and also be - valid according to the Encoding passed. - - The to use in producing the string. - The string that was encoded in the BitString. - - - - Interprets the bitstring as a series of octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - - - - - Interprets the bitstring as a series of signed octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - This method is not CLS-Compliant and may not be available to languages that cannot - handle signed bytes. - - - - - Interprets the bitstring as a series of unsigned 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - - - - - Interprets the bitstring as a series of unsigned 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - - - - - Interprets the bitstring as a series of unsigned 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - - - - - The length of the string. - - - - - Retrieves the value of the bit at the given index. - - - - - Represents the PostgreSQL interval datatype. - PostgreSQL differs from .NET in how it's interval type doesn't assume 24 hours in a day - (to deal with 23- and 25-hour days caused by daylight savings adjustments) and has a concept - of months that doesn't exist in .NET's class. (Neither datatype - has any concessions for leap-seconds). - For most uses just casting to and from TimeSpan will work correctly — in particular, - the results of subtracting one or the PostgreSQL date, time and - timestamp types from another should be the same whether you do so in .NET or PostgreSQL — - but if the handling of days and months in PostgreSQL is important to your application then you - should use this class instead of . - If you don't know whether these differences are important to your application, they - probably arent! Just use and do not use this class directly ☺ - To avoid forcing unnecessary provider-specific concerns on users who need not be concerned - with them a call to on a field containing an - value will return a rather than an - . If you need the extra functionality of - then use . - - - - - - - - - - Represents the number of ticks (100ns periods) in one microsecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one millisecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one second. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one minute. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one hour. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one day. This field is constant. - - - - - Represents the number of hours in one day (assuming no daylight savings adjustments). This field is constant. - - - - - Represents the number of days assumed in one month if month justification or unjustifcation is performed. - This is set to 30 for consistency with PostgreSQL. Note that this is means that month adjustments cause - a year to be taken as 30 × 12 = 360 rather than 356/366 days. - - - - - Represents the number of ticks (100ns periods) in one day, assuming 30 days per month. - - - - - Represents the number of months in a year. This field is constant. - - - - - Represents the maximum . This field is read-only. - - - - - Represents the minimum . This field is read-only. - - - - - Represents the zero . This field is read-only. - - - - - Initializes a new to the specified number of ticks. - - A time period expressed in 100ns units. - - - - Initializes a new to hold the same time as a - - A time period expressed in a - - - - Initializes a new to the specified number of months, days - & ticks. - - Number of months. - Number of days. - Number of 100ns units. - - - - Initializes a new to the specified number of - days, hours, minutes & seconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - - - - Initializes a new to the specified number of - days, hours, minutes, seconds & milliseconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - months, days, hours, minutes, seconds & milliseconds. - - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - years, months, days, hours, minutes, seconds & milliseconds. - Years are calculated exactly equivalent to 12 months. - - Number of years. - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Creates an from a number of ticks. - - The number of ticks (100ns units) in the interval. - A d with the given number of ticks. - - - - Creates an from a number of microseconds. - - The number of microseconds in the interval. - A d with the given number of microseconds. - - - - Creates an from a number of milliseconds. - - The number of milliseconds in the interval. - A d with the given number of milliseconds. - - - - Creates an from a number of seconds. - - The number of seconds in the interval. - A d with the given number of seconds. - - - - Creates an from a number of minutes. - - The number of minutes in the interval. - A d with the given number of minutes. - - - - Creates an from a number of hours. - - The number of hours in the interval. - A d with the given number of hours. - - - - Creates an from a number of days. - - The number of days in the interval. - A d with the given number of days. - - - - Creates an from a number of months. - - The number of months in the interval. - A d with the given number of months. - - - - Adds another interval to this instance and returns the result. - - An to add to this instance. - An whose values are the sums of the two instances. - - - - Subtracts another interval from this instance and returns the result. - - An to subtract from this instance. - An whose values are the differences of the two instances. - - - - Returns an whose value is the negated value of this instance. - - An whose value is the negated value of this instance. - - - - This absolute value of this instance. In the case of some, but not all, components being negative, - the rules used for justification are used to determine if the instance is positive or negative. - - An whose value is the absolute value of this instance. - - - - Equivalent to PostgreSQL's justify_days function. - - An based on this one, but with any hours outside of the range [-23, 23] - converted into days. - - - - Opposite to PostgreSQL's justify_days function. - - An based on this one, but with any days converted to multiples of ±24hours. - - - - Equivalent to PostgreSQL's justify_months function. - - An based on this one, but with any days outside of the range [-30, 30] - converted into months. - - - - Opposite to PostgreSQL's justify_months function. - - An based on this one, but with any months converted to multiples of ±30days. - - - - Equivalent to PostgreSQL's justify_interval function. - - An based on this one, - but with any months converted to multiples of ±30days - and then with any days converted to multiples of ±24hours - - - - Opposite to PostgreSQL's justify_interval function. - - An based on this one, but with any months converted to multiples of ±30days and then any days converted to multiples of ±24hours; - - - - Produces a canonical NpgslInterval with 0 months and hours in the range of [-23, 23]. - - - While the fact that for many purposes, two different instances could be considered - equivalent (e.g. one with 2days, 3hours and one with 1day 27hours) there are different possible canonical forms. - - E.g. we could move all excess hours into days and all excess days into months and have the most readable form, - or we could move everything into the ticks and have the form that allows for the easiest arithmetic) the form - chosen has two important properties that make it the best choice. - First, it is closest two how - objects are most often represented. Second, it is compatible with results of many - PostgreSQL functions, particularly with age() and the results of subtracting one date, time or timestamp from - another. - - Note that the results of casting a to is - canonicalised. - - - An based on this one, but with months converted to multiples of ±30days and with any hours outside of the range [-23, 23] - converted into days. - - - - Implicit cast of a to an - - A - An eqivalent, canonical, . - - - - Implicit cast of an to a . - - A . - An equivalent . - - - - Returns true if another is exactly the same as this instance. - - An for comparison. - true if the two instances are exactly the same, - false otherwise. - - - - Returns true if another object is an , that is exactly the same as - this instance - - An for comparison. - true if the argument is an and is exactly the same - as this one, false otherwise. - - - - Compares two instances. - - The first . - The second . - 0 if the two are equal or equivalent. A value greater than zero if x is greater than y, - a value less than zero if x is less than y. - - - - A hash code suitable for uses with hashing algorithms. - - An signed integer. - - - - Compares this instance with another/ - - An to compare this with. - 0 if the instances are equal or equivalent. A value less than zero if - this instance is less than the argument. A value greater than zero if this instance - is greater than the instance. - - - - Compares this instance with another/ - - An object to compare this with. - 0 if the argument is an and the instances are equal or equivalent. - A value less than zero if the argument is an and - this instance is less than the argument. - A value greater than zero if the argument is an and this instance - is greater than the instance. - A value greater than zero if the argument is null. - The argument is not an . - - - - Parses a and returns a instance. - Designed to use the formats generally returned by PostgreSQL. - - The to parse. - An represented by the argument. - The string was null. - A value obtained from parsing the string exceeded the values allowed for the relevant component. - The string was not in a format that could be parsed to produce an . - - - - Attempt to parse a to produce an . - - The to parse. - (out) The produced, or if the parsing failed. - true if the parsing succeeded, false otherwise. - - - - Create a representation of the instance. - The format returned is of the form: - [M mon[s]] [d day[s]] [HH:mm:ss[.f[f[f[f[f[f[f[f[f]]]]]]]]]] - A zero is represented as 00:00:00 - - Ticks are 100ns, Postgress resolution is only to 1µs at most. Hence we lose 1 or more decimal - precision in storing values in the database. Despite this, this method will output that extra - digit of precision. It's forward-compatible with any future increases in resolution up to 100ns, - and also makes this ToString() more applicable to any other use-case. - - - The representation. - - - - Adds two together. - - The first to add. - The second to add. - An whose values are the sum of the arguments. - - - - Subtracts one from another. - - The to subtract the other from. - The to subtract from the other. - An whose values are the difference of the arguments - - - - Returns true if two are exactly the same. - - The first to compare. - The second to compare. - true if the two arguments are exactly the same, false otherwise. - - - - Returns false if two are exactly the same. - - The first to compare. - The second to compare. - false if the two arguments are exactly the same, true otherwise. - - - - Compares two instances to see if the first is less than the second - - The first to compare. - The second to compare. - true if the first is less than second, false otherwise. - - - - Compares two instances to see if the first is less than or equivalent to the second - - The first to compare. - The second to compare. - true if the first is less than or equivalent to second, false otherwise. - - - - Compares two instances to see if the first is greater than the second - - The first to compare. - The second to compare. - true if the first is greater than second, false otherwise. - - - - Compares two instances to see if the first is greater than or equivalent the second - - The first to compare. - The second to compare. - true if the first is greater than or equivalent to the second, false otherwise. - - - - Returns the instance. - - An . - The argument. - - - - Negates an instance. - - An . - The negation of the argument. - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. This ignores the number of days and - months held. If you want them included use first. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - interval(0) - resolution of 1s (1 second) - - - interval(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - interval(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - interval(3) - resolution of 1ms = 0.001s (1 millisecond) - - - interval(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - interval(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - interval(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL interval will - not suffice for those purposes. - In more frequent cases though, the resolution of the interval suffices. - will always suffice to handle the resolution of any interval value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An in the range [-999999, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An in the range [-999, 999]. - - - - - Gets the number of whole seconds held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole minutes held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that this can be less than -23 or greater than 23 unless - has been used to produce this instance. - - - - - Gets the number of days held in the instance. - Note that this does not pay attention to a time component with -24 or less hours or - 24 or more hours, unless has been called to produce this instance. - - - - - Gets the number of months held in the instance. - Note that this does not pay attention to a day component with -30 or less days or - 30 or more days, unless has been called to produce this instance. - - - - - Returns a representing the time component of the instance. - Note that this may have a value beyond the range ±23:59:59.9999999 unless - has been called to produce this instance. - - - - - The total number of ticks (100ns units) in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of microseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of milliseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of seconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of minutes in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of hours in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of days in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of months in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - time(0) - resolution of 1s (1 second) - - - time(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - time(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - time(3) - resolution of 1ms = 0.001s (1 millisecond) - - - time(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - time(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - time(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL time will - not suffice for those purposes. - In more frequent cases though, the resolution of time suffices. - will always suffice to handle the resolution of any time value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - Compares this with another . As per postgres' rules, - first the times are compared as if they were both in the same timezone. If they are equal then - then timezones are compared (+01:00 being "smaller" than -01:00). - - the to compare with. - An integer which is 0 if they are equal, < 0 if this is the smaller and > 0 if this is the larger. - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - This class implements the Fastpath api. - - - - - This maps the functions names to their id's (possible unique just - to a connection). - - - - - Our connection. - - - - - The network stream. - - - - - Initialises the fastpath system. - - BaseConnection to attach to. - The network stream to the backend. - - - - Initialises the fastpath system. - - BaseConnection to attach to. - - - - Send a function call to the PostgreSQL backend. - - Function id. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - Send a function call to the PostgreSQL backend by name. - Note: the mapping for the procedure name to function id needs to exist, - usually to an earlier call to addfunction(). - This is the prefered method to call, as function id's can/may change - between versions of the backend. - For an example of how this works, refer to NpgsqlTypes.LargeObject - - Function name. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Integer result. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Array containing result - - - - This adds a function to our lookup table. - User code should use the addFunctions method, which is based upon a - query, rather than hard coding the oid. The oid for a function is not - guaranteed to remain static, even on different servers of the same - version. - - Function name. - Function id. - - - - This takes a ResultSet containing two columns. Column 1 contains the - function name, Column 2 the oid. - It reads the entire ResultSet, loading the values into the function - table. - REMEMBER to close() the resultset after calling this!! - Implementation note about function name lookups: - PostgreSQL stores the function id's and their corresponding names in - the pg_proc table. To speed things up locally, instead of querying each - function from that table when required, a Dictionary is used. Also, only - the function's required are entered into this table, keeping connection - times as fast as possible. - The org.postgresql.largeobject.LargeObject class performs a query upon it's startup, - and passes the returned ResultSet to the addFunctions() method here. - Once this has been done, the LargeObject api refers to the functions by - name. - Dont think that manually converting them to the oid's will work. Ok, - they will for now, but they can change during development (there was some - discussion about this for V7.0), so this is implemented to prevent any - unwarranted headaches in the future. - - ResultSet - - - - This returns the function id associated by its name - If addFunction() or addFunctions() have not been called for this name, - then an NpgsqlException is thrown. - - Function name to lookup. - Function ID for fastpath call. - - - - Fast Path Arg. - - - - - Type of argument, true=integer, false=byte[]. - - - - - Integer value if type=true. - - - - - Byte value if type=false; - - - - - Constructs an argument that consists of an integer value. - - Int value to set. - - - - Constructs an argument that consists of an array of bytes. - - Array to store. - - - - Constructs an argument that consists of part of a byte array. - - Source array. - offset within array. - length of data to include. - - - - Constructs an argument that consists of a String. - - String to store. - - - - This sends this argument down the network stream. - The stream sent consists of the length.int4 then the contents. - Note: This is called from Fastpath, and cannot be called from - client code. - - - - - - Report send size. - - Send size. - - - - Large Object. - - - - - Indicates a seek from the begining of a file. - - - - - Indicates a seek from the current position. - - - - - Indicates a seek from the end of a file. - - - - - This opens a large object. - If the object does not exist, then an NpgsqlException is thrown. - - FastPath API for the connection to use. - OID of the Large Object to open. - Mode of opening the large object - - - - OID getter. - - The OID of this LargeObject. - - - - This method closes the object. You must not call methods in this - object after this is called. - - - - - Reads some data from the object, and return as a byte[] array. - - Number of bytes to read. - Array containing data read. - - - - Reads some data from the object into an existing array. - - Destination array. - Offset within array. - Maximum number of bytes to read. - The number of bytes actually read. - - - - Writes an array to the object. - - Array to write. - - - - Writes some data from an array to the object. - - Destination array. - Offset within array. - Number of bytes to write. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object. - Either SEEK_SET, SEEK_CUR or SEEK_END. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object from begining. - - - - Report the current position within the object. - - The current position within the object. - - - - This method is inefficient, as the only way to find out the size of - the object is to seek to the end, record the current position, then - return to the original position. - A better method will be found in the future. - - The size of the large object. - - - - OID. - - - - - Large Object Manager. - - - - - This mode indicates we want to write to an object - - - - - This mode indicates we want to read an object - - - - - This mode is the default. It indicates we want read and write access to - - - - - Constructs the LargeObject API. - There should only be one LargeObjectManager per Connection. The - org.postgresql.Connection class keeps track of the various extension API's - and it's advised you use those to gain access, and not going direct. - - - - - - This opens an existing large object, based on its OID. This method - assumes that READ and WRITE access is required (the default). - - OID of large object. - LargeObject instance providing access to the object - - - - This opens an existing large object, based on its OID. - - OID of large object. - Mode of open. - - - - - This creates a large object, returning its OID. - - OID of new object. - - - - This creates a large object, returning its OID. - - Bitmask describing different attributes of the new object. - OID of new object. - - - - This deletes a large object. - - OID describing object to delete. - - - - This deletes a large object. - It is identical to the Delete() method, and is supplied as the C API uses unlink. - - OID describing object to delete. - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - Clone the current object. - - A new NativeToBackendTypeConverterOptions object. - - - - Clone the current object with a different OID/Name mapping. - - OID/Name mapping object to use in the new instance. - A new NativeToBackendTypeConverterOptions object. - - - - Provide event handlers to convert all native supported basic data types from their backend - text representation to a .NET object. - - - - - Convert UTF8 encoded text a string. - - - - - Byte array from bytea encoded as ASCII text, escaped or hex format. - - - - - Byte array from bytea encoded as binary. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql bit to a System.Boolean. - - - - - Convert a postgresql datetime to a System.DateTime. - - - - - Convert a postgresql date to a System.DateTime. - - - - - Convert a postgresql time to a System.DateTime. - - - - - Convert a postgresql money to a System.Decimal. - - - - - Convert a postgresql float4 or float8 to a System.Float or System.Double respectively. - - - - - Provide event handlers to convert extended native supported data types from their backend - text representation to a .NET object. - - - - - Convert a postgresql point to a System.NpgsqlPoint. - - - - - Convert a postgresql point to a System.RectangleF. - - - - - LDeg. - - - - - Path. - - - - - Polygon. - - - - - Circle. - - - - - Inet. - - - - - MAC Address. - - - - - interval - - - - - Provide event handlers to convert the basic native supported data types from - native form to backend representation. - - - - - Convert a string to UTF8 encoded text, escaped and quoted as required. - - - - - Convert a string to UTF8 encoded text. - - - - - Binary data, escaped and quoted as required. - - - - - Binary data with possible older style octal escapes, quoted. - - - - - Binary data in the new hex format (>= 9.0), quoted. - - - - - Binary data, raw. - - - - - Convert to a postgresql boolean text format. - - - - - Convert to a postgresql boolean binary format. - - - - - Convert to a postgresql binary int2. - - - - - Convert to a postgresql binary int4. - - - - - Convert to a postgresql binary int8. - - - - - Convert to a postgresql bit. - - - - - Convert to a postgresql timestamp. - - - - - Convert to a postgresql date. - - - - - Convert to a postgresql time. - - - - - Convert to a postgres money. - - - - - Convert to a postgres double with maximum precision. - - - - - Convert a System.Float to a postgres float4. - - - - - Convert a System.Double to a postgres float8. - - - - - Provide event handlers to convert extended native supported data types from - native form to backend representation. - - - - - Point. - - - - - Box. - - - - - LSeg. - - - - - Open path. - - - - - Polygon. - - - - - Convert to a postgres MAC Address. - - - - - Circle. - - - - - Convert to a postgres inet. - - - - - Convert to a postgres interval - - - - - Delegate called to convert the given backend text data to its native representation. - - - - - Delegate called to convert the given backend binary data to its native representation. - - - - - Represents a backend data type. - This class can be called upon to convert a backend field representation to a native object. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - fieldValueSize - Type modifier field sent from the backend. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - TypeSize - Type modifier field sent from the backend. - - - - Type OID provided by the backend server. - - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - NpgsqlDbType. - - - - - Provider type to convert fields of this type to. - - - - - System type to convert fields of this type to. - - - - - Reports whether a backend binary to native decoder is available for this type. - - - - - Delegate called to convert the given native data to its backand representation. - - - - - Represents a backend data type. - This class can be called upon to convert a native object to its backend field representation, - - - - - Returns an NpgsqlNativeTypeInfo for an array where the elements are of the type - described by the NpgsqlNativeTypeInfo supplied. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type name provided by the backend server. - DbType - Quote - NpgsqlDbType - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended queries). - - - - Perform a data conversion from a native object to - a backend representation. - DBNull and null values are handled differently depending if a plain query is used - When - - Native .NET object to be converted. - Specifies that the value should be formatted for the extended query syntax. - Options to guide serialization. If null, a default options set is used. - Specifies that the value should be formatted as an extended query array element. - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - DbType. - - - - - Apply quoting. - - - - - Use parameter size information. - - - - - Reports whether a native to backend binary encoder is available for this type. - - - - - Provide mapping between type OID, type name, and a NpgsqlBackendTypeInfo object that represents it. - - - - - Construct an empty mapping. - - - - - Copy constuctor. - - - - - Add the given NpgsqlBackendTypeInfo to this mapping. - - - - - Add a new NpgsqlBackendTypeInfo with the given attributes and conversion handlers to this mapping. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Make a shallow copy of this type mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type OID exists in this mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type OID, or null if none found. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type name, or null if none found. - - - - - Provide mapping between type Type, NpgsqlDbType and a NpgsqlNativeTypeInfo object that represents it. - - - - - Add the given NpgsqlNativeTypeInfo to this mapping. - - - - - Add a new NpgsqlNativeTypeInfo with the given attributes and conversion handlers to this mapping. - - Type name provided by the backend server. - NpgsqlDbType - DbType - Quote - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended query). - - - - Retrieve the NpgsqlNativeTypeInfo with the given NpgsqlDbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given DbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given Type. - - - - - Determine if a NpgsqlNativeTypeInfo with the given backend type name exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given NpgsqlDbType exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given Type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Represents a PostgreSQL Point type - - - - - Represents a PostgreSQL Line Segment type. - - - - - Represents a PostgreSQL Path type. - - - - - Represents a PostgreSQL Polygon type. - - - - - Represents a PostgreSQL Circle type. - - - - - Represents a PostgreSQL inet type. - - - - - Represents a PostgreSQL MacAddress type. - - - - - - - The macAddr parameter must contain a string that can only consist of numbers - and upper-case letters as hexadecimal digits. (See PhysicalAddress.Parse method on MSDN) - - - - This class contains helper methods for type conversion between - the .Net type system and postgresql. - - - - - A cache of basic datatype mappings keyed by server version. This way we don't - have to load the basic type mappings for every connection. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given DbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given System.Type. - - - - - This method is responsible to convert the byte[] received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - This method is responsible to convert the string received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - Create the one and only native to backend type map. - This map is used when formatting native data - types to backend representations. - - - - - This method creates (or retrieves from cache) a mapping between type and OID - of all natively supported postgresql data types. - This is needed as from one version to another, this mapping can be changed and - so we avoid hardcoding them. - - NpgsqlTypeMapping containing all known data types. The mapping must be - cloned before it is modified because it is cached; changes made by one connection may - effect another connection. - - - - - Attempt to map types by issuing a query against pg_type. - This function takes a list of NpgsqlTypeInfo and attempts to resolve the OID field - of each by querying pg_type. If the mapping is found, the type info object is - updated (OID) and added to the provided NpgsqlTypeMapping object. - - NpgsqlConnector to send query through. - Mapping object to add types too. - List of types that need to have OID's mapped. - - - - Summary description for NpgsqlQuery - - - - - For classes representing messages sent from the client to the server. - - - - - Set Cache Size. The default value is 20. - - - - - Lookup cached entity. null will returned if not match. - For both get{} and set{} apply LRU rule. - - key - - - - - The globally available text encoding used for frontend/backend communication. - - - - This class represents the base class for the state pattern design pattern - implementation. - - - This class represents the base class for the state pattern design pattern - implementation. - - - - - - This method is used by the states to change the state of the context. - - - - - Call ProcessBackendResponsesEnum(), and scan and discard all results. - - - - - This method is responsible to handle all protocol messages sent from the backend. - It holds all the logic to do it. - To exchange data, it uses a Mediator object from which it reads/writes information - to handle backend requests. - - - - - - Checks for context socket availability. - Socket.Poll supports integer as microseconds parameter. - This limits the usable command timeout value - to 2,147 seconds: (2,147 x 1,000,000 less than max_int). - In order to bypass this limit, the availability of - the socket is checked in 2,147 seconds cycles - - true, if for context socket availability was checked, false otherwise. - Context. - Select mode. - - - - Called from constructor of derived class. - - - - - Finalizer for HashAlgorithm - - - - - Computes the entire hash of all the bytes in the byte array. - - - - - When overridden in a derived class, drives the hashing function. - - - - - - - - When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created. - - - - - When overridden in a derived class, initializes the object to prepare for hashing. - - - - - Used for stream chaining. Computes hash as data passes through it. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - The buffer to write the copied data to. - At what point in the outputBuffer to write the data at. - - - - Used for stream chaining. Computes hash as data passes through it. Finishes off the hash. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - - - - Get whether or not the hash can transform multiple blocks at a time. - Note: MUST be overriden if descendant can transform multiple block - on a single call! - - - - - Gets the previously computed hash. - - - - - Returns the size in bits of the hash. - - - - - Must be overriden if not 1 - - - - - Must be overriden if not 1 - - - - - Common base class for all derived MD5 implementations. - - - - - Called from constructor of derived class. - - - - - Creates the default derived class. - - - - - C# implementation of the MD5 cryptographic hash function. - - - - - Creates a new MD5CryptoServiceProvider. - - - - - Drives the hashing function. - - Byte array containing the data to hash. - Where in the input buffer to start. - Size in bytes of the data in the buffer to hash. - - - - This finalizes the hash. Takes the data from the chaining variables and returns it. - - - - - Resets the class after use. Called automatically after hashing is done. - - - - - This is the meat of the hash function. It is what processes each block one at a time. - - Byte array to process data from. - Where in the byte array to start processing. - - - - Pads and then processes the final block. - - Buffer to grab data from. - Position in buffer in bytes to get data from. - How much data in bytes in the buffer to use. - - - - Implements for version 3 of the protocol. - - - - - Reads a row, field by field, allowing a DataRow to be built appropriately. - - - - - Marker interface which identifies a class which may take possession of a stream for the duration of - it's lifetime (possibly temporarily giving that possession to another class for part of that time. - - It inherits from IDisposable, since any such class must make sure it leaves the stream in a valid state. - - The most important such class is that compiler-generated from ProcessBackendResponsesEnum. Of course - we can't make that inherit from this interface, alas. - - - - - Marker interface which identifies a class which represents part of - a response from the server. - - - - - Reads part of a field, as needed (for - and - - - - - Adds further functionality to stream that is dependant upon the type of data read. - - - - - Completes the implementation of Streamer for char data. - - - - - Completes the implementation of Streamer for byte data. - - - - - This class represents a BackEndKeyData message received - from PostgreSQL - - - - - This class represents the Bind message sent to PostgreSQL - server. - - - - - - This class represents the CancelRequest message sent to PostgreSQL - server. - - - - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlCommand class. - - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query. - - The text of the query. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query and a NpgsqlConnection. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query, a NpgsqlConnection, and the NpgsqlTransaction. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - The NpgsqlTransaction in which the NpgsqlCommand executes. - - - - Used to execute internal commands. - - - - - Attempts to cancel the execution of a NpgsqlCommand. - - This Method isn't implemented yet. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Creates a new instance of an DbParameter object. - - An DbParameter object. - - - - Creates a new instance of a NpgsqlParameter object. - - A NpgsqlParameter object. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Internal query shortcut for use in cases where the number - of affected rows is of no interest. - - - - - Special adaptation of ExecuteBlind() that sets statement_timeout. - This exists to prevent Connector.SetBackendCommandTimeout() from calling Command.ExecuteBlind(), - which will cause an endless recursive loop. - - - Timeout in seconds. - - - - Executes a SQL statement against the connection and returns the number of rows affected. - - The number of rows affected if known; -1 otherwise. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader. - - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - Currently the CommandBehavior parameter is ignored. - - - - This method binds the parameters from parameters collection to the bind - message. - - - - - Executes the query, and returns the first column of the first row - in the result set returned by the query. Extra columns or rows are ignored. - - The first column of the first row in the result set, - or a null reference if the result set is empty. - - - - Creates a prepared version of the command on a PostgreSQL server. - - - - - This method checks the connection state to see if the connection - is set or it is open. If one of this conditions is not met, throws - an InvalidOperationException - - - - - This method substitutes the Parameters, if exist, in the command - to their actual values. - The parameter name format is :ParameterName. - - A version of CommandText with the Parameters inserted. - - - - Process this.commandText, trimming each distinct command and substituting paramater - tokens. - - - UTF8 encoded command ready to be sent to the backend. - - - - Append a region of a source command text to an output command, performing parameter token - substitutions. - - Stream to which to append output. - Command text. - - - false if the query has multiple statements which are not allowed - - - - Gets or sets the SQL statement or function (stored procedure) to execute at the data source. - - The Transact-SQL statement or stored procedure to execute. The default is an empty string. - - - - Gets or sets the wait time before terminating the attempt - to execute a command and generating an error. - - The time (in seconds) to wait for the command to execute. - The default is 20 seconds. - - - - Gets or sets a value indicating how the - CommandText property is to be interpreted. - - One of the CommandType values. The default is CommandType.Text. - - - - DB connection. - - - - - Gets or sets the NpgsqlConnection - used by this instance of the NpgsqlCommand. - - The connection to a data source. The default value is a null reference. - - - - DB parameter collection. - - - - - Gets the NpgsqlParameterCollection. - - The parameters of the SQL statement or function (stored procedure). The default is an empty collection. - - - - DB transaction. - - - - - Gets or sets the NpgsqlTransaction - within which the NpgsqlCommand executes. - - The NpgsqlTransaction. - The default value is a null reference. - - - - Gets or sets how command results are applied to the DataRow - when used by the Update - method of the DbDataAdapter. - - One of the UpdateRowSource values. - - - - Returns oid of inserted row. This is only updated when using executenonQuery and when command inserts just a single row. If table is created without oids, this will always be 0. - - - - - Returns whether this query will execute as a prepared (compiled) query. - - - - - Design time visible. - - - - - This class is responsible to create database commands for automatic insert, update and delete operations. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The adapter. - - - - - This method is reponsible to derive the command parameter list with values obtained from function definition. - It clears the Parameters collection of command. Also, if there is any parameter type which is not supported by Npgsql, an InvalidOperationException will be thrown. - Parameters name will be parameter1, parameter2, ... - - NpgsqlCommand whose function parameters will be obtained. - - - - Gets the automatically generated object required - to perform insertions at the data source. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated object required to perform insertions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform updates at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform updates. - - - - - Gets the automatically generated object required to perform updates - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform updates. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform deletions at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform deletions. - - - - - Gets the automatically generated object required to perform deletions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform deletions. - - - - - Applies the parameter information. - - The parameter. - The row. - Type of the statement. - if set to true [where clause]. - - - - Returns the name of the specified parameter in the format of @p#. - - The number to be included as part of the parameter's name.. - - The name of the parameter with the specified number appended as part of the parameter name. - - - - - Returns the full parameter name, given the partial parameter name. - - The partial name of the parameter. - - The full parameter name corresponding to the partial parameter name requested. - - - - - Returns the placeholder for the parameter in the associated SQL statement. - - The number to be included as part of the parameter's name. - - The name of the parameter with the specified number appended. - - - - - Registers the to handle the event for a . - - The to be used for the update. - - - - Adds an event handler for the event. - - The sender - A instance containing information about the event. - - - - Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier, including properly escaping any embedded quotes in the identifier. - - The original unquoted identifier. - - The quoted version of the identifier. Embedded quotes within the identifier are properly escaped. - - - - - Unquoted identifier parameter cannot be null - - - - Given a quoted identifier, returns the correct unquoted form of that identifier, including properly un-escaping any embedded quotes in the identifier. - - The identifier that will have its embedded quotes removed. - - The unquoted identifier, with embedded quotes properly un-escaped. - - - - - Quoted identifier parameter cannot be null - - - - Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The beginning character or characters to use. The default is an empty string. - - - - - - - - Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The ending character or characters to use. The default is an empty string. - - - - - - - - Represents the method that handles the Notice events. - - The source of the event. - A NpgsqlNoticeEventArgs that contains the event data. - - - - Represents the method that handles the Notification events. - - The source of the event. - A NpgsqlNotificationEventArgs that contains the event data. - - - - This class represents a connection to a - PostgreSQL server. - - - - - Initializes a new instance of the - NpgsqlConnection class. - - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - An DbTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Begins a database transaction. - - A NpgsqlTransaction - object representing the new transaction. - - Currently there's no support for nested transactions. - - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - A NpgsqlTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Opens a database connection with the property settings specified by the - ConnectionString. - - - - - This method changes the current database by disconnecting from the actual - database and connecting to the specified. - - The name of the database to use in place of the current database. - - - - Releases the connection to the database. If the connection is pooled, it will be - made available for re-use. If it is non-pooled, the actual connection will be shutdown. - - - - - When a connection is closed within an enclosing TransactionScope and the transaction - hasn't been promoted, we defer the actual closing until the scope ends. - - - - - Creates and returns a DbCommand - object associated with the IDbConnection. - - A DbCommand object. - - - - Creates and returns a NpgsqlCommand - object associated with the NpgsqlConnection. - - A NpgsqlCommand object. - - - - Releases all resources used by the - NpgsqlConnection. - - true when called from Dispose(); - false when being called from the finalizer. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Returns a copy of the NpgsqlConnectionStringBuilder that contains the parsed connection string values. - - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - Write each key/value pair in the connection string to the log. - - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Refresh the cached _connectionString whenever the builder settings change - - - - - Returns the supported collections - - - - - Returns the schema collection specified by the collection name. - - The collection name. - The collection specified. - - - - Returns the schema collection specified by the collection name filtered by the restrictions. - - The collection name. - - The restriction values to filter the results. A description of the restrictions is contained - in the Restrictions collection. - - The collection specified. - - - - Clear connection pool. - - - - - Clear all connection pools. - - - - - Enlist transation. - - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets or sets the string used to connect to a PostgreSQL database. - Valid values are: -
    -
  • - Server: Address/Name of Postgresql Server; -
  • -
  • - Port: Port to connect to; -
  • -
  • - Protocol: Protocol version to use, instead of automatic; Integer 2 or 3; -
  • -
  • - Database: Database name. Defaults to user name if not specified; -
  • -
  • - User Id: User name; -
  • -
  • - Password: Password for clear text authentication; -
  • -
  • - SSL: True or False. Controls whether to attempt a secure connection. Default = False; -
  • -
  • - Pooling: True or False. Controls whether connection pooling is used. Default = True; -
  • -
  • - MinPoolSize: Min size of connection pool; -
  • -
  • - MaxPoolSize: Max size of connection pool; -
  • -
  • - Timeout: Time to wait for connection open in seconds. Default is 15. -
  • -
  • - CommandTimeout: Time to wait for command to finish execution before throw an exception. In seconds. Default is 20. -
  • -
  • - Sslmode: Mode for ssl connection control. Can be Prefer, Require, Allow or Disable. Default is Disable. Check user manual for explanation of values. -
  • -
  • - ConnectionLifeTime: Time to wait before closing unused connections in the pool in seconds. Default is 15. -
  • -
  • - SyncNotification: Specifies if Npgsql should use synchronous notifications. -
  • -
  • - SearchPath: Changes search path to specified and public schemas. -
  • -
-
- The connection string that includes the server name, - the database name, and other parameters needed to establish - the initial connection. The default value is an empty string. - -
- - - Backend server host name. - - - - - Backend server port. - - - - - If true, the connection will attempt to use SSL. - - - - - Gets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets the name of the current database or the database to be used after a connection is opened. - - The name of the current database or the name of the database to be - used after a connection is opened. The default value is the empty string. - - - - Whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Gets the database server name. - - - - - Gets flag indicating if we are using Synchronous notification or not. - The default value is false. - - - - - Gets the current state of the connection. - - A bitwise combination of the ConnectionState values. The default is Closed. - - - - Gets whether the current state of the connection is Open or Closed - - ConnectionState.Open or ConnectionState.Closed - - - - Compatibility version. - - - - - Version of the PostgreSQL backend. - This can only be called when there is an active connection. - - - - - PostgreSQL server version. - - - - - Protocol version in use. - This can only be called when there is an active connection. - Always retuna Version3 - - - - - Process id of backend server. - This can only be called when there is an active connection. - - - - - Report whether the backend is expecting standard conformant strings. - In version 8.1, Postgres began reporting this value (false), but did not actually support standard conformant strings. - In version 8.2, Postgres began supporting standard conformant strings, but defaulted this flag to false. - As of version 9.1, this flag defaults to true. - - - - - Report whether the backend understands the string literal E prefix (>= 8.1). - - - - - Report whether the backend understands the hex byte format (>= 9.0). - - - - - The connector object connected to the backend. - - - - - Gets the NpgsqlConnectionStringBuilder containing the parsed connection string values. - - - - - User name. - - - - - Use extended types. - - - - - Password. - - - - - Determine if connection pooling will be used for this connection. - - - - - Return an exact copy of this NpgsqlConnectionString. - - - - - No integrated security if we're on mono and .NET 4.5 because of ClaimsIdentity, - see https://github.com/npgsql/Npgsql/issues/133 - - - - - This function will set value for known key, both private member and base[key]. - - - - - value, coerced as needed to the stored type. - - - - The function will modify private member only, not base[key]. - - - - value, coerced as needed to the stored type. - - - - The function will access private member only, not base[key]. - - - value. - - - - Clear the member and assign them to the default value. - - - - - Gets or sets the backend server host name. - - - - - Gets or sets the backend server port. - - - - - Gets or sets the name of the database to be used after a connection is opened. - - The name of the database to be - used after a connection is opened. - - - - Gets or sets the login user name. - - - - - Gets or sets the login password as a UTF8 encoded byte array. - - - - - Sets the login password as a string. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets or sets the schema search path. - - - - - Gets or sets a value indicating whether connection pooling should be used. - - - - - Gets or sets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets or sets the minimum connection pool size. - - - - - Gets or sets the maximum connection pool size. - - - - - Gets or sets a value indicating whether to listen for notifications and report them between command activity. - - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets or sets a value indicating whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Compatibilty version. When possible, behaviour caused by breaking changes will be preserved - if this version is less than that where the breaking change was introduced. - - - - - Gets or sets the ootional application name parameter to be sent to the backend during connection initiation. - - - - - Gets or sets a value indicating whether to silently Prepare() all commands before execution. - - - - - Gets or sets the specified backend communication protocol version. - - - - - Gets the backend encoding. Always returns "UTF8". - - - - - Case insensative accessor for indivual connection string values. - - - - - Set both ImplicitDefault and ExplicitDefault to the 's default value. - - - - - - - - Set ImplicitDefault to the default value of 's type, - and ExplicitDefault to . - - - - - - - - Represents the method that allows the application to provide a certificate collection to be used for SSL clien authentication - - A X509CertificateCollection to be filled with one or more client certificates. - - - - Represents the method that is called to validate the certificate provided by the server during an SSL handshake - - The server's certificate - The certificate chain containing the certificate's CA and any intermediate authorities - Any errors that were detected - - - - !!! Helper class, for compilation only. - Connector implements the logic for the Connection Objects to - access the physical connection to the database, and isolate - the application developer from connection pooling internals. - - - - - Constructor. - - Connection string. - Pooled - Controls whether the connector can be shared. - - - - This method checks if the connector is still ok. - We try to send a simple query text, select 1 as ConnectionTest; - - - - - This method is responsible for releasing all resources associated with this Connector. - - - - - This method is responsible to release all portals used by this Connector. - - - - - Modify the backend statement_timeout value if needed. - - New timeout - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - This method is required to set all the version dependent features flags. - SupportsPrepare means the server can use prepared query plans (7.3+) - - - - - Opens the physical connection to the server. - - Usually called by the RequestConnector - Method of the connection pool manager. - - - - Closes the physical connection to the server. - - - - - Returns next portal index. - - - - - Returns next plan index. - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets the current state of the connection. - - - - - Return Connection String. - - - - - Version of backend server this connector is connected to. - - - - - The physical connection socket to the backend. - - - - - The physical connection stream to the backend. - - - - - The top level stream to the backend. - - - - - Reports if this connector is fully connected. - - - - - The connection mediator. - - - - - Report if the connection is in a transaction. - - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - This class manages all connector objects, pooled AND non-pooled. - - - - Unique static instance of the connector pool - mamager. - - - Map of index to unused pooled connectors, avaliable to the - next RequestConnector() call. - This hashmap will be indexed by connection string. - This key will hold a list of queues of pooled connectors available to be used. - - - Timer for tracking unused connections in pools. - - - - Searches the shared and pooled connector lists for a - matching connector object or creates a new one. - - The NpgsqlConnection that is requesting - the connector. Its ConnectionString will be used to search the - pool for available connectors. - A connector object. - - - - Find a pooled connector. Handle shared/non-shared here. - - - - - Releases a connector, possibly back to the pool for future use. - - - Pooled connectors will be put back into the pool if there is room. - Shared connectors should just have their use count decremented - since they always stay in the shared pool. - - Connection to which the connector is leased. - The connector to release. - - - - Release a pooled connector. Handle shared/non-shared here. - - - - - Find an available pooled connector in the non-shared pool, or create - a new one if none found. - - - - - Put a pooled connector into the pool queue. - - Connection is leased to. - Connector to pool - - - - A queue with an extra Int32 for keeping track of busy connections. - - - - - Connections available to the end user - - - - - Connections currently in use - - - - - Represents information about COPY operation data transfer format as returned by server. - - - - - Only created when a CopyInResponse or CopyOutResponse is received by NpgsqlState.ProcessBackendResponses() - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Represents a PostgreSQL COPY FROM STDIN operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to read data from (if provided by user) - or for writing it (when generated by driver). - Eg. new NpgsqlCopyIn("COPY mytable FROM STDIN", connection, streamToRead).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is run upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is executed upon Start() and all data from fromStream is passed to it as copy data. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, it will be flushed to server as copy data, and operation will be finished immediately. - Otherwise the CopyStream member can be used for writing copy data to server and operation finished with a call to End() or Cancel(). - - - - - Called after writing all data to CopyStream to successfully complete this copy operation. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Will do nothing if current operation is not active. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start(). - User may provide a stream to constructor; it is used to pass to server all data read from it. - Otherwise, call to Start() sets this to a writable NpgsqlCopyInStream that passes all data written to it to server. - In latter case this is only available while the copy operation is active and null otherwise. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields expected on each input row if this operation is currently active, otherwise -1 - - - - - The Command used to execute this copy operation. - - - - - Set before a COPY IN query to define size of internal buffer for reading from given CopyStream. - - - - - Represents an ongoing COPY FROM STDIN operation. - Provides methods to push data to server and end or cancel the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyInResponse. - If CopyStream is already set, it is used to read data to push to server, after which the copy is completed. - Otherwise CopyStream is set to a writable NpgsqlCopyInStream that calls SendCopyData each time it is written to. - - - - - Sends given packet to server as a CopyData message. - Does not check for notifications! Use another thread for that. - - - - - Sends CopyDone message to server. Handles responses, ie. may throw an exception. - - - - - Sends CopyFail message to server. Handles responses, ie. should always throw an exception: - in CopyIn state the server responds to CopyFail with an error response; - outside of a CopyIn state the server responds to CopyFail with an error response; - without network connection or whatever, there's going to eventually be a failure, timeout or user intervention. - - - - - Copy format information returned from server. - - - - - Stream for writing data to a table on a PostgreSQL version 7.4 or newer database during an active COPY FROM STDIN operation. - Passes data exactly as is and when given, so see to it that you use server encoding, correct format and reasonably sized writes! - - - - - Created only by NpgsqlCopyInState.StartCopy() - - - - - Successfully completes copying data to server. Returns after operation is finished. - Does nothing if this stream is not the active copy operation writer. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Does nothing if this stream is not the active copy operation writer. - - - - - Writes given bytes to server. - Fails if this stream is not the active copy operation writer. - - - - - Flushes stream contents to server. - Fails if this stream is not the active copy operation writer. - - - - - Not readable - - - - - Not seekable - - - - - Not supported - - - - - True while this stream can be used to write copy data to server - - - - - False - - - - - True - - - - - False - - - - - Number of bytes written so far - - - - - Number of bytes written so far; not settable - - - - - Represents a PostgreSQL COPY TO STDOUT operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to write results to (if provided by user) - or for reading the results (when generated by driver). - Eg. new NpgsqlCopyOut("COPY (SELECT * FROM mytable) TO STDOUT", connection, streamToWrite).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is run upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is executed upon Start() and all requested copy data is written to toStream immediately. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, all copy data from server will be written to it, and operation will be finished immediately. - Otherwise the CopyStream member can be used for reading copy data from server until no more data is available. - - - - - Flush generated CopyStream at once. Effectively reads and discard all the rest of copy data from server. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start() - - - - - The Command used to execute this copy operation. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Faster alternative to using the generated CopyStream. - - - - - Represents an ongoing COPY TO STDOUT operation. - Provides methods to read data from server or end the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyOutResponse. - If CopyStream is already set, it is used to write data received from server, after which the copy ends. - Otherwise CopyStream is set to a readable NpgsqlCopyOutStream that receives data from server. - - - - - Called from NpgsqlOutStream.Read to read copy data from server. - - - - - Copy format information returned from server. - - - - - Stream for reading data from a table or select on a PostgreSQL version 7.4 or newer database during an active COPY TO STDOUT operation. - Passes data exactly as provided by the server. - - - - - Created only by NpgsqlCopyOutState.StartCopy() - - - - - Discards copy data as long as server pushes it. Returns after operation is finished. - Does nothing if this stream is not the active copy operation reader. - - - - - Not writable. - - - - - Not flushable. - - - - - Copies data read from server to given byte buffer. - Since server returns data row by row, length will differ each time, but it is only zero once the operation ends. - Can be mixed with calls to the more efficient NpgsqlCopyOutStream.Read() : byte[] though that would not make much sense. - - - - - Not seekable - - - - - Not supported - - - - - Returns a whole row of data from server without extra work. - If standard Stream.Read(...) has been called before, it's internal buffers remains are returned. - - - - - True while this stream can be used to read copy data from server - - - - - True - - - - - False - - - - - False - - - - - Number of bytes read so far - - - - - Number of bytes read so far; can not be set. - - - - - Writes given objects into a stream for PostgreSQL COPY in default copy format (not CSV or BINARY). - - - - - Default delimiter. - - - - - Default separator. - - - - - Default null. - - - - - Default escape. - - - - - Default quote. - - - - - Default buffer size. - - - - - Constructor. - - - - - - Flush buffers. - - - - - Flush rows. - - - - - Flush fields. - - - - - Close the serializer. - - - - - Escape sequence for the given character. - - - - - - - Make room for bytes. - - - - - - Add bytes. - - - - - - End row. - - - - - Prefix field. - - - - - Field added. - - - - - Add null. - - - - - Add string. - - - - - - add Int32. - - - - - - Add Int64. - - - - - - Add number. - - - - - - Add bool - - - - - - Add DateTime. - - - - - - Report whether the serializer is active. - - - - - To Stream. - - - - - Delimiter. - - - - - Separator. - - - - - Escape. - - - - - Null. - - - - - Buffer size. - - - - - Report whether space remains in the buffer. - - - - - Strings to escape. - - - - - Escape sequence bytes. - - - - - Represents the method that handles the RowUpdated events. - - The source of the event. - A NpgsqlRowUpdatedEventArgs that contains the event data. - - - - Represents the method that handles the RowUpdating events. - - The source of the event. - A NpgsqlRowUpdatingEventArgs that contains the event data. - - - - This class represents an adapter from many commands: select, update, insert and delete to fill Datasets. - - - - - Default constructor. - - - - - Constructor. - - - - - - Constructor. - - - - - - - Constructor. - - - - - - - Create row updated event. - - - - - - - - - - Create row updating event. - - - - - - - - - - Raise the RowUpdated event. - - - - - - Raise the RowUpdating event. - - - - - - Row updated event. - - - - - Row updating event. - - - - - Delete command. - - - - - Select command. - - - - - Update command. - - - - - Insert command. - - - - - Provides a means of reading a forward-only stream of rows from a PostgreSQL backend. This class cannot be inherited. - - - - - Return the data type name of the column at index . - - - - - Return the data type of the column at index . - - - - - Return the Npgsql specific data type of the column at requested ordinal. - - column position - Appropriate Npgsql type for column. - - - - Return the column name of the column at index . - - - - - Return the data type OID of the column at index . - - FIXME: Why this method returns String? - - - - Has ordinal. - - - - - - - Return the column name of the column named . - - - - - Return the data DbType of the column at index . - - - - - Return the data NpgsqlDbType of the column at index . - - - - - Get specified field value. - /// - - - - - - Get the value of a column as a . - If the differences between and - in handling of days and months is not important to your application, use - instead. - - Index of the field to find. - value of the field. - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Send closed event. - - - - - Gets the value of a column converted to a Guid. - - - - - Gets the value of a column as Int16. - - - - - Gets the value of a column as Int32. - - - - - Gets the value of a column as Int64. - - - - - Gets the value of a column as Single. - - - - - Gets the value of a column as Double. - - - - - Gets the value of a column as String. - - - - - Gets the value of a column as Decimal. - - - - - Gets the value of a column as TimeSpan. - - - - - Copy values from each column in the current row into . - - Destination for column values. - The number of column values copied. - - - - Copy values from each column in the current row into . - - An array appropriately sized to store values from all columns. - The number of column values copied. - - - - Gets the value of a column as Boolean. - - - - - Gets the value of a column as Byte. - - - - - Gets the value of a column as Char. - - - - - Gets the value of a column as DateTime. - - - - - Returns a System.Data.DataTable that describes the column metadata of the DataReader. - - - - - This methods parses the command text and tries to get the tablename - from it. - - - - - Get enumerator. - - - - - - Is raised whenever Close() is called. - - - - - Gets the number of columns in the current row. - - - - - Gets the value of a column in its native format. - - - - - Gets the value of a column in its native format. - - - - - Gets a value indicating the depth of nesting for the current row. Always returns zero. - - - - - Gets a value indicating whether the data reader is closed. - - - - - Contains the column names as the keys - - - - - Contains all unique columns - - - - - This is the primary implementation of NpgsqlDataReader. It is the one used in normal cases (where the - preload-reader option is not set in the connection string to resolve some potential backwards-compatibility - issues), the only implementation used internally, and in cases where CachingDataReader is used, it is still - used to do the actual "leg-work" of turning a response stream from the server into a datareader-style - object - with CachingDataReader then filling it's cache from here. - - - - - Iterate through the objects returned through from the server. - If it's a CompletedResponse the rowsaffected count is updated appropriately, - and we iterate again, otherwise we return it (perhaps updating our cache of pending - rows if appropriate). - - The next we will deal with. - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Closes the data reader object. - - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Advances the data reader to the next row. - - True if the reader was advanced, otherwise false. - - - - Return the value of the column at index . - - - - - Gets raw data from a column. - - - - - Gets raw data from a column. - - - - - Report whether the value in a column is DBNull. - - - - - Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. - - - - - Indicates if NpgsqlDatareader has rows to be read. - - - - - Provides an implementation of NpgsqlDataReader in which all data is pre-loaded into memory. - This operates by first creating a ForwardsOnlyDataReader as usual, and then loading all of it's - Rows into memory. There is a general principle that when there is a trade-off between a class design that - is more efficient and/or scalable on the one hand and one that is less efficient but has more functionality - (in this case the internal-only functionality of caching results) that one can build the less efficent class - from the most efficient without significant extra loss in efficiency, but not the other way around. The relationship - between ForwardsOnlyDataReader and CachingDataReader is an example of this). - Since the interface presented to the user is still forwards-only, queues are used to - store this information, so that dequeueing as we go we give the garbage collector the best opportunity - possible to reclaim any memory that is no longer in use. - ForwardsOnlyDataReader being used to actually - obtain the information from the server means that the "leg-work" is still only done (and need only be - maintained) in one place. - This class exists to allow for certain potential backwards-compatibility issues to be resolved - with little effort on the part of affected users. It is considerably less efficient than ForwardsOnlyDataReader - and hence never used internally. - - - - - This is the base class for NpgsqlDescribeStatement and NpgsqlDescribePortal. - - - - - - This class represents the Statement Describe message sent to PostgreSQL - server. - - - - - - This class represents the Portal Describe message sent to PostgreSQL - server. - - - - - - EventArgs class to send Notice parameters, which are just NpgsqlError's in a lighter context. - - - - - Notice information. - - - - - This class represents the ErrorResponse and NoticeResponse - message sent from PostgreSQL server. - - - - - Return a string representation of this error object. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Terse error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Internal query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Backend protocol version in use. - - - - - Error and notice message field codes - - - - - Severity: the field contents are ERROR, FATAL, or PANIC (in an error message), - or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a localized - translation of one of these. Always present. - - - - - Code: the SQLSTATE code for the error (see Appendix A). Not localizable. Always present. - - - - - Message: the primary human-readable error message. This should be accurate - but terse (typically one line). Always present. - - - - - Detail: an optional secondary error message carrying more detail about the problem. - Might run to multiple lines. - - - - - Hint: an optional suggestion what to do about the problem. This is intended to differ - from Detail in that it offers advice (potentially inappropriate) rather than hard facts. - Might run to multiple lines. - - - - - Position: the field value is a decimal ASCII integer, indicating an error cursor - position as an index into the original query string. The first character has index 1, - and positions are measured in characters not bytes. - - - - - Internal position: this is defined the same as the P field, but it is used when the - cursor position refers to an internally generated command rather than the one submitted - by the client. - The q field will always appear when this field appears. - - - - - Internal query: the text of a failed internally-generated command. - This could be, for example, a SQL query issued by a PL/pgSQL function. - - - - - Where: an indication of the context in which the error occurred. - Presently this includes a call stack traceback of active procedural language functions - and internally-generated queries. The trace is one entry per line, most recent first. - - - - - Schema name: if the error was associated with a specific database object, - the name of the schema containing that object, if any. - - - - - Table name: if the error was associated with a specific table, the name of the table. - (Refer to the schema name field for the name of the table's schema.) - - - - - Column name: if the error was associated with a specific table column, the name of the column. - (Refer to the schema and table name fields to identify the table.) - - - - - Data type name: if the error was associated with a specific data type, the name of the data type. - (Refer to the schema name field for the name of the data type's schema.) - - - - - Constraint name: if the error was associated with a specific constraint, the name of the constraint. - Refer to fields listed above for the associated table or domain. - (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.) - - - - - File: the file name of the source-code location where the error was reported. - - - - - Line: the line number of the source-code location where the error was reported. - - - - - Routine: the name of the source-code routine reporting the error. - - - - - The level of verbosity of the NpgsqlEventLog - - - - - Don't log at all - - - - - Only log the most common issues - - - - - Log everything - - - - - This class handles all the Npgsql event and debug logging - - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - - This method is obsolete and should no longer be used. - It is likely to be removed in future versions of Npgsql - - The message to write to the event log - The minimum LogLevel for which this message should be logged. - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - The ResourceManager to get the localized resources - The name of the resource that should be fetched by the ResourceManager - The minimum LogLevel for which this message should be logged. - The additional parameters that shall be included into the log-message (must be compatible with the string in the resource): - - - - Writes the default log-message for the action of calling the Get-part of an Indexer to the log file. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - - - - Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - The value the Indexer is set to - - - - Writes the default log-message for the action of calling the Get-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - - - - Writes the default log-message for the action of calling the Set-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - The value the Property is set to - - - - Writes the default log-message for the action of calling a Method without Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - - - - Writes the default log-message for the action of calling a Method with one Argument to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the Argument of the Method - - - - Writes the default log-message for the action of calling a Method with two Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - - - - Writes the default log-message for the action of calling a Method with three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - The value of the third Argument of the Method - - - - Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - A Object-Array with zero or more Ojects that are Arguments of the Method. - - - - Sets/Returns the filename to use for logging. - - The filename of the current Log file. - - - - Sets/Returns whether Log messages should be echoed to the console - - true if Log messages are echoed to the console, otherwise false - - - - The exception that is thrown when the PostgreSQL backend reports errors. - - - - - Construct a backend error exception based on a list of one or more - backend errors. The basic Exception.Message will be built from the - first (usually the only) error in the list. - - - - - Get object data. - - - - - - - Format a .NET style exception string. - Include all errors in the list, including any hints. - - - - - Append a line to the given Stream, first checking for zero-length. - - - - - Provide access to the entire list of errors provided by the PostgreSQL backend. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Basic error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Returns the entire list of errors provided by the PostgreSQL backend. - - - - - This class represents the Execute message sent to PostgreSQL - server. - - - - - - A factory to create instances of various Npgsql objects. - - - - - Creates an NpgsqlCommand object. - - - - - This class represents the Flush message sent to PostgreSQL - server. - - - - - - For classes representing simple messages, - consisting only of a message code and length identifier, - sent from the client to the server. - - - - - This class is responsible for serving as bridge between the backend - protocol handling and the core classes. It is used as the mediator for - exchanging data generated/sent from/to backend. - - - - - - The current command timeout on the backend. This is set via "SET statement_timeout = (milliseconds)". - A value of -1 means the backend's timeout value is unknown because it has not yet been set. - - - - - EventArgs class to send Notification parameters. - - - - - Process ID of the PostgreSQL backend that sent this notification. - - - - - Condition that triggered that notification. - - - - - Additional Information From Notifiying Process (for future use, currently postgres always sets this to an empty string) - - - - - This class represents a parameter to a command that will be sent to server - - - - - Initializes a new instance of the NpgsqlParameter class. - - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and a value of the new NpgsqlParameter. - - The m_Name of the parameter to map. - An Object that is the value of the NpgsqlParameter. - -

When you specify an Object - in the value parameter, the DbType is - inferred from the .NET Framework type of the Object.

-

When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. - This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. - Use Convert.ToInt32(value) for example to have compiler calling the correct constructor.

-
-
- - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and the data type. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Reset DBType. - - - - - Creates a new NpgsqlParameter that - is a copy of the current instance. - - A new NpgsqlParameter that is a copy of this instance. - - - - The collection to which this parameter belongs, if any. - - - - - Gets or sets the maximum number of digits used to represent the - Value property. - - The maximum number of digits used to represent the - Value property. - The default value is 0, which indicates that the data provider - sets the precision for Value. - - - - Whether to use an explicit cast when included in a query. - - - - - Gets or sets the number of decimal places to which - Value is resolved. - - The number of decimal places to which - Value is resolved. The default is 0. - - - - Gets or sets the maximum size, in bytes, of the data within the column. - - The maximum size, in bytes, of the data within the column. - The default value is inferred from the parameter value. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets a value indicating whether the parameter is input-only, - output-only, bidirectional, or a stored procedure return value parameter. - - One of the ParameterDirection - values. The default is Input. - - - - Gets or sets a value indicating whether the parameter accepts null values. - - true if null values are accepted; otherwise, false. The default is false. - - - - Gets or sets the m_Name of the NpgsqlParameter. - - The m_Name of the NpgsqlParameter. - The default is an empty string. - - - - The m_Name scrubbed of any optional marker - - - - - Gets or sets the m_Name of the source column that is mapped to the - DataSet and used for loading or - returning the Value. - - The m_Name of the source column that is mapped to the - DataSet. The default is an empty string. - - - - Gets or sets the DataRowVersion - to use when loading Value. - - One of the DataRowVersion values. - The default is Current. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Source column mapping. - - - - - Represents a collection of parameters relevant to a NpgsqlCommand - as well as their respective mappings to columns in a DataSet. - This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlParameterCollection class. - - - - - Invalidate the hash lookup tables. This should be done any time a change - may throw the lookups out of sync with the list. - - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The index of the new NpgsqlParameter object. - - - - Obsolete. Use AddWithValue instead. - - - Use caution when using this overload of the - Add method to specify integer parameter values. - Because this overload takes a value of type Object, - you must convert the integral value to an Object - type when the value is zero, as the following C# example demonstrates. - parameters.Add(":pname", Convert.ToInt32(0)); - If you do not perform this conversion, the compiler will assume you - are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload. - - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The name of the source column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the parameter name and the data type. - - The name of the parameter. - One of the DbType values. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, and the column length. - - The name of the parameter. - One of the DbType values. - The length of the column. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, the column length, and the source column name. - - The name of the parameter. - One of the DbType values. - The length of the column. - The name of the source column. - The index of the new NpgsqlParameter object. - - - - Removes the specified NpgsqlParameter from the collection using the parameter name. - - The name of the NpgsqlParameter object to retrieve. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - true if the collection contains the parameter; otherwise, false. - - - - Gets the location of the NpgsqlParameter in the collection with a specific parameter name. - - The name of the NpgsqlParameter object to find. - The zero-based location of the NpgsqlParameter in the collection. - - - - Removes the specified NpgsqlParameter from the collection using a specific index. - - The zero-based index of the parameter. - - - - Inserts a NpgsqlParameter into the collection at the specified index. - - The zero-based index where the parameter is to be inserted within the collection. - The NpgsqlParameter to add to the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The name of the NpgsqlParameter to remove from the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The NpgsqlParameter to remove from the collection. - - - - Gets a value indicating whether a NpgsqlParameter exists in the collection. - - The value of the NpgsqlParameter object to find. - true if the collection contains the NpgsqlParameter object; otherwise, false. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - A reference to the requested parameter is returned in this out param if it is found in the list. This value is null if the parameter is not found. - true if the collection contains the parameter and param will contain the parameter; otherwise, false. - - - - Removes all items from the collection. - - - - - Gets the location of a NpgsqlParameter in the collection. - - The value of the NpgsqlParameter object to find. - The zero-based index of the NpgsqlParameter object in the collection. - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The zero-based index of the new NpgsqlParameter object. - - - - Copies NpgsqlParameter objects from the NpgsqlParameterCollection to the specified array. - - An Array to which to copy the NpgsqlParameter objects in the collection. - The starting index of the array. - - - - Returns an enumerator that can iterate through the collection. - - An IEnumerator that can be used to iterate through the collection. - - - - Add an Array of parameters to the collection. - - Parameters to add. - - - - Get parameter. - - - - - - - Get parameter. - - - - - - - Set parameter. - - - - - - - Set parameter. - - - - - - - In methods taking an object as argument this method is used to verify - that the argument has the type NpgsqlParameter - - The object to verify - - - - Report the offset within the collection of the given parameter. - - Parameter to find. - Index of the parameter, or -1 if the parameter is not present. - - - - Insert the specified parameter into the collection. - - Index of the existing parameter before which to insert the new one. - Parameter to insert. - - - - Report whether the specified parameter is present in the collection. - - Parameter to find. - True if the parameter was found, otherwise false. - - - - Remove the specified parameter from the collection. - - Parameter to remove. - True if the parameter was found and removed, otherwise false. - - - - Convert collection to a System.Array. - - Destination array. - Starting index in destination array. - - - - Convert collection to a System.Array. - - NpgsqlParameter[] - - - - Gets the NpgsqlParameter with the specified name. - - The name of the NpgsqlParameter to retrieve. - The NpgsqlParameter with the specified name, or a null reference if the parameter is not found. - - - - Gets the NpgsqlParameter at the specified index. - - The zero-based index of the NpgsqlParameter to retrieve. - The NpgsqlParameter at the specified index. - - - - Report whether the collection is read only. Always false. - - - - - Report whether the collection is fixed size. Always false. - - - - - Report whether the collection is synchronized. - - - - - Gets the number of NpgsqlParameter objects in the collection. - - The number of NpgsqlParameter objects in the collection. - - - - Sync root. - - - - - This class represents the ParameterStatus message sent from PostgreSQL - server. - - - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - This class represents a PasswordPacket message sent to backend - PostgreSQL. - - - - - Used when a connection is closed - - - - - This is the abstract base class for NpgsqlAsciiRow and NpgsqlBinaryRow. - - - - - The index of the current field in the stream, i.e. the one that hasn't - been read yet - - - - - This class represents a RowDescription message sent from - the PostgreSQL. - - - - - - This struct represents the internal data of the RowDescription message. - - - - - Provides the underlying mechanism for reading schema information. - - - - - Returns the MetaDataCollections that lists all possible collections. - - The MetaDataCollections - - - - Returns the Restrictions that contains the meaning and position of the values in the restrictions array. - - The Restrictions - - - - Returns the Databases that contains a list of all accessable databases. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Databases - - - - Returns the Tables that contains table and view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Tables - - - - Returns the Columns that contains information about columns in tables. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Columns. - - - - Returns the Views that contains view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Views - - - - Returns the Users containing user names and the sysid of those users. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Users. - - - - This class represents a StartupPacket message of PostgreSQL - protocol. - - - - - - Represents a completed response message. - - - - - This class represents the Sync message sent to PostgreSQL - server. - - - - - - Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited. - - - - - Dispose. - - - - - - Commits the database transaction. - - - - - Rolls back a transaction from a pending state. - - - - - Rolls back a transaction from a pending savepoint state. - - - - - Creates a transaction save point. - - - - - Cancel the transaction without telling the backend about it. This is - used to make the transaction go away when closing a connection. - - - - - Gets the NpgsqlConnection - object associated with the transaction, or a null reference if the - transaction is no longer valid. - - The NpgsqlConnection - object associated with the transaction. - - - - DB connection. - - - - - Specifies the IsolationLevel for this transaction. - - The IsolationLevel for this transaction. - The default is ReadCommitted. - - - - This class provides many util methods to handle - reading and writing of PostgreSQL protocol messages. - - - - - This method takes a ProtocolVersion and returns an integer - version number that the Postgres backend will recognize in a - startup packet. - - - - - This method takes a version string as returned by SELECT VERSION() and returns - a valid version string ("7.2.2" for example). - This is only needed when running protocol version 2. - This does not do any validity checks. - - - - - This method gets a C NULL terminated string from the network stream. - It keeps reading a byte in each time until a NULL byte is returned. - It returns the resultant string of bytes read. - This string is sent from backend. - - - - - Reads requested number of bytes from stream with retries until Stream.Read returns 0 or count is reached. - - Stream to read - byte buffer to fill - starting position to fill the buffer - number of bytes to read - The number of bytes read. May be less than count if no more bytes are available. - - - - Reads requested number of bytes from . If output matches exactly, and == false, is returned directly. - - Source array. - Starting position to read from - Number of bytes to read - Force a copy, even if the output is an exact copy of . - byte[] containing data requested. - - - - This method writes a string to the network stream. - - - - - This method writes a string to the network stream. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a C NULL terminated string limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - This method writes a C NULL terminated byte[] limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - Write a 32-bit integer to the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given array in the correct byte order. - - - - - Write a 16-bit integer to the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given array in the correct byte order. - - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Starting offset in source array. - Number of bytes to copy. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Represent the frontend/backend protocol version. - - - - - Represent the backend server version. - As this class offers no functionality beyond that offered by it has been - deprecated in favour of that class. - - - - - - Returns the string representation of this version in three place dot notation (Major.Minor.Patch). - - - - - Server version major number. - - - - - Server version minor number. - - - - - Server version patch level number. - - - - - A class to handle everything associated with SSPI authentication - - - - - Simplified SecBufferDesc struct with only one SecBuffer - - - - - Provides a set of static (Shared in Visual Basic) methods for - querying objects that implement . - - - - - Returns the input typed as . - - - - - Returns an empty that has the - specified type argument. - - - - - Converts the elements of an to the - specified type. - - - - - Filters the elements of an based on a specified type. - - - - - Generates a sequence of integral numbers within a specified range. - - The value of the first integer in the sequence. - The number of sequential integers to generate. - - - - Generates a sequence that contains one repeated value. - - - - - Filters a sequence of values based on a predicate. - - - - - Filters a sequence of values based on a predicate. - Each element's index is used in the logic of the predicate function. - - - - - Projects each element of a sequence into a new form. - - - - - Projects each element of a sequence into a new form by - incorporating the element's index. - - - - - Projects each element of a sequence to an - and flattens the resulting sequences into one sequence. - - - - - Projects each element of a sequence to an , - and flattens the resulting sequences into one sequence. The - index of each source element is used in the projected form of - that element. - - - - - Projects each element of a sequence to an , - flattens the resulting sequences into one sequence, and invokes - a result selector function on each element therein. - - - - - Projects each element of a sequence to an , - flattens the resulting sequences into one sequence, and invokes - a result selector function on each element therein. The index of - each source element is used in the intermediate projected form - of that element. - - - - - Returns elements from a sequence as long as a specified condition is true. - - - - - Returns elements from a sequence as long as a specified condition is true. - The element's index is used in the logic of the predicate function. - - - - - Returns a specified number of contiguous elements from the start - of a sequence. - - - - - Base implementation of First operator. - - - - - Returns the first element of a sequence. - - - - - Returns the first element in a sequence that satisfies a specified condition. - - - - - Returns the first element of a sequence, or a default value if - the sequence contains no elements. - - - - - Returns the first element of the sequence that satisfies a - condition or a default value if no such element is found. - - - - - Base implementation of Last operator. - - - - - Returns the last element of a sequence. - - - - - Returns the last element of a sequence that satisfies a - specified condition. - - - - - Returns the last element of a sequence, or a default value if - the sequence contains no elements. - - - - - Returns the last element of a sequence that satisfies a - condition or a default value if no such element is found. - - - - - Base implementation of Single operator. - - - - - Returns the only element of a sequence, and throws an exception - if there is not exactly one element in the sequence. - - - - - Returns the only element of a sequence that satisfies a - specified condition, and throws an exception if more than one - such element exists. - - - - - Returns the only element of a sequence, or a default value if - the sequence is empty; this method throws an exception if there - is more than one element in the sequence. - - - - - Returns the only element of a sequence that satisfies a - specified condition or a default value if no such element - exists; this method throws an exception if more than one element - satisfies the condition. - - - - - Returns the element at a specified index in a sequence. - - - - - Returns the element at a specified index in a sequence or a - default value if the index is out of range. - - - - - Inverts the order of the elements in a sequence. - - - - - Bypasses elements in a sequence as long as a specified condition - is true and then returns the remaining elements. - - - - - Bypasses elements in a sequence as long as a specified condition - is true and then returns the remaining elements. The element's - index is used in the logic of the predicate function. - - - - - Bypasses a specified number of elements in a sequence and then - returns the remaining elements. - - - - - Returns the number of elements in a sequence. - - - - - Returns a number that represents how many elements in the - specified sequence satisfy a condition. - - - - - Returns an that represents the total number - of elements in a sequence. - - - - - Returns an that represents how many elements - in a sequence satisfy a condition. - - - - - Concatenates two sequences. - - - - - Creates a from an . - - - - - Creates an array from an . - - - - - Returns distinct elements from a sequence by using the default - equality comparer to compare values. - - - - - Returns distinct elements from a sequence by using a specified - to compare values. - - - - - Creates a from an - according to a specified key - selector function. - - - - - Creates a from an - according to a specified key - selector function and a key comparer. - - - - - Creates a from an - according to specified key - and element selector functions. - - - - - Creates a from an - according to a specified key - selector function, a comparer and an element selector function. - - - - - Groups the elements of a sequence according to a specified key - selector function. - - - - - Groups the elements of a sequence according to a specified key - selector function and compares the keys by using a specified - comparer. - - - - - Groups the elements of a sequence according to a specified key - selector function and projects the elements for each group by - using a specified function. - - - - - Groups the elements of a sequence according to a specified key - selector function and creates a result value from each group and - its key. - - - - - Groups the elements of a sequence according to a key selector - function. The keys are compared by using a comparer and each - group's elements are projected by using a specified function. - - - - - Groups the elements of a sequence according to a specified key - selector function and creates a result value from each group and - its key. The elements of each group are projected by using a - specified function. - - - - - Groups the elements of a sequence according to a specified key - selector function and creates a result value from each group and - its key. The keys are compared by using a specified comparer. - - - - - Groups the elements of a sequence according to a specified key - selector function and creates a result value from each group and - its key. Key values are compared by using a specified comparer, - and the elements of each group are projected by using a - specified function. - - - - - Applies an accumulator function over a sequence. - - - - - Applies an accumulator function over a sequence. The specified - seed value is used as the initial accumulator value. - - - - - Applies an accumulator function over a sequence. The specified - seed value is used as the initial accumulator value, and the - specified function is used to select the result value. - - - - - Produces the set union of two sequences by using the default - equality comparer. - - - - - Produces the set union of two sequences by using a specified - . - - - - - Returns the elements of the specified sequence or the type - parameter's default value in a singleton collection if the - sequence is empty. - - - - - Returns the elements of the specified sequence or the specified - value in a singleton collection if the sequence is empty. - - - - - Determines whether all elements of a sequence satisfy a condition. - - - - - Determines whether a sequence contains any elements. - - - - - Determines whether any element of a sequence satisfies a - condition. - - - - - Determines whether a sequence contains a specified element by - using the default equality comparer. - - - - - Determines whether a sequence contains a specified element by - using a specified . - - - - - Determines whether two sequences are equal by comparing the - elements by using the default equality comparer for their type. - - - - - Determines whether two sequences are equal by comparing their - elements by using a specified . - - - - - Base implementation for Min/Max operator. - - - - - Base implementation for Min/Max operator for nullable types. - - - - - Returns the minimum value in a generic sequence. - - - - - Invokes a transform function on each element of a generic - sequence and returns the minimum resulting value. - - - - - Returns the maximum value in a generic sequence. - - - - - Invokes a transform function on each element of a generic - sequence and returns the maximum resulting value. - - - - - Makes an enumerator seen as enumerable once more. - - - The supplied enumerator must have been started. The first element - returned is the element the enumerator was on when passed in. - DO NOT use this method if the caller must be a generator. It is - mostly safe among aggregate operations. - - - - - Sorts the elements of a sequence in ascending order according to a key. - - - - - Sorts the elements of a sequence in ascending order by using a - specified comparer. - - - - - Sorts the elements of a sequence in descending order according to a key. - - - - - Sorts the elements of a sequence in descending order by using a - specified comparer. - - - - - Performs a subsequent ordering of the elements in a sequence in - ascending order according to a key. - - - - - Performs a subsequent ordering of the elements in a sequence in - ascending order by using a specified comparer. - - - - - Performs a subsequent ordering of the elements in a sequence in - descending order, according to a key. - - - - - Performs a subsequent ordering of the elements in a sequence in - descending order by using a specified comparer. - - - - - Base implementation for Intersect and Except operators. - - - - - Produces the set intersection of two sequences by using the - default equality comparer to compare values. - - - - - Produces the set intersection of two sequences by using the - specified to compare values. - - - - - Produces the set difference of two sequences by using the - default equality comparer to compare values. - - - - - Produces the set difference of two sequences by using the - specified to compare values. - - - - - Creates a from an - according to a specified key - selector function. - - - - - Creates a from an - according to a specified key - selector function and key comparer. - - - - - Creates a from an - according to specified key - selector and element selector functions. - - - - - Creates a from an - according to a specified key - selector function, a comparer, and an element selector function. - - - - - Correlates the elements of two sequences based on matching keys. - The default equality comparer is used to compare keys. - - - - - Correlates the elements of two sequences based on matching keys. - The default equality comparer is used to compare keys. A - specified is used to compare keys. - - - - - Correlates the elements of two sequences based on equality of - keys and groups the results. The default equality comparer is - used to compare keys. - - - - - Correlates the elements of two sequences based on equality of - keys and groups the results. The default equality comparer is - used to compare keys. A specified - is used to compare keys. - - - - - Computes the sum of a sequence of nullable values. - - - - - Computes the sum of a sequence of nullable - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of nullable values. - - - - - Computes the average of a sequence of nullable values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Computes the sum of a sequence of values. - - - - - Computes the sum of a sequence of - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of values. - - - - - Computes the average of a sequence of values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Returns the minimum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the minimum nullable value. - - - - - Returns the maximum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the maximum nullable value. - - - - - Computes the sum of a sequence of nullable values. - - - - - Computes the sum of a sequence of nullable - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of nullable values. - - - - - Computes the average of a sequence of nullable values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Computes the sum of a sequence of values. - - - - - Computes the sum of a sequence of - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of values. - - - - - Computes the average of a sequence of values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Returns the minimum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the minimum nullable value. - - - - - Returns the maximum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the maximum nullable value. - - - - - Computes the sum of a sequence of nullable values. - - - - - Computes the sum of a sequence of nullable - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of nullable values. - - - - - Computes the average of a sequence of nullable values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Computes the sum of a sequence of values. - - - - - Computes the sum of a sequence of - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of values. - - - - - Computes the average of a sequence of values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Returns the minimum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the minimum nullable value. - - - - - Returns the maximum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the maximum nullable value. - - - - - Computes the sum of a sequence of nullable values. - - - - - Computes the sum of a sequence of nullable - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of nullable values. - - - - - Computes the average of a sequence of nullable values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Computes the sum of a sequence of values. - - - - - Computes the sum of a sequence of - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of values. - - - - - Computes the average of a sequence of values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Returns the minimum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the minimum nullable value. - - - - - Returns the maximum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the maximum nullable value. - - - - - Computes the sum of a sequence of nullable values. - - - - - Computes the sum of a sequence of nullable - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of nullable values. - - - - - Computes the average of a sequence of nullable values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Computes the sum of a sequence of values. - - - - - Computes the sum of a sequence of - values that are obtained by invoking a transform function on - each element of the input sequence. - - - - - Computes the average of a sequence of values. - - - - - Computes the average of a sequence of values - that are obtained by invoking a transform function on each - element of the input sequence. - - - - - Returns the minimum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the minimum nullable value. - - - - - Returns the maximum value in a sequence of nullable - values. - - - - - Invokes a transform function on each element of a sequence and - returns the maximum nullable value. - - - - - Represents a collection of objects that have a common key. - - - - - Gets the key of the . - - - - - This attribute allows us to define extension methods without - requiring .NET Framework 3.5. For more information, see the section, - Extension Methods in .NET Framework 2.0 Apps, - of Basic Instincts: Extension Methods - column in MSDN Magazine, - issue Nov 2007. - - - - - Defines an indexer, size property, and Boolean search method for - data structures that map keys to - sequences of values. - - - - - This type is not intended to be used directly from user code. - It may be removed or changed in a future version without notice. - - - - - This type is not intended to be used directly from user code. - It may be removed or changed in a future version without notice. - - - - - This type is not intended to be used directly from user code. - It may be removed or changed in a future version without notice. - - - - - Represents a sorted sequence. - - - - - Performs a subsequent ordering on the elements of an - according to a key. - - - - - Represents a collection of keys each mapped to one or more values. - - - - - Determines whether a specified key is in the . - - - - - Applies a transform function to each key and its associated - values and returns the results. - - - - - Returns a generic enumerator that iterates through the . - - - - - Gets the number of key/value collection pairs in the . - - - - - Gets the collection of values indexed by the specified key. - - -
-
diff --git a/src/packages/Npgsql.2.2.3/lib/net20/de/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net20/de/Npgsql.resources.dll deleted file mode 100644 index ad068c56b..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/de/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net20/es/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net20/es/Npgsql.resources.dll deleted file mode 100644 index 842068f2c..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/es/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net20/fi/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net20/fi/Npgsql.resources.dll deleted file mode 100644 index 457d99b65..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/fi/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net20/fr/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net20/fr/Npgsql.resources.dll deleted file mode 100644 index 41d613c96..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/fr/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net20/ja/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net20/ja/Npgsql.resources.dll deleted file mode 100644 index 2e9574aa9..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/ja/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net20/zh-CN/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net20/zh-CN/Npgsql.resources.dll deleted file mode 100644 index a0ba42ba9..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net20/zh-CN/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/Mono.Security.dll b/src/packages/Npgsql.2.2.3/lib/net35/Mono.Security.dll deleted file mode 100644 index 5173f0dc4..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/Mono.Security.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/Npgsql.dll b/src/packages/Npgsql.2.2.3/lib/net35/Npgsql.dll deleted file mode 100644 index 33fcba497..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/Npgsql.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/Npgsql.xml b/src/packages/Npgsql.2.2.3/lib/net35/Npgsql.xml deleted file mode 100644 index 332e24dd4..000000000 --- a/src/packages/Npgsql.2.2.3/lib/net35/Npgsql.xml +++ /dev/null @@ -1,6502 +0,0 @@ - - - - Npgsql - - - - - Handles serialisation of .NET array or IEnumeration to pg format. - Arrays of arrays, enumerations of enumerations, arrays of enumerations etc. - are treated as multi-dimensional arrays (in much the same manner as an array of arrays - is used to emulate multi-dimensional arrays in languages that lack native support for them). - If such an enumeration of enumerations is "jagged" (as opposed to rectangular, cuboid, - hypercuboid, hyperhypercuboid, etc) then this class will "correctly" serialise it, but pg - will raise an error as it doesn't allow jagged arrays. - - - - - Create an ArrayNativeToBackendTypeConverter with the element converter passed - - The that would be used to serialise the element type. - - - - Serialise the enumeration or array. - - - - - Convert a System.Array to PG binary format. - Write the array header and prepare to write array data to the stream. - - - - - Append all array data to the binary stream. - - - - - Handles parsing of pg arrays into .NET arrays. - - - - - Takes a string representation of a pg 1-dimensional array - (or a 1-dimensional row within an n-dimensional array) - and allows enumeration of the string represenations of each items. - - - - - Takes a string representation of a pg n-dimensional array - and allows enumeration of the string represenations of the next - lower level of rows (which in turn can be taken as (n-1)-dimensional arrays. - - - - - Takes an ArrayList which may be an ArrayList of ArrayLists, an ArrayList of ArrayLists of ArrayLists - and so on and enumerates the items that aren't ArrayLists (the leaf nodes if we think of the ArrayList - passed as a tree). Simply uses the ArrayLists' own IEnumerators to get that of the next, - pushing them onto a stack until we hit something that isn't an ArrayList. - ArrayList to enumerate - IEnumerable - - - - - Create a new ArrayBackendToNativeTypeConverter - - for the element type. - - - - Creates an array from pg text representation. - - - - - Creates an array list from pg represenation of an array. - Multidimensional arrays are treated as ArrayLists of ArrayLists - - - - - Creates an n-dimensional array from an ArrayList of ArrayLists or - a 1-dimensional array from something else. - - to convert - Type of the elements in the list - produced. - - - - Creates an n-dimensional System.Array from PG binary representation. - This function reads the array header and sets up an n-dimensional System.Array object to hold its data. - PopulateArrayFromBinaryArray() is then called to carry out array population. - - - - - Recursively populates an array from PB binary data representation. - - - - - Takes an array of ints and treats them like the limits of a set of counters. - Retains a matching set of ints that is set to all zeros on the first ++ - On a ++ it increments the "right-most" int. If that int reaches it's - limit it is set to zero and the one before it is incremented, and so on. - - Making this a more general purpose class is pretty straight-forward, but we'll just put what we need here. - - - - - Implements a bit string; a collection of zero or more bits which can each be 1 or 0. - BitString's behave as a list of bools, though like most strings and unlike most collections the position - tends to be of as much significance as the value. - BitStrings are often used as masks, and are commonly cast to and from other values. - - - - - Represents the empty string. - - - - - Create a BitString from an enumeration of boolean values. The BitString will contain - those booleans in the order they came in. - - The boolean values. - - - - Creates a BitString filled with a given number of true or false values. - - The value to fill the string with. - The number of bits to fill. - - - - Creats a bitstring from a string. - The string to copy from. - - - - - - Creates a single-bit element from a boolean value. - - The bool value which determines whether - the bit is 1 or 0. - - - - Creates a bitstring from an unsigned integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - This method is not CLS Compliant, and may not be available to some languages. - - - - Creates a bitstring from an integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - - - - Finds the first instance of a given value - - The value - whether true or false - to search for. - The index of the value found, or -1 if none are present. - - - - True if there is at least one bit with the value looked for. - - The value - true or false - to detect. - True if at least one bit was the same as item, false otherwise. - - - - Copies the bitstring to an array of bools. - - The boolean array to copy to. - The index in the array to start copying from. - - - - Returns an enumerator that enumerates through the string. - - The enumerator. - - - - Creats a bitstring by concatenating another onto this one. - - The string to append to this one. - The combined strings. - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string. - The length of the string to return, must be greater than zero, and may not be - so large that the start + length exceeds the bounds of this instance. - The Bitstring identified - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string, - the rest of the string is returned. - The Bitstring identified - - - - A logical and between this string and another. The two strings must be the same length. - - Another BitString to AND with this one. - A bitstring with 1 where both BitStrings had 1 and 0 otherwise. - - - - A logical or between this string and another. The two strings must be the same length. - - Another BitString to OR with this one. - A bitstring with 1 where either BitString had 1 and 0 otherwise. - - - - A logical xor between this string and another. The two strings must be the same length. - - Another BitString to XOR with this one. - A bitstring with 1 where one BitStrings and the other had 0, - and 0 where they both had 1 or both had 0. - - - - A bitstring that is the logical inverse of this one. - - A bitstring of the same length as this with 1 where this has 0 and vice-versa. - - - - Shifts the string operand bits to the left, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the left. - A left-shifted bitstring. - The behaviour of LShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a right-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. - - - - - Shifts the string operand bits to the right, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the right. - A right-shifted bitstring. - The behaviour of RShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a left-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. It also performs - a logical shift, rather than an arithmetic shift, so it always sets the vacated bit positions to zero - (like PostgreSQL and like .NET for unsigned integers but not for signed integers). - - - - - Returns true if the this string is identical to the argument passed. - - - - - Compares two strings. Strings are compared as strings, so while 0 being less than 1 will - mean a comparison between two strings of the same size is the same as treating them as numbers, - in the case of two strings of differing lengths the comparison starts at the right-most (most significant) - bit, and if all bits of the shorter string are exhausted without finding a comparison, then the larger - string is deemed to be greater than the shorter (0010 is greater than 0001 but less than 00100). - - Another string to compare with this one. - A value if the two strings are identical, an integer less - than zero if this is less than the argument, and an integer greater - than zero otherwise. - - - - Compares the string with another object. - - The object to compare with. - If the object is null then this string is considered greater. If the object is another BitString - then they are compared as in the explicit comparison for BitStrings - in any other case a is thrown. - - - - Compares this BitString with an object for equality. - - - - - Returns a code for use in hashing operations. - - - - - Returns a string representation of the BitString. - - - A string which can contain a letter and optionally a number which sets a minimum size for the string - returned. In each case using the lower-case form of the letter will result in a lower-case string - being returned. - - - B - A string of 1s and 0s. - - - X - An hexadecimal string (will result in an error unless the string's length is divisible by 4). - - - G - A string of 1s and 0s in single-quotes preceded by 'B' (Postgres bit string literal syntax). - - Y - An hexadecimal string in single-quotes preceded by 'X' (Postgres bit literal syntax, will result in an error unless the string's length is divisible by 4. - - C - The format produced by format-string "Y" if legal, otherwise that produced by format-string "G". - E - The most compact safe representation for Postgres. If single bit will be either a 0 or a 1. Otherwise if it - can be that produce by format string "Y" it will, otherwise if there are less than 9bits in length it will be that - produced by format-string "G". For longer strings that cannot be represented in hexadecimal it will be a string - representing the first part of the string in format "Y" followed by the PostgreSQL concatenation operator, followed - by the final bits in the format "G". E.g. "X'13DCE'||B'110'" - If format is empty or null, it is treated as if "B" had been passed (the default repreesentation, and that - generally used by PostgreSQL for display). - - The formatted string. - - - - Returns a string representation for the Bitstring - - A string containing '0' and '1' characters. - - - - Returns the same string as . formatProvider is ignored. - - - - - Parses a string to produce a BitString. Most formats that can be produced by - can be accepted, but hexadecimal - can be interpreted with the preceding X' to mark the following characters as - being hexadecimal rather than binary. - - - - - Performs a logical AND on the two operands. - - - - - Performs a logcial OR on the two operands. - - - - - Perofrms a logical EXCLUSIVE-OR on the two operands - - - - - Performs a logical NOT on the operand. - - - - - Concatenates the operands. - - - - - Left-shifts the string BitString. - - - - - Right-shifts the string BitString. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Interprets the bitstring as a series of bits in an encoded character string, - encoded according to the Encoding passed, and returns that string. - The bitstring must contain a whole number of octets(bytes) and also be - valid according to the Encoding passed. - - The to use in producing the string. - The string that was encoded in the BitString. - - - - Interprets the bitstring as a series of octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - - - - - Interprets the bitstring as a series of signed octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - This method is not CLS-Compliant and may not be available to languages that cannot - handle signed bytes. - - - - - Interprets the bitstring as a series of unsigned 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - - - - - Interprets the bitstring as a series of unsigned 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - - - - - Interprets the bitstring as a series of unsigned 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - - - - - The length of the string. - - - - - Retrieves the value of the bit at the given index. - - - - - Represents the PostgreSQL interval datatype. - PostgreSQL differs from .NET in how it's interval type doesn't assume 24 hours in a day - (to deal with 23- and 25-hour days caused by daylight savings adjustments) and has a concept - of months that doesn't exist in .NET's class. (Neither datatype - has any concessions for leap-seconds). - For most uses just casting to and from TimeSpan will work correctly — in particular, - the results of subtracting one or the PostgreSQL date, time and - timestamp types from another should be the same whether you do so in .NET or PostgreSQL — - but if the handling of days and months in PostgreSQL is important to your application then you - should use this class instead of . - If you don't know whether these differences are important to your application, they - probably arent! Just use and do not use this class directly ☺ - To avoid forcing unnecessary provider-specific concerns on users who need not be concerned - with them a call to on a field containing an - value will return a rather than an - . If you need the extra functionality of - then use . - - - - - - - - - - Represents the number of ticks (100ns periods) in one microsecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one millisecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one second. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one minute. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one hour. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one day. This field is constant. - - - - - Represents the number of hours in one day (assuming no daylight savings adjustments). This field is constant. - - - - - Represents the number of days assumed in one month if month justification or unjustifcation is performed. - This is set to 30 for consistency with PostgreSQL. Note that this is means that month adjustments cause - a year to be taken as 30 × 12 = 360 rather than 356/366 days. - - - - - Represents the number of ticks (100ns periods) in one day, assuming 30 days per month. - - - - - Represents the number of months in a year. This field is constant. - - - - - Represents the maximum . This field is read-only. - - - - - Represents the minimum . This field is read-only. - - - - - Represents the zero . This field is read-only. - - - - - Initializes a new to the specified number of ticks. - - A time period expressed in 100ns units. - - - - Initializes a new to hold the same time as a - - A time period expressed in a - - - - Initializes a new to the specified number of months, days - & ticks. - - Number of months. - Number of days. - Number of 100ns units. - - - - Initializes a new to the specified number of - days, hours, minutes & seconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - - - - Initializes a new to the specified number of - days, hours, minutes, seconds & milliseconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - months, days, hours, minutes, seconds & milliseconds. - - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - years, months, days, hours, minutes, seconds & milliseconds. - Years are calculated exactly equivalent to 12 months. - - Number of years. - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Creates an from a number of ticks. - - The number of ticks (100ns units) in the interval. - A d with the given number of ticks. - - - - Creates an from a number of microseconds. - - The number of microseconds in the interval. - A d with the given number of microseconds. - - - - Creates an from a number of milliseconds. - - The number of milliseconds in the interval. - A d with the given number of milliseconds. - - - - Creates an from a number of seconds. - - The number of seconds in the interval. - A d with the given number of seconds. - - - - Creates an from a number of minutes. - - The number of minutes in the interval. - A d with the given number of minutes. - - - - Creates an from a number of hours. - - The number of hours in the interval. - A d with the given number of hours. - - - - Creates an from a number of days. - - The number of days in the interval. - A d with the given number of days. - - - - Creates an from a number of months. - - The number of months in the interval. - A d with the given number of months. - - - - Adds another interval to this instance and returns the result. - - An to add to this instance. - An whose values are the sums of the two instances. - - - - Subtracts another interval from this instance and returns the result. - - An to subtract from this instance. - An whose values are the differences of the two instances. - - - - Returns an whose value is the negated value of this instance. - - An whose value is the negated value of this instance. - - - - This absolute value of this instance. In the case of some, but not all, components being negative, - the rules used for justification are used to determine if the instance is positive or negative. - - An whose value is the absolute value of this instance. - - - - Equivalent to PostgreSQL's justify_days function. - - An based on this one, but with any hours outside of the range [-23, 23] - converted into days. - - - - Opposite to PostgreSQL's justify_days function. - - An based on this one, but with any days converted to multiples of ±24hours. - - - - Equivalent to PostgreSQL's justify_months function. - - An based on this one, but with any days outside of the range [-30, 30] - converted into months. - - - - Opposite to PostgreSQL's justify_months function. - - An based on this one, but with any months converted to multiples of ±30days. - - - - Equivalent to PostgreSQL's justify_interval function. - - An based on this one, - but with any months converted to multiples of ±30days - and then with any days converted to multiples of ±24hours - - - - Opposite to PostgreSQL's justify_interval function. - - An based on this one, but with any months converted to multiples of ±30days and then any days converted to multiples of ±24hours; - - - - Produces a canonical NpgslInterval with 0 months and hours in the range of [-23, 23]. - - - While the fact that for many purposes, two different instances could be considered - equivalent (e.g. one with 2days, 3hours and one with 1day 27hours) there are different possible canonical forms. - - E.g. we could move all excess hours into days and all excess days into months and have the most readable form, - or we could move everything into the ticks and have the form that allows for the easiest arithmetic) the form - chosen has two important properties that make it the best choice. - First, it is closest two how - objects are most often represented. Second, it is compatible with results of many - PostgreSQL functions, particularly with age() and the results of subtracting one date, time or timestamp from - another. - - Note that the results of casting a to is - canonicalised. - - - An based on this one, but with months converted to multiples of ±30days and with any hours outside of the range [-23, 23] - converted into days. - - - - Implicit cast of a to an - - A - An eqivalent, canonical, . - - - - Implicit cast of an to a . - - A . - An equivalent . - - - - Returns true if another is exactly the same as this instance. - - An for comparison. - true if the two instances are exactly the same, - false otherwise. - - - - Returns true if another object is an , that is exactly the same as - this instance - - An for comparison. - true if the argument is an and is exactly the same - as this one, false otherwise. - - - - Compares two instances. - - The first . - The second . - 0 if the two are equal or equivalent. A value greater than zero if x is greater than y, - a value less than zero if x is less than y. - - - - A hash code suitable for uses with hashing algorithms. - - An signed integer. - - - - Compares this instance with another/ - - An to compare this with. - 0 if the instances are equal or equivalent. A value less than zero if - this instance is less than the argument. A value greater than zero if this instance - is greater than the instance. - - - - Compares this instance with another/ - - An object to compare this with. - 0 if the argument is an and the instances are equal or equivalent. - A value less than zero if the argument is an and - this instance is less than the argument. - A value greater than zero if the argument is an and this instance - is greater than the instance. - A value greater than zero if the argument is null. - The argument is not an . - - - - Parses a and returns a instance. - Designed to use the formats generally returned by PostgreSQL. - - The to parse. - An represented by the argument. - The string was null. - A value obtained from parsing the string exceeded the values allowed for the relevant component. - The string was not in a format that could be parsed to produce an . - - - - Attempt to parse a to produce an . - - The to parse. - (out) The produced, or if the parsing failed. - true if the parsing succeeded, false otherwise. - - - - Create a representation of the instance. - The format returned is of the form: - [M mon[s]] [d day[s]] [HH:mm:ss[.f[f[f[f[f[f[f[f[f]]]]]]]]]] - A zero is represented as 00:00:00 - - Ticks are 100ns, Postgress resolution is only to 1µs at most. Hence we lose 1 or more decimal - precision in storing values in the database. Despite this, this method will output that extra - digit of precision. It's forward-compatible with any future increases in resolution up to 100ns, - and also makes this ToString() more applicable to any other use-case. - - - The representation. - - - - Adds two together. - - The first to add. - The second to add. - An whose values are the sum of the arguments. - - - - Subtracts one from another. - - The to subtract the other from. - The to subtract from the other. - An whose values are the difference of the arguments - - - - Returns true if two are exactly the same. - - The first to compare. - The second to compare. - true if the two arguments are exactly the same, false otherwise. - - - - Returns false if two are exactly the same. - - The first to compare. - The second to compare. - false if the two arguments are exactly the same, true otherwise. - - - - Compares two instances to see if the first is less than the second - - The first to compare. - The second to compare. - true if the first is less than second, false otherwise. - - - - Compares two instances to see if the first is less than or equivalent to the second - - The first to compare. - The second to compare. - true if the first is less than or equivalent to second, false otherwise. - - - - Compares two instances to see if the first is greater than the second - - The first to compare. - The second to compare. - true if the first is greater than second, false otherwise. - - - - Compares two instances to see if the first is greater than or equivalent the second - - The first to compare. - The second to compare. - true if the first is greater than or equivalent to the second, false otherwise. - - - - Returns the instance. - - An . - The argument. - - - - Negates an instance. - - An . - The negation of the argument. - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. This ignores the number of days and - months held. If you want them included use first. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - interval(0) - resolution of 1s (1 second) - - - interval(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - interval(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - interval(3) - resolution of 1ms = 0.001s (1 millisecond) - - - interval(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - interval(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - interval(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL interval will - not suffice for those purposes. - In more frequent cases though, the resolution of the interval suffices. - will always suffice to handle the resolution of any interval value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An in the range [-999999, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An in the range [-999, 999]. - - - - - Gets the number of whole seconds held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole minutes held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that this can be less than -23 or greater than 23 unless - has been used to produce this instance. - - - - - Gets the number of days held in the instance. - Note that this does not pay attention to a time component with -24 or less hours or - 24 or more hours, unless has been called to produce this instance. - - - - - Gets the number of months held in the instance. - Note that this does not pay attention to a day component with -30 or less days or - 30 or more days, unless has been called to produce this instance. - - - - - Returns a representing the time component of the instance. - Note that this may have a value beyond the range ±23:59:59.9999999 unless - has been called to produce this instance. - - - - - The total number of ticks (100ns units) in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of microseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of milliseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of seconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of minutes in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of hours in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of days in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of months in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - time(0) - resolution of 1s (1 second) - - - time(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - time(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - time(3) - resolution of 1ms = 0.001s (1 millisecond) - - - time(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - time(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - time(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL time will - not suffice for those purposes. - In more frequent cases though, the resolution of time suffices. - will always suffice to handle the resolution of any time value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - Compares this with another . As per postgres' rules, - first the times are compared as if they were both in the same timezone. If they are equal then - then timezones are compared (+01:00 being "smaller" than -01:00). - - the to compare with. - An integer which is 0 if they are equal, < 0 if this is the smaller and > 0 if this is the larger. - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - This class implements the Fastpath api. - - - - - This maps the functions names to their id's (possible unique just - to a connection). - - - - - Our connection. - - - - - The network stream. - - - - - Initialises the fastpath system. - - BaseConnection to attach to. - The network stream to the backend. - - - - Initialises the fastpath system. - - BaseConnection to attach to. - - - - Send a function call to the PostgreSQL backend. - - Function id. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - Send a function call to the PostgreSQL backend by name. - Note: the mapping for the procedure name to function id needs to exist, - usually to an earlier call to addfunction(). - This is the prefered method to call, as function id's can/may change - between versions of the backend. - For an example of how this works, refer to NpgsqlTypes.LargeObject - - Function name. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Integer result. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Array containing result - - - - This adds a function to our lookup table. - User code should use the addFunctions method, which is based upon a - query, rather than hard coding the oid. The oid for a function is not - guaranteed to remain static, even on different servers of the same - version. - - Function name. - Function id. - - - - This takes a ResultSet containing two columns. Column 1 contains the - function name, Column 2 the oid. - It reads the entire ResultSet, loading the values into the function - table. - REMEMBER to close() the resultset after calling this!! - Implementation note about function name lookups: - PostgreSQL stores the function id's and their corresponding names in - the pg_proc table. To speed things up locally, instead of querying each - function from that table when required, a Dictionary is used. Also, only - the function's required are entered into this table, keeping connection - times as fast as possible. - The org.postgresql.largeobject.LargeObject class performs a query upon it's startup, - and passes the returned ResultSet to the addFunctions() method here. - Once this has been done, the LargeObject api refers to the functions by - name. - Dont think that manually converting them to the oid's will work. Ok, - they will for now, but they can change during development (there was some - discussion about this for V7.0), so this is implemented to prevent any - unwarranted headaches in the future. - - ResultSet - - - - This returns the function id associated by its name - If addFunction() or addFunctions() have not been called for this name, - then an NpgsqlException is thrown. - - Function name to lookup. - Function ID for fastpath call. - - - - Fast Path Arg. - - - - - Type of argument, true=integer, false=byte[]. - - - - - Integer value if type=true. - - - - - Byte value if type=false; - - - - - Constructs an argument that consists of an integer value. - - Int value to set. - - - - Constructs an argument that consists of an array of bytes. - - Array to store. - - - - Constructs an argument that consists of part of a byte array. - - Source array. - offset within array. - length of data to include. - - - - Constructs an argument that consists of a String. - - String to store. - - - - This sends this argument down the network stream. - The stream sent consists of the length.int4 then the contents. - Note: This is called from Fastpath, and cannot be called from - client code. - - - - - - Report send size. - - Send size. - - - - Large Object. - - - - - Indicates a seek from the begining of a file. - - - - - Indicates a seek from the current position. - - - - - Indicates a seek from the end of a file. - - - - - This opens a large object. - If the object does not exist, then an NpgsqlException is thrown. - - FastPath API for the connection to use. - OID of the Large Object to open. - Mode of opening the large object - - - - OID getter. - - The OID of this LargeObject. - - - - This method closes the object. You must not call methods in this - object after this is called. - - - - - Reads some data from the object, and return as a byte[] array. - - Number of bytes to read. - Array containing data read. - - - - Reads some data from the object into an existing array. - - Destination array. - Offset within array. - Maximum number of bytes to read. - The number of bytes actually read. - - - - Writes an array to the object. - - Array to write. - - - - Writes some data from an array to the object. - - Destination array. - Offset within array. - Number of bytes to write. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object. - Either SEEK_SET, SEEK_CUR or SEEK_END. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object from begining. - - - - Report the current position within the object. - - The current position within the object. - - - - This method is inefficient, as the only way to find out the size of - the object is to seek to the end, record the current position, then - return to the original position. - A better method will be found in the future. - - The size of the large object. - - - - OID. - - - - - Large Object Manager. - - - - - This mode indicates we want to write to an object - - - - - This mode indicates we want to read an object - - - - - This mode is the default. It indicates we want read and write access to - - - - - Constructs the LargeObject API. - There should only be one LargeObjectManager per Connection. The - org.postgresql.Connection class keeps track of the various extension API's - and it's advised you use those to gain access, and not going direct. - - - - - - This opens an existing large object, based on its OID. This method - assumes that READ and WRITE access is required (the default). - - OID of large object. - LargeObject instance providing access to the object - - - - This opens an existing large object, based on its OID. - - OID of large object. - Mode of open. - - - - - This creates a large object, returning its OID. - - OID of new object. - - - - This creates a large object, returning its OID. - - Bitmask describing different attributes of the new object. - OID of new object. - - - - This deletes a large object. - - OID describing object to delete. - - - - This deletes a large object. - It is identical to the Delete() method, and is supplied as the C API uses unlink. - - OID describing object to delete. - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - Clone the current object. - - A new NativeToBackendTypeConverterOptions object. - - - - Clone the current object with a different OID/Name mapping. - - OID/Name mapping object to use in the new instance. - A new NativeToBackendTypeConverterOptions object. - - - - Provide event handlers to convert all native supported basic data types from their backend - text representation to a .NET object. - - - - - Convert UTF8 encoded text a string. - - - - - Byte array from bytea encoded as ASCII text, escaped or hex format. - - - - - Byte array from bytea encoded as binary. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql bit to a System.Boolean. - - - - - Convert a postgresql datetime to a System.DateTime. - - - - - Convert a postgresql date to a System.DateTime. - - - - - Convert a postgresql time to a System.DateTime. - - - - - Convert a postgresql money to a System.Decimal. - - - - - Convert a postgresql float4 or float8 to a System.Float or System.Double respectively. - - - - - Provide event handlers to convert extended native supported data types from their backend - text representation to a .NET object. - - - - - Convert a postgresql point to a System.NpgsqlPoint. - - - - - Convert a postgresql point to a System.RectangleF. - - - - - LDeg. - - - - - Path. - - - - - Polygon. - - - - - Circle. - - - - - Inet. - - - - - MAC Address. - - - - - interval - - - - - Provide event handlers to convert the basic native supported data types from - native form to backend representation. - - - - - Convert a string to UTF8 encoded text, escaped and quoted as required. - - - - - Convert a string to UTF8 encoded text. - - - - - Binary data, escaped and quoted as required. - - - - - Binary data with possible older style octal escapes, quoted. - - - - - Binary data in the new hex format (>= 9.0), quoted. - - - - - Binary data, raw. - - - - - Convert to a postgresql boolean text format. - - - - - Convert to a postgresql boolean binary format. - - - - - Convert to a postgresql binary int2. - - - - - Convert to a postgresql binary int4. - - - - - Convert to a postgresql binary int8. - - - - - Convert to a postgresql bit. - - - - - Convert to a postgresql timestamp. - - - - - Convert to a postgresql date. - - - - - Convert to a postgresql time. - - - - - Convert to a postgres money. - - - - - Convert to a postgres double with maximum precision. - - - - - Convert a System.Float to a postgres float4. - - - - - Convert a System.Double to a postgres float8. - - - - - Provide event handlers to convert extended native supported data types from - native form to backend representation. - - - - - Point. - - - - - Box. - - - - - LSeg. - - - - - Open path. - - - - - Polygon. - - - - - Convert to a postgres MAC Address. - - - - - Circle. - - - - - Convert to a postgres inet. - - - - - Convert to a postgres interval - - - - - Delegate called to convert the given backend text data to its native representation. - - - - - Delegate called to convert the given backend binary data to its native representation. - - - - - Represents a backend data type. - This class can be called upon to convert a backend field representation to a native object. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - fieldValueSize - Type modifier field sent from the backend. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - TypeSize - Type modifier field sent from the backend. - - - - Type OID provided by the backend server. - - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - NpgsqlDbType. - - - - - Provider type to convert fields of this type to. - - - - - System type to convert fields of this type to. - - - - - Reports whether a backend binary to native decoder is available for this type. - - - - - Delegate called to convert the given native data to its backand representation. - - - - - Represents a backend data type. - This class can be called upon to convert a native object to its backend field representation, - - - - - Returns an NpgsqlNativeTypeInfo for an array where the elements are of the type - described by the NpgsqlNativeTypeInfo supplied. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type name provided by the backend server. - DbType - Quote - NpgsqlDbType - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended queries). - - - - Perform a data conversion from a native object to - a backend representation. - DBNull and null values are handled differently depending if a plain query is used - When - - Native .NET object to be converted. - Specifies that the value should be formatted for the extended query syntax. - Options to guide serialization. If null, a default options set is used. - Specifies that the value should be formatted as an extended query array element. - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - DbType. - - - - - Apply quoting. - - - - - Use parameter size information. - - - - - Reports whether a native to backend binary encoder is available for this type. - - - - - Provide mapping between type OID, type name, and a NpgsqlBackendTypeInfo object that represents it. - - - - - Construct an empty mapping. - - - - - Copy constuctor. - - - - - Add the given NpgsqlBackendTypeInfo to this mapping. - - - - - Add a new NpgsqlBackendTypeInfo with the given attributes and conversion handlers to this mapping. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Make a shallow copy of this type mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type OID exists in this mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type OID, or null if none found. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type name, or null if none found. - - - - - Provide mapping between type Type, NpgsqlDbType and a NpgsqlNativeTypeInfo object that represents it. - - - - - Add the given NpgsqlNativeTypeInfo to this mapping. - - - - - Add a new NpgsqlNativeTypeInfo with the given attributes and conversion handlers to this mapping. - - Type name provided by the backend server. - NpgsqlDbType - DbType - Quote - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended query). - - - - Retrieve the NpgsqlNativeTypeInfo with the given NpgsqlDbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given DbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given Type. - - - - - Determine if a NpgsqlNativeTypeInfo with the given backend type name exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given NpgsqlDbType exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given Type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Represents a PostgreSQL Point type - - - - - Represents a PostgreSQL Line Segment type. - - - - - Represents a PostgreSQL Path type. - - - - - Represents a PostgreSQL Polygon type. - - - - - Represents a PostgreSQL Circle type. - - - - - Represents a PostgreSQL inet type. - - - - - Represents a PostgreSQL MacAddress type. - - - - - - - The macAddr parameter must contain a string that can only consist of numbers - and upper-case letters as hexadecimal digits. (See PhysicalAddress.Parse method on MSDN) - - - - This class contains helper methods for type conversion between - the .Net type system and postgresql. - - - - - A cache of basic datatype mappings keyed by server version. This way we don't - have to load the basic type mappings for every connection. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given DbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given System.Type. - - - - - This method is responsible to convert the byte[] received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - This method is responsible to convert the string received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - Create the one and only native to backend type map. - This map is used when formatting native data - types to backend representations. - - - - - This method creates (or retrieves from cache) a mapping between type and OID - of all natively supported postgresql data types. - This is needed as from one version to another, this mapping can be changed and - so we avoid hardcoding them. - - NpgsqlTypeMapping containing all known data types. The mapping must be - cloned before it is modified because it is cached; changes made by one connection may - effect another connection. - - - - - Attempt to map types by issuing a query against pg_type. - This function takes a list of NpgsqlTypeInfo and attempts to resolve the OID field - of each by querying pg_type. If the mapping is found, the type info object is - updated (OID) and added to the provided NpgsqlTypeMapping object. - - NpgsqlConnector to send query through. - Mapping object to add types too. - List of types that need to have OID's mapped. - - - - Summary description for NpgsqlQuery - - - - - For classes representing messages sent from the client to the server. - - - - - Set Cache Size. The default value is 20. - - - - - Lookup cached entity. null will returned if not match. - For both get{} and set{} apply LRU rule. - - key - - - - - The globally available text encoding used for frontend/backend communication. - - - - This class represents the base class for the state pattern design pattern - implementation. - - - This class represents the base class for the state pattern design pattern - implementation. - - - - - - This method is used by the states to change the state of the context. - - - - - Call ProcessBackendResponsesEnum(), and scan and discard all results. - - - - - This method is responsible to handle all protocol messages sent from the backend. - It holds all the logic to do it. - To exchange data, it uses a Mediator object from which it reads/writes information - to handle backend requests. - - - - - - Checks for context socket availability. - Socket.Poll supports integer as microseconds parameter. - This limits the usable command timeout value - to 2,147 seconds: (2,147 x 1,000,000 less than max_int). - In order to bypass this limit, the availability of - the socket is checked in 2,147 seconds cycles - - true, if for context socket availability was checked, false otherwise. - Context. - Select mode. - - - - Called from constructor of derived class. - - - - - Finalizer for HashAlgorithm - - - - - Computes the entire hash of all the bytes in the byte array. - - - - - When overridden in a derived class, drives the hashing function. - - - - - - - - When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created. - - - - - When overridden in a derived class, initializes the object to prepare for hashing. - - - - - Used for stream chaining. Computes hash as data passes through it. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - The buffer to write the copied data to. - At what point in the outputBuffer to write the data at. - - - - Used for stream chaining. Computes hash as data passes through it. Finishes off the hash. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - - - - Get whether or not the hash can transform multiple blocks at a time. - Note: MUST be overriden if descendant can transform multiple block - on a single call! - - - - - Gets the previously computed hash. - - - - - Returns the size in bits of the hash. - - - - - Must be overriden if not 1 - - - - - Must be overriden if not 1 - - - - - Common base class for all derived MD5 implementations. - - - - - Called from constructor of derived class. - - - - - Creates the default derived class. - - - - - C# implementation of the MD5 cryptographic hash function. - - - - - Creates a new MD5CryptoServiceProvider. - - - - - Drives the hashing function. - - Byte array containing the data to hash. - Where in the input buffer to start. - Size in bytes of the data in the buffer to hash. - - - - This finalizes the hash. Takes the data from the chaining variables and returns it. - - - - - Resets the class after use. Called automatically after hashing is done. - - - - - This is the meat of the hash function. It is what processes each block one at a time. - - Byte array to process data from. - Where in the byte array to start processing. - - - - Pads and then processes the final block. - - Buffer to grab data from. - Position in buffer in bytes to get data from. - How much data in bytes in the buffer to use. - - - - Implements for version 3 of the protocol. - - - - - Reads a row, field by field, allowing a DataRow to be built appropriately. - - - - - Marker interface which identifies a class which may take possession of a stream for the duration of - it's lifetime (possibly temporarily giving that possession to another class for part of that time. - - It inherits from IDisposable, since any such class must make sure it leaves the stream in a valid state. - - The most important such class is that compiler-generated from ProcessBackendResponsesEnum. Of course - we can't make that inherit from this interface, alas. - - - - - Marker interface which identifies a class which represents part of - a response from the server. - - - - - Reads part of a field, as needed (for - and - - - - - Adds further functionality to stream that is dependant upon the type of data read. - - - - - Completes the implementation of Streamer for char data. - - - - - Completes the implementation of Streamer for byte data. - - - - - This class represents a BackEndKeyData message received - from PostgreSQL - - - - - This class represents the Bind message sent to PostgreSQL - server. - - - - - - This class represents the CancelRequest message sent to PostgreSQL - server. - - - - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlCommand class. - - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query. - - The text of the query. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query and a NpgsqlConnection. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query, a NpgsqlConnection, and the NpgsqlTransaction. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - The NpgsqlTransaction in which the NpgsqlCommand executes. - - - - Used to execute internal commands. - - - - - Attempts to cancel the execution of a NpgsqlCommand. - - This Method isn't implemented yet. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Creates a new instance of an DbParameter object. - - An DbParameter object. - - - - Creates a new instance of a NpgsqlParameter object. - - A NpgsqlParameter object. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Internal query shortcut for use in cases where the number - of affected rows is of no interest. - - - - - Special adaptation of ExecuteBlind() that sets statement_timeout. - This exists to prevent Connector.SetBackendCommandTimeout() from calling Command.ExecuteBlind(), - which will cause an endless recursive loop. - - - Timeout in seconds. - - - - Executes a SQL statement against the connection and returns the number of rows affected. - - The number of rows affected if known; -1 otherwise. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader. - - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - Currently the CommandBehavior parameter is ignored. - - - - This method binds the parameters from parameters collection to the bind - message. - - - - - Executes the query, and returns the first column of the first row - in the result set returned by the query. Extra columns or rows are ignored. - - The first column of the first row in the result set, - or a null reference if the result set is empty. - - - - Creates a prepared version of the command on a PostgreSQL server. - - - - - This method checks the connection state to see if the connection - is set or it is open. If one of this conditions is not met, throws - an InvalidOperationException - - - - - This method substitutes the Parameters, if exist, in the command - to their actual values. - The parameter name format is :ParameterName. - - A version of CommandText with the Parameters inserted. - - - - Process this.commandText, trimming each distinct command and substituting paramater - tokens. - - - UTF8 encoded command ready to be sent to the backend. - - - - Append a region of a source command text to an output command, performing parameter token - substitutions. - - Stream to which to append output. - Command text. - - - false if the query has multiple statements which are not allowed - - - - Gets or sets the SQL statement or function (stored procedure) to execute at the data source. - - The Transact-SQL statement or stored procedure to execute. The default is an empty string. - - - - Gets or sets the wait time before terminating the attempt - to execute a command and generating an error. - - The time (in seconds) to wait for the command to execute. - The default is 20 seconds. - - - - Gets or sets a value indicating how the - CommandText property is to be interpreted. - - One of the CommandType values. The default is CommandType.Text. - - - - DB connection. - - - - - Gets or sets the NpgsqlConnection - used by this instance of the NpgsqlCommand. - - The connection to a data source. The default value is a null reference. - - - - DB parameter collection. - - - - - Gets the NpgsqlParameterCollection. - - The parameters of the SQL statement or function (stored procedure). The default is an empty collection. - - - - DB transaction. - - - - - Gets or sets the NpgsqlTransaction - within which the NpgsqlCommand executes. - - The NpgsqlTransaction. - The default value is a null reference. - - - - Gets or sets how command results are applied to the DataRow - when used by the Update - method of the DbDataAdapter. - - One of the UpdateRowSource values. - - - - Returns oid of inserted row. This is only updated when using executenonQuery and when command inserts just a single row. If table is created without oids, this will always be 0. - - - - - Returns whether this query will execute as a prepared (compiled) query. - - - - - Design time visible. - - - - - This class is responsible to create database commands for automatic insert, update and delete operations. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The adapter. - - - - - This method is reponsible to derive the command parameter list with values obtained from function definition. - It clears the Parameters collection of command. Also, if there is any parameter type which is not supported by Npgsql, an InvalidOperationException will be thrown. - Parameters name will be parameter1, parameter2, ... - - NpgsqlCommand whose function parameters will be obtained. - - - - Gets the automatically generated object required - to perform insertions at the data source. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated object required to perform insertions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform updates at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform updates. - - - - - Gets the automatically generated object required to perform updates - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform updates. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform deletions at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform deletions. - - - - - Gets the automatically generated object required to perform deletions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform deletions. - - - - - Applies the parameter information. - - The parameter. - The row. - Type of the statement. - if set to true [where clause]. - - - - Returns the name of the specified parameter in the format of @p#. - - The number to be included as part of the parameter's name.. - - The name of the parameter with the specified number appended as part of the parameter name. - - - - - Returns the full parameter name, given the partial parameter name. - - The partial name of the parameter. - - The full parameter name corresponding to the partial parameter name requested. - - - - - Returns the placeholder for the parameter in the associated SQL statement. - - The number to be included as part of the parameter's name. - - The name of the parameter with the specified number appended. - - - - - Registers the to handle the event for a . - - The to be used for the update. - - - - Adds an event handler for the event. - - The sender - A instance containing information about the event. - - - - Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier, including properly escaping any embedded quotes in the identifier. - - The original unquoted identifier. - - The quoted version of the identifier. Embedded quotes within the identifier are properly escaped. - - - - - Unquoted identifier parameter cannot be null - - - - Given a quoted identifier, returns the correct unquoted form of that identifier, including properly un-escaping any embedded quotes in the identifier. - - The identifier that will have its embedded quotes removed. - - The unquoted identifier, with embedded quotes properly un-escaped. - - - - - Quoted identifier parameter cannot be null - - - - Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The beginning character or characters to use. The default is an empty string. - - - - - - - - Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The ending character or characters to use. The default is an empty string. - - - - - - - - Represents the method that handles the Notice events. - - The source of the event. - A NpgsqlNoticeEventArgs that contains the event data. - - - - Represents the method that handles the Notification events. - - The source of the event. - A NpgsqlNotificationEventArgs that contains the event data. - - - - This class represents a connection to a - PostgreSQL server. - - - - - Initializes a new instance of the - NpgsqlConnection class. - - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - An DbTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Begins a database transaction. - - A NpgsqlTransaction - object representing the new transaction. - - Currently there's no support for nested transactions. - - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - A NpgsqlTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Opens a database connection with the property settings specified by the - ConnectionString. - - - - - This method changes the current database by disconnecting from the actual - database and connecting to the specified. - - The name of the database to use in place of the current database. - - - - Releases the connection to the database. If the connection is pooled, it will be - made available for re-use. If it is non-pooled, the actual connection will be shutdown. - - - - - When a connection is closed within an enclosing TransactionScope and the transaction - hasn't been promoted, we defer the actual closing until the scope ends. - - - - - Creates and returns a DbCommand - object associated with the IDbConnection. - - A DbCommand object. - - - - Creates and returns a NpgsqlCommand - object associated with the NpgsqlConnection. - - A NpgsqlCommand object. - - - - Releases all resources used by the - NpgsqlConnection. - - true when called from Dispose(); - false when being called from the finalizer. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Returns a copy of the NpgsqlConnectionStringBuilder that contains the parsed connection string values. - - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - Write each key/value pair in the connection string to the log. - - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Refresh the cached _connectionString whenever the builder settings change - - - - - Returns the supported collections - - - - - Returns the schema collection specified by the collection name. - - The collection name. - The collection specified. - - - - Returns the schema collection specified by the collection name filtered by the restrictions. - - The collection name. - - The restriction values to filter the results. A description of the restrictions is contained - in the Restrictions collection. - - The collection specified. - - - - Clear connection pool. - - - - - Clear all connection pools. - - - - - Enlist transation. - - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets or sets the string used to connect to a PostgreSQL database. - Valid values are: -
    -
  • - Server: Address/Name of Postgresql Server; -
  • -
  • - Port: Port to connect to; -
  • -
  • - Protocol: Protocol version to use, instead of automatic; Integer 2 or 3; -
  • -
  • - Database: Database name. Defaults to user name if not specified; -
  • -
  • - User Id: User name; -
  • -
  • - Password: Password for clear text authentication; -
  • -
  • - SSL: True or False. Controls whether to attempt a secure connection. Default = False; -
  • -
  • - Pooling: True or False. Controls whether connection pooling is used. Default = True; -
  • -
  • - MinPoolSize: Min size of connection pool; -
  • -
  • - MaxPoolSize: Max size of connection pool; -
  • -
  • - Timeout: Time to wait for connection open in seconds. Default is 15. -
  • -
  • - CommandTimeout: Time to wait for command to finish execution before throw an exception. In seconds. Default is 20. -
  • -
  • - Sslmode: Mode for ssl connection control. Can be Prefer, Require, Allow or Disable. Default is Disable. Check user manual for explanation of values. -
  • -
  • - ConnectionLifeTime: Time to wait before closing unused connections in the pool in seconds. Default is 15. -
  • -
  • - SyncNotification: Specifies if Npgsql should use synchronous notifications. -
  • -
  • - SearchPath: Changes search path to specified and public schemas. -
  • -
-
- The connection string that includes the server name, - the database name, and other parameters needed to establish - the initial connection. The default value is an empty string. - -
- - - Backend server host name. - - - - - Backend server port. - - - - - If true, the connection will attempt to use SSL. - - - - - Gets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets the name of the current database or the database to be used after a connection is opened. - - The name of the current database or the name of the database to be - used after a connection is opened. The default value is the empty string. - - - - Whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Gets the database server name. - - - - - Gets flag indicating if we are using Synchronous notification or not. - The default value is false. - - - - - Gets the current state of the connection. - - A bitwise combination of the ConnectionState values. The default is Closed. - - - - Gets whether the current state of the connection is Open or Closed - - ConnectionState.Open or ConnectionState.Closed - - - - Compatibility version. - - - - - Version of the PostgreSQL backend. - This can only be called when there is an active connection. - - - - - PostgreSQL server version. - - - - - Protocol version in use. - This can only be called when there is an active connection. - Always retuna Version3 - - - - - Process id of backend server. - This can only be called when there is an active connection. - - - - - Report whether the backend is expecting standard conformant strings. - In version 8.1, Postgres began reporting this value (false), but did not actually support standard conformant strings. - In version 8.2, Postgres began supporting standard conformant strings, but defaulted this flag to false. - As of version 9.1, this flag defaults to true. - - - - - Report whether the backend understands the string literal E prefix (>= 8.1). - - - - - Report whether the backend understands the hex byte format (>= 9.0). - - - - - The connector object connected to the backend. - - - - - Gets the NpgsqlConnectionStringBuilder containing the parsed connection string values. - - - - - User name. - - - - - Use extended types. - - - - - Password. - - - - - Determine if connection pooling will be used for this connection. - - - - - DB provider factory. - - - - - Return an exact copy of this NpgsqlConnectionString. - - - - - No integrated security if we're on mono and .NET 4.5 because of ClaimsIdentity, - see https://github.com/npgsql/Npgsql/issues/133 - - - - - This function will set value for known key, both private member and base[key]. - - - - - value, coerced as needed to the stored type. - - - - The function will modify private member only, not base[key]. - - - - value, coerced as needed to the stored type. - - - - The function will access private member only, not base[key]. - - - value. - - - - Clear the member and assign them to the default value. - - - - - Gets or sets the backend server host name. - - - - - Gets or sets the backend server port. - - - - - Gets or sets the name of the database to be used after a connection is opened. - - The name of the database to be - used after a connection is opened. - - - - Gets or sets the login user name. - - - - - Gets or sets the login password as a UTF8 encoded byte array. - - - - - Sets the login password as a string. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets or sets the schema search path. - - - - - Gets or sets a value indicating whether connection pooling should be used. - - - - - Gets or sets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets or sets the minimum connection pool size. - - - - - Gets or sets the maximum connection pool size. - - - - - Gets or sets a value indicating whether to listen for notifications and report them between command activity. - - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets or sets a value indicating whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Compatibilty version. When possible, behaviour caused by breaking changes will be preserved - if this version is less than that where the breaking change was introduced. - - - - - Gets or sets the ootional application name parameter to be sent to the backend during connection initiation. - - - - - Gets or sets a value indicating whether to silently Prepare() all commands before execution. - - - - - Gets or sets the specified backend communication protocol version. - - - - - Gets the backend encoding. Always returns "UTF8". - - - - - Case insensative accessor for indivual connection string values. - - - - - Set both ImplicitDefault and ExplicitDefault to the 's default value. - - - - - - - - Set ImplicitDefault to the default value of 's type, - and ExplicitDefault to . - - - - - - - - Represents the method that allows the application to provide a certificate collection to be used for SSL clien authentication - - A X509CertificateCollection to be filled with one or more client certificates. - - - - Represents the method that is called to validate the certificate provided by the server during an SSL handshake - - The server's certificate - The certificate chain containing the certificate's CA and any intermediate authorities - Any errors that were detected - - - - !!! Helper class, for compilation only. - Connector implements the logic for the Connection Objects to - access the physical connection to the database, and isolate - the application developer from connection pooling internals. - - - - - Constructor. - - Connection string. - Pooled - Controls whether the connector can be shared. - - - - This method checks if the connector is still ok. - We try to send a simple query text, select 1 as ConnectionTest; - - - - - This method is responsible for releasing all resources associated with this Connector. - - - - - This method is responsible to release all portals used by this Connector. - - - - - Modify the backend statement_timeout value if needed. - - New timeout - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - This method is required to set all the version dependent features flags. - SupportsPrepare means the server can use prepared query plans (7.3+) - - - - - Opens the physical connection to the server. - - Usually called by the RequestConnector - Method of the connection pool manager. - - - - Closes the physical connection to the server. - - - - - Returns next portal index. - - - - - Returns next plan index. - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets the current state of the connection. - - - - - Return Connection String. - - - - - Version of backend server this connector is connected to. - - - - - The physical connection socket to the backend. - - - - - The physical connection stream to the backend. - - - - - The top level stream to the backend. - - - - - Reports if this connector is fully connected. - - - - - The connection mediator. - - - - - Report if the connection is in a transaction. - - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - This class manages all connector objects, pooled AND non-pooled. - - - - Unique static instance of the connector pool - mamager. - - - Map of index to unused pooled connectors, avaliable to the - next RequestConnector() call. - This hashmap will be indexed by connection string. - This key will hold a list of queues of pooled connectors available to be used. - - - Timer for tracking unused connections in pools. - - - - Searches the shared and pooled connector lists for a - matching connector object or creates a new one. - - The NpgsqlConnection that is requesting - the connector. Its ConnectionString will be used to search the - pool for available connectors. - A connector object. - - - - Find a pooled connector. Handle shared/non-shared here. - - - - - Releases a connector, possibly back to the pool for future use. - - - Pooled connectors will be put back into the pool if there is room. - Shared connectors should just have their use count decremented - since they always stay in the shared pool. - - Connection to which the connector is leased. - The connector to release. - - - - Release a pooled connector. Handle shared/non-shared here. - - - - - Find an available pooled connector in the non-shared pool, or create - a new one if none found. - - - - - Put a pooled connector into the pool queue. - - Connection is leased to. - Connector to pool - - - - A queue with an extra Int32 for keeping track of busy connections. - - - - - Connections available to the end user - - - - - Connections currently in use - - - - - Represents information about COPY operation data transfer format as returned by server. - - - - - Only created when a CopyInResponse or CopyOutResponse is received by NpgsqlState.ProcessBackendResponses() - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Represents a PostgreSQL COPY FROM STDIN operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to read data from (if provided by user) - or for writing it (when generated by driver). - Eg. new NpgsqlCopyIn("COPY mytable FROM STDIN", connection, streamToRead).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is run upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is executed upon Start() and all data from fromStream is passed to it as copy data. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, it will be flushed to server as copy data, and operation will be finished immediately. - Otherwise the CopyStream member can be used for writing copy data to server and operation finished with a call to End() or Cancel(). - - - - - Called after writing all data to CopyStream to successfully complete this copy operation. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Will do nothing if current operation is not active. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start(). - User may provide a stream to constructor; it is used to pass to server all data read from it. - Otherwise, call to Start() sets this to a writable NpgsqlCopyInStream that passes all data written to it to server. - In latter case this is only available while the copy operation is active and null otherwise. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields expected on each input row if this operation is currently active, otherwise -1 - - - - - The Command used to execute this copy operation. - - - - - Set before a COPY IN query to define size of internal buffer for reading from given CopyStream. - - - - - Represents an ongoing COPY FROM STDIN operation. - Provides methods to push data to server and end or cancel the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyInResponse. - If CopyStream is already set, it is used to read data to push to server, after which the copy is completed. - Otherwise CopyStream is set to a writable NpgsqlCopyInStream that calls SendCopyData each time it is written to. - - - - - Sends given packet to server as a CopyData message. - Does not check for notifications! Use another thread for that. - - - - - Sends CopyDone message to server. Handles responses, ie. may throw an exception. - - - - - Sends CopyFail message to server. Handles responses, ie. should always throw an exception: - in CopyIn state the server responds to CopyFail with an error response; - outside of a CopyIn state the server responds to CopyFail with an error response; - without network connection or whatever, there's going to eventually be a failure, timeout or user intervention. - - - - - Copy format information returned from server. - - - - - Stream for writing data to a table on a PostgreSQL version 7.4 or newer database during an active COPY FROM STDIN operation. - Passes data exactly as is and when given, so see to it that you use server encoding, correct format and reasonably sized writes! - - - - - Created only by NpgsqlCopyInState.StartCopy() - - - - - Successfully completes copying data to server. Returns after operation is finished. - Does nothing if this stream is not the active copy operation writer. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Does nothing if this stream is not the active copy operation writer. - - - - - Writes given bytes to server. - Fails if this stream is not the active copy operation writer. - - - - - Flushes stream contents to server. - Fails if this stream is not the active copy operation writer. - - - - - Not readable - - - - - Not seekable - - - - - Not supported - - - - - True while this stream can be used to write copy data to server - - - - - False - - - - - True - - - - - False - - - - - Number of bytes written so far - - - - - Number of bytes written so far; not settable - - - - - Represents a PostgreSQL COPY TO STDOUT operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to write results to (if provided by user) - or for reading the results (when generated by driver). - Eg. new NpgsqlCopyOut("COPY (SELECT * FROM mytable) TO STDOUT", connection, streamToWrite).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is run upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is executed upon Start() and all requested copy data is written to toStream immediately. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, all copy data from server will be written to it, and operation will be finished immediately. - Otherwise the CopyStream member can be used for reading copy data from server until no more data is available. - - - - - Flush generated CopyStream at once. Effectively reads and discard all the rest of copy data from server. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start() - - - - - The Command used to execute this copy operation. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Faster alternative to using the generated CopyStream. - - - - - Represents an ongoing COPY TO STDOUT operation. - Provides methods to read data from server or end the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyOutResponse. - If CopyStream is already set, it is used to write data received from server, after which the copy ends. - Otherwise CopyStream is set to a readable NpgsqlCopyOutStream that receives data from server. - - - - - Called from NpgsqlOutStream.Read to read copy data from server. - - - - - Copy format information returned from server. - - - - - Stream for reading data from a table or select on a PostgreSQL version 7.4 or newer database during an active COPY TO STDOUT operation. - Passes data exactly as provided by the server. - - - - - Created only by NpgsqlCopyOutState.StartCopy() - - - - - Discards copy data as long as server pushes it. Returns after operation is finished. - Does nothing if this stream is not the active copy operation reader. - - - - - Not writable. - - - - - Not flushable. - - - - - Copies data read from server to given byte buffer. - Since server returns data row by row, length will differ each time, but it is only zero once the operation ends. - Can be mixed with calls to the more efficient NpgsqlCopyOutStream.Read() : byte[] though that would not make much sense. - - - - - Not seekable - - - - - Not supported - - - - - Returns a whole row of data from server without extra work. - If standard Stream.Read(...) has been called before, it's internal buffers remains are returned. - - - - - True while this stream can be used to read copy data from server - - - - - True - - - - - False - - - - - False - - - - - Number of bytes read so far - - - - - Number of bytes read so far; can not be set. - - - - - Writes given objects into a stream for PostgreSQL COPY in default copy format (not CSV or BINARY). - - - - - Default delimiter. - - - - - Default separator. - - - - - Default null. - - - - - Default escape. - - - - - Default quote. - - - - - Default buffer size. - - - - - Constructor. - - - - - - Flush buffers. - - - - - Flush rows. - - - - - Flush fields. - - - - - Close the serializer. - - - - - Escape sequence for the given character. - - - - - - - Make room for bytes. - - - - - - Add bytes. - - - - - - End row. - - - - - Prefix field. - - - - - Field added. - - - - - Add null. - - - - - Add string. - - - - - - add Int32. - - - - - - Add Int64. - - - - - - Add number. - - - - - - Add bool - - - - - - Add DateTime. - - - - - - Report whether the serializer is active. - - - - - To Stream. - - - - - Delimiter. - - - - - Separator. - - - - - Escape. - - - - - Null. - - - - - Buffer size. - - - - - Report whether space remains in the buffer. - - - - - Strings to escape. - - - - - Escape sequence bytes. - - - - - Represents the method that handles the RowUpdated events. - - The source of the event. - A NpgsqlRowUpdatedEventArgs that contains the event data. - - - - Represents the method that handles the RowUpdating events. - - The source of the event. - A NpgsqlRowUpdatingEventArgs that contains the event data. - - - - This class represents an adapter from many commands: select, update, insert and delete to fill Datasets. - - - - - Default constructor. - - - - - Constructor. - - - - - - Constructor. - - - - - - - Constructor. - - - - - - - Create row updated event. - - - - - - - - - - Create row updating event. - - - - - - - - - - Raise the RowUpdated event. - - - - - - Raise the RowUpdating event. - - - - - - Row updated event. - - - - - Row updating event. - - - - - Delete command. - - - - - Select command. - - - - - Update command. - - - - - Insert command. - - - - - Provides a means of reading a forward-only stream of rows from a PostgreSQL backend. This class cannot be inherited. - - - - - Return the data type name of the column at index . - - - - - Return the data type of the column at index . - - - - - Return the Npgsql specific data type of the column at requested ordinal. - - column position - Appropriate Npgsql type for column. - - - - Return the column name of the column at index . - - - - - Return the data type OID of the column at index . - - FIXME: Why this method returns String? - - - - Has ordinal. - - - - - - - Return the column name of the column named . - - - - - Return the data DbType of the column at index . - - - - - Return the data NpgsqlDbType of the column at index . - - - - - Get specified field value. - /// - - - - - - Get the value of a column as a . - If the differences between and - in handling of days and months is not important to your application, use - instead. - - Index of the field to find. - value of the field. - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Send closed event. - - - - - Gets the value of a column converted to a Guid. - - - - - Gets the value of a column as Int16. - - - - - Gets the value of a column as Int32. - - - - - Gets the value of a column as Int64. - - - - - Gets the value of a column as Single. - - - - - Gets the value of a column as Double. - - - - - Gets the value of a column as String. - - - - - Gets the value of a column as Decimal. - - - - - Gets the value of a column as TimeSpan. - - - - - Copy values from each column in the current row into . - - Destination for column values. - The number of column values copied. - - - - Copy values from each column in the current row into . - - An array appropriately sized to store values from all columns. - The number of column values copied. - - - - Gets the value of a column as Boolean. - - - - - Gets the value of a column as Byte. - - - - - Gets the value of a column as Char. - - - - - Gets the value of a column as DateTime. - - - - - Returns a System.Data.DataTable that describes the column metadata of the DataReader. - - - - - This methods parses the command text and tries to get the tablename - from it. - - - - - Get enumerator. - - - - - - Is raised whenever Close() is called. - - - - - Gets the number of columns in the current row. - - - - - Gets the value of a column in its native format. - - - - - Gets the value of a column in its native format. - - - - - Gets a value indicating the depth of nesting for the current row. Always returns zero. - - - - - Gets a value indicating whether the data reader is closed. - - - - - Contains the column names as the keys - - - - - Contains all unique columns - - - - - This is the primary implementation of NpgsqlDataReader. It is the one used in normal cases (where the - preload-reader option is not set in the connection string to resolve some potential backwards-compatibility - issues), the only implementation used internally, and in cases where CachingDataReader is used, it is still - used to do the actual "leg-work" of turning a response stream from the server into a datareader-style - object - with CachingDataReader then filling it's cache from here. - - - - - Iterate through the objects returned through from the server. - If it's a CompletedResponse the rowsaffected count is updated appropriately, - and we iterate again, otherwise we return it (perhaps updating our cache of pending - rows if appropriate). - - The next we will deal with. - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Closes the data reader object. - - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Advances the data reader to the next row. - - True if the reader was advanced, otherwise false. - - - - Return the value of the column at index . - - - - - Gets raw data from a column. - - - - - Gets raw data from a column. - - - - - Report whether the value in a column is DBNull. - - - - - Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. - - - - - Indicates if NpgsqlDatareader has rows to be read. - - - - - Provides an implementation of NpgsqlDataReader in which all data is pre-loaded into memory. - This operates by first creating a ForwardsOnlyDataReader as usual, and then loading all of it's - Rows into memory. There is a general principle that when there is a trade-off between a class design that - is more efficient and/or scalable on the one hand and one that is less efficient but has more functionality - (in this case the internal-only functionality of caching results) that one can build the less efficent class - from the most efficient without significant extra loss in efficiency, but not the other way around. The relationship - between ForwardsOnlyDataReader and CachingDataReader is an example of this). - Since the interface presented to the user is still forwards-only, queues are used to - store this information, so that dequeueing as we go we give the garbage collector the best opportunity - possible to reclaim any memory that is no longer in use. - ForwardsOnlyDataReader being used to actually - obtain the information from the server means that the "leg-work" is still only done (and need only be - maintained) in one place. - This class exists to allow for certain potential backwards-compatibility issues to be resolved - with little effort on the part of affected users. It is considerably less efficient than ForwardsOnlyDataReader - and hence never used internally. - - - - - This is the base class for NpgsqlDescribeStatement and NpgsqlDescribePortal. - - - - - - This class represents the Statement Describe message sent to PostgreSQL - server. - - - - - - This class represents the Portal Describe message sent to PostgreSQL - server. - - - - - - EventArgs class to send Notice parameters, which are just NpgsqlError's in a lighter context. - - - - - Notice information. - - - - - This class represents the ErrorResponse and NoticeResponse - message sent from PostgreSQL server. - - - - - Return a string representation of this error object. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Terse error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Internal query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Backend protocol version in use. - - - - - Error and notice message field codes - - - - - Severity: the field contents are ERROR, FATAL, or PANIC (in an error message), - or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a localized - translation of one of these. Always present. - - - - - Code: the SQLSTATE code for the error (see Appendix A). Not localizable. Always present. - - - - - Message: the primary human-readable error message. This should be accurate - but terse (typically one line). Always present. - - - - - Detail: an optional secondary error message carrying more detail about the problem. - Might run to multiple lines. - - - - - Hint: an optional suggestion what to do about the problem. This is intended to differ - from Detail in that it offers advice (potentially inappropriate) rather than hard facts. - Might run to multiple lines. - - - - - Position: the field value is a decimal ASCII integer, indicating an error cursor - position as an index into the original query string. The first character has index 1, - and positions are measured in characters not bytes. - - - - - Internal position: this is defined the same as the P field, but it is used when the - cursor position refers to an internally generated command rather than the one submitted - by the client. - The q field will always appear when this field appears. - - - - - Internal query: the text of a failed internally-generated command. - This could be, for example, a SQL query issued by a PL/pgSQL function. - - - - - Where: an indication of the context in which the error occurred. - Presently this includes a call stack traceback of active procedural language functions - and internally-generated queries. The trace is one entry per line, most recent first. - - - - - Schema name: if the error was associated with a specific database object, - the name of the schema containing that object, if any. - - - - - Table name: if the error was associated with a specific table, the name of the table. - (Refer to the schema name field for the name of the table's schema.) - - - - - Column name: if the error was associated with a specific table column, the name of the column. - (Refer to the schema and table name fields to identify the table.) - - - - - Data type name: if the error was associated with a specific data type, the name of the data type. - (Refer to the schema name field for the name of the data type's schema.) - - - - - Constraint name: if the error was associated with a specific constraint, the name of the constraint. - Refer to fields listed above for the associated table or domain. - (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.) - - - - - File: the file name of the source-code location where the error was reported. - - - - - Line: the line number of the source-code location where the error was reported. - - - - - Routine: the name of the source-code routine reporting the error. - - - - - The level of verbosity of the NpgsqlEventLog - - - - - Don't log at all - - - - - Only log the most common issues - - - - - Log everything - - - - - This class handles all the Npgsql event and debug logging - - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - - This method is obsolete and should no longer be used. - It is likely to be removed in future versions of Npgsql - - The message to write to the event log - The minimum LogLevel for which this message should be logged. - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - The ResourceManager to get the localized resources - The name of the resource that should be fetched by the ResourceManager - The minimum LogLevel for which this message should be logged. - The additional parameters that shall be included into the log-message (must be compatible with the string in the resource): - - - - Writes the default log-message for the action of calling the Get-part of an Indexer to the log file. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - - - - Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - The value the Indexer is set to - - - - Writes the default log-message for the action of calling the Get-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - - - - Writes the default log-message for the action of calling the Set-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - The value the Property is set to - - - - Writes the default log-message for the action of calling a Method without Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - - - - Writes the default log-message for the action of calling a Method with one Argument to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the Argument of the Method - - - - Writes the default log-message for the action of calling a Method with two Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - - - - Writes the default log-message for the action of calling a Method with three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - The value of the third Argument of the Method - - - - Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - A Object-Array with zero or more Ojects that are Arguments of the Method. - - - - Sets/Returns the filename to use for logging. - - The filename of the current Log file. - - - - Sets/Returns whether Log messages should be echoed to the console - - true if Log messages are echoed to the console, otherwise false - - - - The exception that is thrown when the PostgreSQL backend reports errors. - - - - - Construct a backend error exception based on a list of one or more - backend errors. The basic Exception.Message will be built from the - first (usually the only) error in the list. - - - - - Get object data. - - - - - - - Format a .NET style exception string. - Include all errors in the list, including any hints. - - - - - Append a line to the given Stream, first checking for zero-length. - - - - - Provide access to the entire list of errors provided by the PostgreSQL backend. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Basic error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Returns the entire list of errors provided by the PostgreSQL backend. - - - - - This class represents the Execute message sent to PostgreSQL - server. - - - - - - A factory to create instances of various Npgsql objects. - - - - - Creates an NpgsqlCommand object. - - - - - This class represents the Flush message sent to PostgreSQL - server. - - - - - - For classes representing simple messages, - consisting only of a message code and length identifier, - sent from the client to the server. - - - - - This class is responsible for serving as bridge between the backend - protocol handling and the core classes. It is used as the mediator for - exchanging data generated/sent from/to backend. - - - - - - The current command timeout on the backend. This is set via "SET statement_timeout = (milliseconds)". - A value of -1 means the backend's timeout value is unknown because it has not yet been set. - - - - - EventArgs class to send Notification parameters. - - - - - Process ID of the PostgreSQL backend that sent this notification. - - - - - Condition that triggered that notification. - - - - - Additional Information From Notifiying Process (for future use, currently postgres always sets this to an empty string) - - - - - This class represents a parameter to a command that will be sent to server - - - - - Initializes a new instance of the NpgsqlParameter class. - - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and a value of the new NpgsqlParameter. - - The m_Name of the parameter to map. - An Object that is the value of the NpgsqlParameter. - -

When you specify an Object - in the value parameter, the DbType is - inferred from the .NET Framework type of the Object.

-

When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. - This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. - Use Convert.ToInt32(value) for example to have compiler calling the correct constructor.

-
-
- - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and the data type. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Reset DBType. - - - - - Creates a new NpgsqlParameter that - is a copy of the current instance. - - A new NpgsqlParameter that is a copy of this instance. - - - - The collection to which this parameter belongs, if any. - - - - - Gets or sets the maximum number of digits used to represent the - Value property. - - The maximum number of digits used to represent the - Value property. - The default value is 0, which indicates that the data provider - sets the precision for Value. - - - - Whether to use an explicit cast when included in a query. - - - - - Gets or sets the number of decimal places to which - Value is resolved. - - The number of decimal places to which - Value is resolved. The default is 0. - - - - Gets or sets the maximum size, in bytes, of the data within the column. - - The maximum size, in bytes, of the data within the column. - The default value is inferred from the parameter value. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets a value indicating whether the parameter is input-only, - output-only, bidirectional, or a stored procedure return value parameter. - - One of the ParameterDirection - values. The default is Input. - - - - Gets or sets a value indicating whether the parameter accepts null values. - - true if null values are accepted; otherwise, false. The default is false. - - - - Gets or sets the m_Name of the NpgsqlParameter. - - The m_Name of the NpgsqlParameter. - The default is an empty string. - - - - The m_Name scrubbed of any optional marker - - - - - Gets or sets the m_Name of the source column that is mapped to the - DataSet and used for loading or - returning the Value. - - The m_Name of the source column that is mapped to the - DataSet. The default is an empty string. - - - - Gets or sets the DataRowVersion - to use when loading Value. - - One of the DataRowVersion values. - The default is Current. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Source column mapping. - - - - - Represents a collection of parameters relevant to a NpgsqlCommand - as well as their respective mappings to columns in a DataSet. - This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlParameterCollection class. - - - - - Invalidate the hash lookup tables. This should be done any time a change - may throw the lookups out of sync with the list. - - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The index of the new NpgsqlParameter object. - - - - Obsolete. Use AddWithValue instead. - - - Use caution when using this overload of the - Add method to specify integer parameter values. - Because this overload takes a value of type Object, - you must convert the integral value to an Object - type when the value is zero, as the following C# example demonstrates. - parameters.Add(":pname", Convert.ToInt32(0)); - If you do not perform this conversion, the compiler will assume you - are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload. - - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The name of the source column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the parameter name and the data type. - - The name of the parameter. - One of the DbType values. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, and the column length. - - The name of the parameter. - One of the DbType values. - The length of the column. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, the column length, and the source column name. - - The name of the parameter. - One of the DbType values. - The length of the column. - The name of the source column. - The index of the new NpgsqlParameter object. - - - - Removes the specified NpgsqlParameter from the collection using the parameter name. - - The name of the NpgsqlParameter object to retrieve. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - true if the collection contains the parameter; otherwise, false. - - - - Gets the location of the NpgsqlParameter in the collection with a specific parameter name. - - The name of the NpgsqlParameter object to find. - The zero-based location of the NpgsqlParameter in the collection. - - - - Removes the specified NpgsqlParameter from the collection using a specific index. - - The zero-based index of the parameter. - - - - Inserts a NpgsqlParameter into the collection at the specified index. - - The zero-based index where the parameter is to be inserted within the collection. - The NpgsqlParameter to add to the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The name of the NpgsqlParameter to remove from the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The NpgsqlParameter to remove from the collection. - - - - Gets a value indicating whether a NpgsqlParameter exists in the collection. - - The value of the NpgsqlParameter object to find. - true if the collection contains the NpgsqlParameter object; otherwise, false. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - A reference to the requested parameter is returned in this out param if it is found in the list. This value is null if the parameter is not found. - true if the collection contains the parameter and param will contain the parameter; otherwise, false. - - - - Removes all items from the collection. - - - - - Gets the location of a NpgsqlParameter in the collection. - - The value of the NpgsqlParameter object to find. - The zero-based index of the NpgsqlParameter object in the collection. - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The zero-based index of the new NpgsqlParameter object. - - - - Copies NpgsqlParameter objects from the NpgsqlParameterCollection to the specified array. - - An Array to which to copy the NpgsqlParameter objects in the collection. - The starting index of the array. - - - - Returns an enumerator that can iterate through the collection. - - An IEnumerator that can be used to iterate through the collection. - - - - Add an Array of parameters to the collection. - - Parameters to add. - - - - Get parameter. - - - - - - - Get parameter. - - - - - - - Set parameter. - - - - - - - Set parameter. - - - - - - - In methods taking an object as argument this method is used to verify - that the argument has the type NpgsqlParameter - - The object to verify - - - - Report the offset within the collection of the given parameter. - - Parameter to find. - Index of the parameter, or -1 if the parameter is not present. - - - - Insert the specified parameter into the collection. - - Index of the existing parameter before which to insert the new one. - Parameter to insert. - - - - Report whether the specified parameter is present in the collection. - - Parameter to find. - True if the parameter was found, otherwise false. - - - - Remove the specified parameter from the collection. - - Parameter to remove. - True if the parameter was found and removed, otherwise false. - - - - Convert collection to a System.Array. - - Destination array. - Starting index in destination array. - - - - Convert collection to a System.Array. - - NpgsqlParameter[] - - - - Gets the NpgsqlParameter with the specified name. - - The name of the NpgsqlParameter to retrieve. - The NpgsqlParameter with the specified name, or a null reference if the parameter is not found. - - - - Gets the NpgsqlParameter at the specified index. - - The zero-based index of the NpgsqlParameter to retrieve. - The NpgsqlParameter at the specified index. - - - - Report whether the collection is read only. Always false. - - - - - Report whether the collection is fixed size. Always false. - - - - - Report whether the collection is synchronized. - - - - - Gets the number of NpgsqlParameter objects in the collection. - - The number of NpgsqlParameter objects in the collection. - - - - Sync root. - - - - - This class represents the ParameterStatus message sent from PostgreSQL - server. - - - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - This class represents a PasswordPacket message sent to backend - PostgreSQL. - - - - - Used when a connection is closed - - - - - This is the abstract base class for NpgsqlAsciiRow and NpgsqlBinaryRow. - - - - - The index of the current field in the stream, i.e. the one that hasn't - been read yet - - - - - This class represents a RowDescription message sent from - the PostgreSQL. - - - - - - This struct represents the internal data of the RowDescription message. - - - - - Provides the underlying mechanism for reading schema information. - - - - - Returns the MetaDataCollections that lists all possible collections. - - The MetaDataCollections - - - - Returns the Restrictions that contains the meaning and position of the values in the restrictions array. - - The Restrictions - - - - Returns the Databases that contains a list of all accessable databases. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Databases - - - - Returns the Tables that contains table and view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Tables - - - - Returns the Columns that contains information about columns in tables. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Columns. - - - - Returns the Views that contains view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Views - - - - Returns the Users containing user names and the sysid of those users. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Users. - - - - This class represents a StartupPacket message of PostgreSQL - protocol. - - - - - - Represents a completed response message. - - - - - This class represents the Sync message sent to PostgreSQL - server. - - - - - - Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited. - - - - - Dispose. - - - - - - Commits the database transaction. - - - - - Rolls back a transaction from a pending state. - - - - - Rolls back a transaction from a pending savepoint state. - - - - - Creates a transaction save point. - - - - - Cancel the transaction without telling the backend about it. This is - used to make the transaction go away when closing a connection. - - - - - Gets the NpgsqlConnection - object associated with the transaction, or a null reference if the - transaction is no longer valid. - - The NpgsqlConnection - object associated with the transaction. - - - - DB connection. - - - - - Specifies the IsolationLevel for this transaction. - - The IsolationLevel for this transaction. - The default is ReadCommitted. - - - - This class provides many util methods to handle - reading and writing of PostgreSQL protocol messages. - - - - - This method takes a ProtocolVersion and returns an integer - version number that the Postgres backend will recognize in a - startup packet. - - - - - This method takes a version string as returned by SELECT VERSION() and returns - a valid version string ("7.2.2" for example). - This is only needed when running protocol version 2. - This does not do any validity checks. - - - - - This method gets a C NULL terminated string from the network stream. - It keeps reading a byte in each time until a NULL byte is returned. - It returns the resultant string of bytes read. - This string is sent from backend. - - - - - Reads requested number of bytes from stream with retries until Stream.Read returns 0 or count is reached. - - Stream to read - byte buffer to fill - starting position to fill the buffer - number of bytes to read - The number of bytes read. May be less than count if no more bytes are available. - - - - Reads requested number of bytes from . If output matches exactly, and == false, is returned directly. - - Source array. - Starting position to read from - Number of bytes to read - Force a copy, even if the output is an exact copy of . - byte[] containing data requested. - - - - This method writes a string to the network stream. - - - - - This method writes a string to the network stream. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a C NULL terminated string limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - This method writes a C NULL terminated byte[] limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - Write a 32-bit integer to the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given array in the correct byte order. - - - - - Write a 16-bit integer to the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given array in the correct byte order. - - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Starting offset in source array. - Number of bytes to copy. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Represent the frontend/backend protocol version. - - - - - Represent the backend server version. - As this class offers no functionality beyond that offered by it has been - deprecated in favour of that class. - - - - - - Returns the string representation of this version in three place dot notation (Major.Minor.Patch). - - - - - Server version major number. - - - - - Server version minor number. - - - - - Server version patch level number. - - - - - A class to handle everything associated with SSPI authentication - - - - - Simplified SecBufferDesc struct with only one SecBuffer - - -
-
diff --git a/src/packages/Npgsql.2.2.3/lib/net35/de/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net35/de/Npgsql.resources.dll deleted file mode 100644 index be17d5ced..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/de/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/es/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net35/es/Npgsql.resources.dll deleted file mode 100644 index 0a8dd9249..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/es/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/fi/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net35/fi/Npgsql.resources.dll deleted file mode 100644 index e2a405aff..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/fi/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/fr/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net35/fr/Npgsql.resources.dll deleted file mode 100644 index 15f82d068..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/fr/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/ja/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net35/ja/Npgsql.resources.dll deleted file mode 100644 index 76f95c0d9..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/ja/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net35/zh-CN/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net35/zh-CN/Npgsql.resources.dll deleted file mode 100644 index f197ae4c7..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net35/zh-CN/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/Mono.Security.dll b/src/packages/Npgsql.2.2.3/lib/net40/Mono.Security.dll deleted file mode 100644 index 62ae33940..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/Mono.Security.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/Npgsql.dll b/src/packages/Npgsql.2.2.3/lib/net40/Npgsql.dll deleted file mode 100644 index 53d9860ae..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/Npgsql.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/Npgsql.xml b/src/packages/Npgsql.2.2.3/lib/net40/Npgsql.xml deleted file mode 100644 index 332e24dd4..000000000 --- a/src/packages/Npgsql.2.2.3/lib/net40/Npgsql.xml +++ /dev/null @@ -1,6502 +0,0 @@ - - - - Npgsql - - - - - Handles serialisation of .NET array or IEnumeration to pg format. - Arrays of arrays, enumerations of enumerations, arrays of enumerations etc. - are treated as multi-dimensional arrays (in much the same manner as an array of arrays - is used to emulate multi-dimensional arrays in languages that lack native support for them). - If such an enumeration of enumerations is "jagged" (as opposed to rectangular, cuboid, - hypercuboid, hyperhypercuboid, etc) then this class will "correctly" serialise it, but pg - will raise an error as it doesn't allow jagged arrays. - - - - - Create an ArrayNativeToBackendTypeConverter with the element converter passed - - The that would be used to serialise the element type. - - - - Serialise the enumeration or array. - - - - - Convert a System.Array to PG binary format. - Write the array header and prepare to write array data to the stream. - - - - - Append all array data to the binary stream. - - - - - Handles parsing of pg arrays into .NET arrays. - - - - - Takes a string representation of a pg 1-dimensional array - (or a 1-dimensional row within an n-dimensional array) - and allows enumeration of the string represenations of each items. - - - - - Takes a string representation of a pg n-dimensional array - and allows enumeration of the string represenations of the next - lower level of rows (which in turn can be taken as (n-1)-dimensional arrays. - - - - - Takes an ArrayList which may be an ArrayList of ArrayLists, an ArrayList of ArrayLists of ArrayLists - and so on and enumerates the items that aren't ArrayLists (the leaf nodes if we think of the ArrayList - passed as a tree). Simply uses the ArrayLists' own IEnumerators to get that of the next, - pushing them onto a stack until we hit something that isn't an ArrayList. - ArrayList to enumerate - IEnumerable - - - - - Create a new ArrayBackendToNativeTypeConverter - - for the element type. - - - - Creates an array from pg text representation. - - - - - Creates an array list from pg represenation of an array. - Multidimensional arrays are treated as ArrayLists of ArrayLists - - - - - Creates an n-dimensional array from an ArrayList of ArrayLists or - a 1-dimensional array from something else. - - to convert - Type of the elements in the list - produced. - - - - Creates an n-dimensional System.Array from PG binary representation. - This function reads the array header and sets up an n-dimensional System.Array object to hold its data. - PopulateArrayFromBinaryArray() is then called to carry out array population. - - - - - Recursively populates an array from PB binary data representation. - - - - - Takes an array of ints and treats them like the limits of a set of counters. - Retains a matching set of ints that is set to all zeros on the first ++ - On a ++ it increments the "right-most" int. If that int reaches it's - limit it is set to zero and the one before it is incremented, and so on. - - Making this a more general purpose class is pretty straight-forward, but we'll just put what we need here. - - - - - Implements a bit string; a collection of zero or more bits which can each be 1 or 0. - BitString's behave as a list of bools, though like most strings and unlike most collections the position - tends to be of as much significance as the value. - BitStrings are often used as masks, and are commonly cast to and from other values. - - - - - Represents the empty string. - - - - - Create a BitString from an enumeration of boolean values. The BitString will contain - those booleans in the order they came in. - - The boolean values. - - - - Creates a BitString filled with a given number of true or false values. - - The value to fill the string with. - The number of bits to fill. - - - - Creats a bitstring from a string. - The string to copy from. - - - - - - Creates a single-bit element from a boolean value. - - The bool value which determines whether - the bit is 1 or 0. - - - - Creates a bitstring from an unsigned integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - This method is not CLS Compliant, and may not be available to some languages. - - - - Creates a bitstring from an integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - - - - Finds the first instance of a given value - - The value - whether true or false - to search for. - The index of the value found, or -1 if none are present. - - - - True if there is at least one bit with the value looked for. - - The value - true or false - to detect. - True if at least one bit was the same as item, false otherwise. - - - - Copies the bitstring to an array of bools. - - The boolean array to copy to. - The index in the array to start copying from. - - - - Returns an enumerator that enumerates through the string. - - The enumerator. - - - - Creats a bitstring by concatenating another onto this one. - - The string to append to this one. - The combined strings. - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string. - The length of the string to return, must be greater than zero, and may not be - so large that the start + length exceeds the bounds of this instance. - The Bitstring identified - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string, - the rest of the string is returned. - The Bitstring identified - - - - A logical and between this string and another. The two strings must be the same length. - - Another BitString to AND with this one. - A bitstring with 1 where both BitStrings had 1 and 0 otherwise. - - - - A logical or between this string and another. The two strings must be the same length. - - Another BitString to OR with this one. - A bitstring with 1 where either BitString had 1 and 0 otherwise. - - - - A logical xor between this string and another. The two strings must be the same length. - - Another BitString to XOR with this one. - A bitstring with 1 where one BitStrings and the other had 0, - and 0 where they both had 1 or both had 0. - - - - A bitstring that is the logical inverse of this one. - - A bitstring of the same length as this with 1 where this has 0 and vice-versa. - - - - Shifts the string operand bits to the left, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the left. - A left-shifted bitstring. - The behaviour of LShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a right-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. - - - - - Shifts the string operand bits to the right, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the right. - A right-shifted bitstring. - The behaviour of RShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a left-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. It also performs - a logical shift, rather than an arithmetic shift, so it always sets the vacated bit positions to zero - (like PostgreSQL and like .NET for unsigned integers but not for signed integers). - - - - - Returns true if the this string is identical to the argument passed. - - - - - Compares two strings. Strings are compared as strings, so while 0 being less than 1 will - mean a comparison between two strings of the same size is the same as treating them as numbers, - in the case of two strings of differing lengths the comparison starts at the right-most (most significant) - bit, and if all bits of the shorter string are exhausted without finding a comparison, then the larger - string is deemed to be greater than the shorter (0010 is greater than 0001 but less than 00100). - - Another string to compare with this one. - A value if the two strings are identical, an integer less - than zero if this is less than the argument, and an integer greater - than zero otherwise. - - - - Compares the string with another object. - - The object to compare with. - If the object is null then this string is considered greater. If the object is another BitString - then they are compared as in the explicit comparison for BitStrings - in any other case a is thrown. - - - - Compares this BitString with an object for equality. - - - - - Returns a code for use in hashing operations. - - - - - Returns a string representation of the BitString. - - - A string which can contain a letter and optionally a number which sets a minimum size for the string - returned. In each case using the lower-case form of the letter will result in a lower-case string - being returned. - - - B - A string of 1s and 0s. - - - X - An hexadecimal string (will result in an error unless the string's length is divisible by 4). - - - G - A string of 1s and 0s in single-quotes preceded by 'B' (Postgres bit string literal syntax). - - Y - An hexadecimal string in single-quotes preceded by 'X' (Postgres bit literal syntax, will result in an error unless the string's length is divisible by 4. - - C - The format produced by format-string "Y" if legal, otherwise that produced by format-string "G". - E - The most compact safe representation for Postgres. If single bit will be either a 0 or a 1. Otherwise if it - can be that produce by format string "Y" it will, otherwise if there are less than 9bits in length it will be that - produced by format-string "G". For longer strings that cannot be represented in hexadecimal it will be a string - representing the first part of the string in format "Y" followed by the PostgreSQL concatenation operator, followed - by the final bits in the format "G". E.g. "X'13DCE'||B'110'" - If format is empty or null, it is treated as if "B" had been passed (the default repreesentation, and that - generally used by PostgreSQL for display). - - The formatted string. - - - - Returns a string representation for the Bitstring - - A string containing '0' and '1' characters. - - - - Returns the same string as . formatProvider is ignored. - - - - - Parses a string to produce a BitString. Most formats that can be produced by - can be accepted, but hexadecimal - can be interpreted with the preceding X' to mark the following characters as - being hexadecimal rather than binary. - - - - - Performs a logical AND on the two operands. - - - - - Performs a logcial OR on the two operands. - - - - - Perofrms a logical EXCLUSIVE-OR on the two operands - - - - - Performs a logical NOT on the operand. - - - - - Concatenates the operands. - - - - - Left-shifts the string BitString. - - - - - Right-shifts the string BitString. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Interprets the bitstring as a series of bits in an encoded character string, - encoded according to the Encoding passed, and returns that string. - The bitstring must contain a whole number of octets(bytes) and also be - valid according to the Encoding passed. - - The to use in producing the string. - The string that was encoded in the BitString. - - - - Interprets the bitstring as a series of octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - - - - - Interprets the bitstring as a series of signed octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - This method is not CLS-Compliant and may not be available to languages that cannot - handle signed bytes. - - - - - Interprets the bitstring as a series of unsigned 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - - - - - Interprets the bitstring as a series of unsigned 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - - - - - Interprets the bitstring as a series of unsigned 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - - - - - The length of the string. - - - - - Retrieves the value of the bit at the given index. - - - - - Represents the PostgreSQL interval datatype. - PostgreSQL differs from .NET in how it's interval type doesn't assume 24 hours in a day - (to deal with 23- and 25-hour days caused by daylight savings adjustments) and has a concept - of months that doesn't exist in .NET's class. (Neither datatype - has any concessions for leap-seconds). - For most uses just casting to and from TimeSpan will work correctly — in particular, - the results of subtracting one or the PostgreSQL date, time and - timestamp types from another should be the same whether you do so in .NET or PostgreSQL — - but if the handling of days and months in PostgreSQL is important to your application then you - should use this class instead of . - If you don't know whether these differences are important to your application, they - probably arent! Just use and do not use this class directly ☺ - To avoid forcing unnecessary provider-specific concerns on users who need not be concerned - with them a call to on a field containing an - value will return a rather than an - . If you need the extra functionality of - then use . - - - - - - - - - - Represents the number of ticks (100ns periods) in one microsecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one millisecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one second. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one minute. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one hour. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one day. This field is constant. - - - - - Represents the number of hours in one day (assuming no daylight savings adjustments). This field is constant. - - - - - Represents the number of days assumed in one month if month justification or unjustifcation is performed. - This is set to 30 for consistency with PostgreSQL. Note that this is means that month adjustments cause - a year to be taken as 30 × 12 = 360 rather than 356/366 days. - - - - - Represents the number of ticks (100ns periods) in one day, assuming 30 days per month. - - - - - Represents the number of months in a year. This field is constant. - - - - - Represents the maximum . This field is read-only. - - - - - Represents the minimum . This field is read-only. - - - - - Represents the zero . This field is read-only. - - - - - Initializes a new to the specified number of ticks. - - A time period expressed in 100ns units. - - - - Initializes a new to hold the same time as a - - A time period expressed in a - - - - Initializes a new to the specified number of months, days - & ticks. - - Number of months. - Number of days. - Number of 100ns units. - - - - Initializes a new to the specified number of - days, hours, minutes & seconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - - - - Initializes a new to the specified number of - days, hours, minutes, seconds & milliseconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - months, days, hours, minutes, seconds & milliseconds. - - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - years, months, days, hours, minutes, seconds & milliseconds. - Years are calculated exactly equivalent to 12 months. - - Number of years. - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Creates an from a number of ticks. - - The number of ticks (100ns units) in the interval. - A d with the given number of ticks. - - - - Creates an from a number of microseconds. - - The number of microseconds in the interval. - A d with the given number of microseconds. - - - - Creates an from a number of milliseconds. - - The number of milliseconds in the interval. - A d with the given number of milliseconds. - - - - Creates an from a number of seconds. - - The number of seconds in the interval. - A d with the given number of seconds. - - - - Creates an from a number of minutes. - - The number of minutes in the interval. - A d with the given number of minutes. - - - - Creates an from a number of hours. - - The number of hours in the interval. - A d with the given number of hours. - - - - Creates an from a number of days. - - The number of days in the interval. - A d with the given number of days. - - - - Creates an from a number of months. - - The number of months in the interval. - A d with the given number of months. - - - - Adds another interval to this instance and returns the result. - - An to add to this instance. - An whose values are the sums of the two instances. - - - - Subtracts another interval from this instance and returns the result. - - An to subtract from this instance. - An whose values are the differences of the two instances. - - - - Returns an whose value is the negated value of this instance. - - An whose value is the negated value of this instance. - - - - This absolute value of this instance. In the case of some, but not all, components being negative, - the rules used for justification are used to determine if the instance is positive or negative. - - An whose value is the absolute value of this instance. - - - - Equivalent to PostgreSQL's justify_days function. - - An based on this one, but with any hours outside of the range [-23, 23] - converted into days. - - - - Opposite to PostgreSQL's justify_days function. - - An based on this one, but with any days converted to multiples of ±24hours. - - - - Equivalent to PostgreSQL's justify_months function. - - An based on this one, but with any days outside of the range [-30, 30] - converted into months. - - - - Opposite to PostgreSQL's justify_months function. - - An based on this one, but with any months converted to multiples of ±30days. - - - - Equivalent to PostgreSQL's justify_interval function. - - An based on this one, - but with any months converted to multiples of ±30days - and then with any days converted to multiples of ±24hours - - - - Opposite to PostgreSQL's justify_interval function. - - An based on this one, but with any months converted to multiples of ±30days and then any days converted to multiples of ±24hours; - - - - Produces a canonical NpgslInterval with 0 months and hours in the range of [-23, 23]. - - - While the fact that for many purposes, two different instances could be considered - equivalent (e.g. one with 2days, 3hours and one with 1day 27hours) there are different possible canonical forms. - - E.g. we could move all excess hours into days and all excess days into months and have the most readable form, - or we could move everything into the ticks and have the form that allows for the easiest arithmetic) the form - chosen has two important properties that make it the best choice. - First, it is closest two how - objects are most often represented. Second, it is compatible with results of many - PostgreSQL functions, particularly with age() and the results of subtracting one date, time or timestamp from - another. - - Note that the results of casting a to is - canonicalised. - - - An based on this one, but with months converted to multiples of ±30days and with any hours outside of the range [-23, 23] - converted into days. - - - - Implicit cast of a to an - - A - An eqivalent, canonical, . - - - - Implicit cast of an to a . - - A . - An equivalent . - - - - Returns true if another is exactly the same as this instance. - - An for comparison. - true if the two instances are exactly the same, - false otherwise. - - - - Returns true if another object is an , that is exactly the same as - this instance - - An for comparison. - true if the argument is an and is exactly the same - as this one, false otherwise. - - - - Compares two instances. - - The first . - The second . - 0 if the two are equal or equivalent. A value greater than zero if x is greater than y, - a value less than zero if x is less than y. - - - - A hash code suitable for uses with hashing algorithms. - - An signed integer. - - - - Compares this instance with another/ - - An to compare this with. - 0 if the instances are equal or equivalent. A value less than zero if - this instance is less than the argument. A value greater than zero if this instance - is greater than the instance. - - - - Compares this instance with another/ - - An object to compare this with. - 0 if the argument is an and the instances are equal or equivalent. - A value less than zero if the argument is an and - this instance is less than the argument. - A value greater than zero if the argument is an and this instance - is greater than the instance. - A value greater than zero if the argument is null. - The argument is not an . - - - - Parses a and returns a instance. - Designed to use the formats generally returned by PostgreSQL. - - The to parse. - An represented by the argument. - The string was null. - A value obtained from parsing the string exceeded the values allowed for the relevant component. - The string was not in a format that could be parsed to produce an . - - - - Attempt to parse a to produce an . - - The to parse. - (out) The produced, or if the parsing failed. - true if the parsing succeeded, false otherwise. - - - - Create a representation of the instance. - The format returned is of the form: - [M mon[s]] [d day[s]] [HH:mm:ss[.f[f[f[f[f[f[f[f[f]]]]]]]]]] - A zero is represented as 00:00:00 - - Ticks are 100ns, Postgress resolution is only to 1µs at most. Hence we lose 1 or more decimal - precision in storing values in the database. Despite this, this method will output that extra - digit of precision. It's forward-compatible with any future increases in resolution up to 100ns, - and also makes this ToString() more applicable to any other use-case. - - - The representation. - - - - Adds two together. - - The first to add. - The second to add. - An whose values are the sum of the arguments. - - - - Subtracts one from another. - - The to subtract the other from. - The to subtract from the other. - An whose values are the difference of the arguments - - - - Returns true if two are exactly the same. - - The first to compare. - The second to compare. - true if the two arguments are exactly the same, false otherwise. - - - - Returns false if two are exactly the same. - - The first to compare. - The second to compare. - false if the two arguments are exactly the same, true otherwise. - - - - Compares two instances to see if the first is less than the second - - The first to compare. - The second to compare. - true if the first is less than second, false otherwise. - - - - Compares two instances to see if the first is less than or equivalent to the second - - The first to compare. - The second to compare. - true if the first is less than or equivalent to second, false otherwise. - - - - Compares two instances to see if the first is greater than the second - - The first to compare. - The second to compare. - true if the first is greater than second, false otherwise. - - - - Compares two instances to see if the first is greater than or equivalent the second - - The first to compare. - The second to compare. - true if the first is greater than or equivalent to the second, false otherwise. - - - - Returns the instance. - - An . - The argument. - - - - Negates an instance. - - An . - The negation of the argument. - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. This ignores the number of days and - months held. If you want them included use first. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - interval(0) - resolution of 1s (1 second) - - - interval(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - interval(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - interval(3) - resolution of 1ms = 0.001s (1 millisecond) - - - interval(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - interval(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - interval(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL interval will - not suffice for those purposes. - In more frequent cases though, the resolution of the interval suffices. - will always suffice to handle the resolution of any interval value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An in the range [-999999, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An in the range [-999, 999]. - - - - - Gets the number of whole seconds held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole minutes held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that this can be less than -23 or greater than 23 unless - has been used to produce this instance. - - - - - Gets the number of days held in the instance. - Note that this does not pay attention to a time component with -24 or less hours or - 24 or more hours, unless has been called to produce this instance. - - - - - Gets the number of months held in the instance. - Note that this does not pay attention to a day component with -30 or less days or - 30 or more days, unless has been called to produce this instance. - - - - - Returns a representing the time component of the instance. - Note that this may have a value beyond the range ±23:59:59.9999999 unless - has been called to produce this instance. - - - - - The total number of ticks (100ns units) in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of microseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of milliseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of seconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of minutes in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of hours in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of days in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of months in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - time(0) - resolution of 1s (1 second) - - - time(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - time(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - time(3) - resolution of 1ms = 0.001s (1 millisecond) - - - time(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - time(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - time(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL time will - not suffice for those purposes. - In more frequent cases though, the resolution of time suffices. - will always suffice to handle the resolution of any time value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - Compares this with another . As per postgres' rules, - first the times are compared as if they were both in the same timezone. If they are equal then - then timezones are compared (+01:00 being "smaller" than -01:00). - - the to compare with. - An integer which is 0 if they are equal, < 0 if this is the smaller and > 0 if this is the larger. - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - This class implements the Fastpath api. - - - - - This maps the functions names to their id's (possible unique just - to a connection). - - - - - Our connection. - - - - - The network stream. - - - - - Initialises the fastpath system. - - BaseConnection to attach to. - The network stream to the backend. - - - - Initialises the fastpath system. - - BaseConnection to attach to. - - - - Send a function call to the PostgreSQL backend. - - Function id. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - Send a function call to the PostgreSQL backend by name. - Note: the mapping for the procedure name to function id needs to exist, - usually to an earlier call to addfunction(). - This is the prefered method to call, as function id's can/may change - between versions of the backend. - For an example of how this works, refer to NpgsqlTypes.LargeObject - - Function name. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Integer result. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Array containing result - - - - This adds a function to our lookup table. - User code should use the addFunctions method, which is based upon a - query, rather than hard coding the oid. The oid for a function is not - guaranteed to remain static, even on different servers of the same - version. - - Function name. - Function id. - - - - This takes a ResultSet containing two columns. Column 1 contains the - function name, Column 2 the oid. - It reads the entire ResultSet, loading the values into the function - table. - REMEMBER to close() the resultset after calling this!! - Implementation note about function name lookups: - PostgreSQL stores the function id's and their corresponding names in - the pg_proc table. To speed things up locally, instead of querying each - function from that table when required, a Dictionary is used. Also, only - the function's required are entered into this table, keeping connection - times as fast as possible. - The org.postgresql.largeobject.LargeObject class performs a query upon it's startup, - and passes the returned ResultSet to the addFunctions() method here. - Once this has been done, the LargeObject api refers to the functions by - name. - Dont think that manually converting them to the oid's will work. Ok, - they will for now, but they can change during development (there was some - discussion about this for V7.0), so this is implemented to prevent any - unwarranted headaches in the future. - - ResultSet - - - - This returns the function id associated by its name - If addFunction() or addFunctions() have not been called for this name, - then an NpgsqlException is thrown. - - Function name to lookup. - Function ID for fastpath call. - - - - Fast Path Arg. - - - - - Type of argument, true=integer, false=byte[]. - - - - - Integer value if type=true. - - - - - Byte value if type=false; - - - - - Constructs an argument that consists of an integer value. - - Int value to set. - - - - Constructs an argument that consists of an array of bytes. - - Array to store. - - - - Constructs an argument that consists of part of a byte array. - - Source array. - offset within array. - length of data to include. - - - - Constructs an argument that consists of a String. - - String to store. - - - - This sends this argument down the network stream. - The stream sent consists of the length.int4 then the contents. - Note: This is called from Fastpath, and cannot be called from - client code. - - - - - - Report send size. - - Send size. - - - - Large Object. - - - - - Indicates a seek from the begining of a file. - - - - - Indicates a seek from the current position. - - - - - Indicates a seek from the end of a file. - - - - - This opens a large object. - If the object does not exist, then an NpgsqlException is thrown. - - FastPath API for the connection to use. - OID of the Large Object to open. - Mode of opening the large object - - - - OID getter. - - The OID of this LargeObject. - - - - This method closes the object. You must not call methods in this - object after this is called. - - - - - Reads some data from the object, and return as a byte[] array. - - Number of bytes to read. - Array containing data read. - - - - Reads some data from the object into an existing array. - - Destination array. - Offset within array. - Maximum number of bytes to read. - The number of bytes actually read. - - - - Writes an array to the object. - - Array to write. - - - - Writes some data from an array to the object. - - Destination array. - Offset within array. - Number of bytes to write. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object. - Either SEEK_SET, SEEK_CUR or SEEK_END. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object from begining. - - - - Report the current position within the object. - - The current position within the object. - - - - This method is inefficient, as the only way to find out the size of - the object is to seek to the end, record the current position, then - return to the original position. - A better method will be found in the future. - - The size of the large object. - - - - OID. - - - - - Large Object Manager. - - - - - This mode indicates we want to write to an object - - - - - This mode indicates we want to read an object - - - - - This mode is the default. It indicates we want read and write access to - - - - - Constructs the LargeObject API. - There should only be one LargeObjectManager per Connection. The - org.postgresql.Connection class keeps track of the various extension API's - and it's advised you use those to gain access, and not going direct. - - - - - - This opens an existing large object, based on its OID. This method - assumes that READ and WRITE access is required (the default). - - OID of large object. - LargeObject instance providing access to the object - - - - This opens an existing large object, based on its OID. - - OID of large object. - Mode of open. - - - - - This creates a large object, returning its OID. - - OID of new object. - - - - This creates a large object, returning its OID. - - Bitmask describing different attributes of the new object. - OID of new object. - - - - This deletes a large object. - - OID describing object to delete. - - - - This deletes a large object. - It is identical to the Delete() method, and is supplied as the C API uses unlink. - - OID describing object to delete. - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - Clone the current object. - - A new NativeToBackendTypeConverterOptions object. - - - - Clone the current object with a different OID/Name mapping. - - OID/Name mapping object to use in the new instance. - A new NativeToBackendTypeConverterOptions object. - - - - Provide event handlers to convert all native supported basic data types from their backend - text representation to a .NET object. - - - - - Convert UTF8 encoded text a string. - - - - - Byte array from bytea encoded as ASCII text, escaped or hex format. - - - - - Byte array from bytea encoded as binary. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql bit to a System.Boolean. - - - - - Convert a postgresql datetime to a System.DateTime. - - - - - Convert a postgresql date to a System.DateTime. - - - - - Convert a postgresql time to a System.DateTime. - - - - - Convert a postgresql money to a System.Decimal. - - - - - Convert a postgresql float4 or float8 to a System.Float or System.Double respectively. - - - - - Provide event handlers to convert extended native supported data types from their backend - text representation to a .NET object. - - - - - Convert a postgresql point to a System.NpgsqlPoint. - - - - - Convert a postgresql point to a System.RectangleF. - - - - - LDeg. - - - - - Path. - - - - - Polygon. - - - - - Circle. - - - - - Inet. - - - - - MAC Address. - - - - - interval - - - - - Provide event handlers to convert the basic native supported data types from - native form to backend representation. - - - - - Convert a string to UTF8 encoded text, escaped and quoted as required. - - - - - Convert a string to UTF8 encoded text. - - - - - Binary data, escaped and quoted as required. - - - - - Binary data with possible older style octal escapes, quoted. - - - - - Binary data in the new hex format (>= 9.0), quoted. - - - - - Binary data, raw. - - - - - Convert to a postgresql boolean text format. - - - - - Convert to a postgresql boolean binary format. - - - - - Convert to a postgresql binary int2. - - - - - Convert to a postgresql binary int4. - - - - - Convert to a postgresql binary int8. - - - - - Convert to a postgresql bit. - - - - - Convert to a postgresql timestamp. - - - - - Convert to a postgresql date. - - - - - Convert to a postgresql time. - - - - - Convert to a postgres money. - - - - - Convert to a postgres double with maximum precision. - - - - - Convert a System.Float to a postgres float4. - - - - - Convert a System.Double to a postgres float8. - - - - - Provide event handlers to convert extended native supported data types from - native form to backend representation. - - - - - Point. - - - - - Box. - - - - - LSeg. - - - - - Open path. - - - - - Polygon. - - - - - Convert to a postgres MAC Address. - - - - - Circle. - - - - - Convert to a postgres inet. - - - - - Convert to a postgres interval - - - - - Delegate called to convert the given backend text data to its native representation. - - - - - Delegate called to convert the given backend binary data to its native representation. - - - - - Represents a backend data type. - This class can be called upon to convert a backend field representation to a native object. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - fieldValueSize - Type modifier field sent from the backend. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - TypeSize - Type modifier field sent from the backend. - - - - Type OID provided by the backend server. - - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - NpgsqlDbType. - - - - - Provider type to convert fields of this type to. - - - - - System type to convert fields of this type to. - - - - - Reports whether a backend binary to native decoder is available for this type. - - - - - Delegate called to convert the given native data to its backand representation. - - - - - Represents a backend data type. - This class can be called upon to convert a native object to its backend field representation, - - - - - Returns an NpgsqlNativeTypeInfo for an array where the elements are of the type - described by the NpgsqlNativeTypeInfo supplied. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type name provided by the backend server. - DbType - Quote - NpgsqlDbType - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended queries). - - - - Perform a data conversion from a native object to - a backend representation. - DBNull and null values are handled differently depending if a plain query is used - When - - Native .NET object to be converted. - Specifies that the value should be formatted for the extended query syntax. - Options to guide serialization. If null, a default options set is used. - Specifies that the value should be formatted as an extended query array element. - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - DbType. - - - - - Apply quoting. - - - - - Use parameter size information. - - - - - Reports whether a native to backend binary encoder is available for this type. - - - - - Provide mapping between type OID, type name, and a NpgsqlBackendTypeInfo object that represents it. - - - - - Construct an empty mapping. - - - - - Copy constuctor. - - - - - Add the given NpgsqlBackendTypeInfo to this mapping. - - - - - Add a new NpgsqlBackendTypeInfo with the given attributes and conversion handlers to this mapping. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Make a shallow copy of this type mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type OID exists in this mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type OID, or null if none found. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type name, or null if none found. - - - - - Provide mapping between type Type, NpgsqlDbType and a NpgsqlNativeTypeInfo object that represents it. - - - - - Add the given NpgsqlNativeTypeInfo to this mapping. - - - - - Add a new NpgsqlNativeTypeInfo with the given attributes and conversion handlers to this mapping. - - Type name provided by the backend server. - NpgsqlDbType - DbType - Quote - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended query). - - - - Retrieve the NpgsqlNativeTypeInfo with the given NpgsqlDbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given DbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given Type. - - - - - Determine if a NpgsqlNativeTypeInfo with the given backend type name exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given NpgsqlDbType exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given Type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Represents a PostgreSQL Point type - - - - - Represents a PostgreSQL Line Segment type. - - - - - Represents a PostgreSQL Path type. - - - - - Represents a PostgreSQL Polygon type. - - - - - Represents a PostgreSQL Circle type. - - - - - Represents a PostgreSQL inet type. - - - - - Represents a PostgreSQL MacAddress type. - - - - - - - The macAddr parameter must contain a string that can only consist of numbers - and upper-case letters as hexadecimal digits. (See PhysicalAddress.Parse method on MSDN) - - - - This class contains helper methods for type conversion between - the .Net type system and postgresql. - - - - - A cache of basic datatype mappings keyed by server version. This way we don't - have to load the basic type mappings for every connection. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given DbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given System.Type. - - - - - This method is responsible to convert the byte[] received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - This method is responsible to convert the string received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - Create the one and only native to backend type map. - This map is used when formatting native data - types to backend representations. - - - - - This method creates (or retrieves from cache) a mapping between type and OID - of all natively supported postgresql data types. - This is needed as from one version to another, this mapping can be changed and - so we avoid hardcoding them. - - NpgsqlTypeMapping containing all known data types. The mapping must be - cloned before it is modified because it is cached; changes made by one connection may - effect another connection. - - - - - Attempt to map types by issuing a query against pg_type. - This function takes a list of NpgsqlTypeInfo and attempts to resolve the OID field - of each by querying pg_type. If the mapping is found, the type info object is - updated (OID) and added to the provided NpgsqlTypeMapping object. - - NpgsqlConnector to send query through. - Mapping object to add types too. - List of types that need to have OID's mapped. - - - - Summary description for NpgsqlQuery - - - - - For classes representing messages sent from the client to the server. - - - - - Set Cache Size. The default value is 20. - - - - - Lookup cached entity. null will returned if not match. - For both get{} and set{} apply LRU rule. - - key - - - - - The globally available text encoding used for frontend/backend communication. - - - - This class represents the base class for the state pattern design pattern - implementation. - - - This class represents the base class for the state pattern design pattern - implementation. - - - - - - This method is used by the states to change the state of the context. - - - - - Call ProcessBackendResponsesEnum(), and scan and discard all results. - - - - - This method is responsible to handle all protocol messages sent from the backend. - It holds all the logic to do it. - To exchange data, it uses a Mediator object from which it reads/writes information - to handle backend requests. - - - - - - Checks for context socket availability. - Socket.Poll supports integer as microseconds parameter. - This limits the usable command timeout value - to 2,147 seconds: (2,147 x 1,000,000 less than max_int). - In order to bypass this limit, the availability of - the socket is checked in 2,147 seconds cycles - - true, if for context socket availability was checked, false otherwise. - Context. - Select mode. - - - - Called from constructor of derived class. - - - - - Finalizer for HashAlgorithm - - - - - Computes the entire hash of all the bytes in the byte array. - - - - - When overridden in a derived class, drives the hashing function. - - - - - - - - When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created. - - - - - When overridden in a derived class, initializes the object to prepare for hashing. - - - - - Used for stream chaining. Computes hash as data passes through it. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - The buffer to write the copied data to. - At what point in the outputBuffer to write the data at. - - - - Used for stream chaining. Computes hash as data passes through it. Finishes off the hash. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - - - - Get whether or not the hash can transform multiple blocks at a time. - Note: MUST be overriden if descendant can transform multiple block - on a single call! - - - - - Gets the previously computed hash. - - - - - Returns the size in bits of the hash. - - - - - Must be overriden if not 1 - - - - - Must be overriden if not 1 - - - - - Common base class for all derived MD5 implementations. - - - - - Called from constructor of derived class. - - - - - Creates the default derived class. - - - - - C# implementation of the MD5 cryptographic hash function. - - - - - Creates a new MD5CryptoServiceProvider. - - - - - Drives the hashing function. - - Byte array containing the data to hash. - Where in the input buffer to start. - Size in bytes of the data in the buffer to hash. - - - - This finalizes the hash. Takes the data from the chaining variables and returns it. - - - - - Resets the class after use. Called automatically after hashing is done. - - - - - This is the meat of the hash function. It is what processes each block one at a time. - - Byte array to process data from. - Where in the byte array to start processing. - - - - Pads and then processes the final block. - - Buffer to grab data from. - Position in buffer in bytes to get data from. - How much data in bytes in the buffer to use. - - - - Implements for version 3 of the protocol. - - - - - Reads a row, field by field, allowing a DataRow to be built appropriately. - - - - - Marker interface which identifies a class which may take possession of a stream for the duration of - it's lifetime (possibly temporarily giving that possession to another class for part of that time. - - It inherits from IDisposable, since any such class must make sure it leaves the stream in a valid state. - - The most important such class is that compiler-generated from ProcessBackendResponsesEnum. Of course - we can't make that inherit from this interface, alas. - - - - - Marker interface which identifies a class which represents part of - a response from the server. - - - - - Reads part of a field, as needed (for - and - - - - - Adds further functionality to stream that is dependant upon the type of data read. - - - - - Completes the implementation of Streamer for char data. - - - - - Completes the implementation of Streamer for byte data. - - - - - This class represents a BackEndKeyData message received - from PostgreSQL - - - - - This class represents the Bind message sent to PostgreSQL - server. - - - - - - This class represents the CancelRequest message sent to PostgreSQL - server. - - - - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlCommand class. - - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query. - - The text of the query. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query and a NpgsqlConnection. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query, a NpgsqlConnection, and the NpgsqlTransaction. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - The NpgsqlTransaction in which the NpgsqlCommand executes. - - - - Used to execute internal commands. - - - - - Attempts to cancel the execution of a NpgsqlCommand. - - This Method isn't implemented yet. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Creates a new instance of an DbParameter object. - - An DbParameter object. - - - - Creates a new instance of a NpgsqlParameter object. - - A NpgsqlParameter object. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Internal query shortcut for use in cases where the number - of affected rows is of no interest. - - - - - Special adaptation of ExecuteBlind() that sets statement_timeout. - This exists to prevent Connector.SetBackendCommandTimeout() from calling Command.ExecuteBlind(), - which will cause an endless recursive loop. - - - Timeout in seconds. - - - - Executes a SQL statement against the connection and returns the number of rows affected. - - The number of rows affected if known; -1 otherwise. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader. - - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - Currently the CommandBehavior parameter is ignored. - - - - This method binds the parameters from parameters collection to the bind - message. - - - - - Executes the query, and returns the first column of the first row - in the result set returned by the query. Extra columns or rows are ignored. - - The first column of the first row in the result set, - or a null reference if the result set is empty. - - - - Creates a prepared version of the command on a PostgreSQL server. - - - - - This method checks the connection state to see if the connection - is set or it is open. If one of this conditions is not met, throws - an InvalidOperationException - - - - - This method substitutes the Parameters, if exist, in the command - to their actual values. - The parameter name format is :ParameterName. - - A version of CommandText with the Parameters inserted. - - - - Process this.commandText, trimming each distinct command and substituting paramater - tokens. - - - UTF8 encoded command ready to be sent to the backend. - - - - Append a region of a source command text to an output command, performing parameter token - substitutions. - - Stream to which to append output. - Command text. - - - false if the query has multiple statements which are not allowed - - - - Gets or sets the SQL statement or function (stored procedure) to execute at the data source. - - The Transact-SQL statement or stored procedure to execute. The default is an empty string. - - - - Gets or sets the wait time before terminating the attempt - to execute a command and generating an error. - - The time (in seconds) to wait for the command to execute. - The default is 20 seconds. - - - - Gets or sets a value indicating how the - CommandText property is to be interpreted. - - One of the CommandType values. The default is CommandType.Text. - - - - DB connection. - - - - - Gets or sets the NpgsqlConnection - used by this instance of the NpgsqlCommand. - - The connection to a data source. The default value is a null reference. - - - - DB parameter collection. - - - - - Gets the NpgsqlParameterCollection. - - The parameters of the SQL statement or function (stored procedure). The default is an empty collection. - - - - DB transaction. - - - - - Gets or sets the NpgsqlTransaction - within which the NpgsqlCommand executes. - - The NpgsqlTransaction. - The default value is a null reference. - - - - Gets or sets how command results are applied to the DataRow - when used by the Update - method of the DbDataAdapter. - - One of the UpdateRowSource values. - - - - Returns oid of inserted row. This is only updated when using executenonQuery and when command inserts just a single row. If table is created without oids, this will always be 0. - - - - - Returns whether this query will execute as a prepared (compiled) query. - - - - - Design time visible. - - - - - This class is responsible to create database commands for automatic insert, update and delete operations. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The adapter. - - - - - This method is reponsible to derive the command parameter list with values obtained from function definition. - It clears the Parameters collection of command. Also, if there is any parameter type which is not supported by Npgsql, an InvalidOperationException will be thrown. - Parameters name will be parameter1, parameter2, ... - - NpgsqlCommand whose function parameters will be obtained. - - - - Gets the automatically generated object required - to perform insertions at the data source. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated object required to perform insertions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform updates at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform updates. - - - - - Gets the automatically generated object required to perform updates - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform updates. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform deletions at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform deletions. - - - - - Gets the automatically generated object required to perform deletions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform deletions. - - - - - Applies the parameter information. - - The parameter. - The row. - Type of the statement. - if set to true [where clause]. - - - - Returns the name of the specified parameter in the format of @p#. - - The number to be included as part of the parameter's name.. - - The name of the parameter with the specified number appended as part of the parameter name. - - - - - Returns the full parameter name, given the partial parameter name. - - The partial name of the parameter. - - The full parameter name corresponding to the partial parameter name requested. - - - - - Returns the placeholder for the parameter in the associated SQL statement. - - The number to be included as part of the parameter's name. - - The name of the parameter with the specified number appended. - - - - - Registers the to handle the event for a . - - The to be used for the update. - - - - Adds an event handler for the event. - - The sender - A instance containing information about the event. - - - - Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier, including properly escaping any embedded quotes in the identifier. - - The original unquoted identifier. - - The quoted version of the identifier. Embedded quotes within the identifier are properly escaped. - - - - - Unquoted identifier parameter cannot be null - - - - Given a quoted identifier, returns the correct unquoted form of that identifier, including properly un-escaping any embedded quotes in the identifier. - - The identifier that will have its embedded quotes removed. - - The unquoted identifier, with embedded quotes properly un-escaped. - - - - - Quoted identifier parameter cannot be null - - - - Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The beginning character or characters to use. The default is an empty string. - - - - - - - - Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The ending character or characters to use. The default is an empty string. - - - - - - - - Represents the method that handles the Notice events. - - The source of the event. - A NpgsqlNoticeEventArgs that contains the event data. - - - - Represents the method that handles the Notification events. - - The source of the event. - A NpgsqlNotificationEventArgs that contains the event data. - - - - This class represents a connection to a - PostgreSQL server. - - - - - Initializes a new instance of the - NpgsqlConnection class. - - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - An DbTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Begins a database transaction. - - A NpgsqlTransaction - object representing the new transaction. - - Currently there's no support for nested transactions. - - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - A NpgsqlTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Opens a database connection with the property settings specified by the - ConnectionString. - - - - - This method changes the current database by disconnecting from the actual - database and connecting to the specified. - - The name of the database to use in place of the current database. - - - - Releases the connection to the database. If the connection is pooled, it will be - made available for re-use. If it is non-pooled, the actual connection will be shutdown. - - - - - When a connection is closed within an enclosing TransactionScope and the transaction - hasn't been promoted, we defer the actual closing until the scope ends. - - - - - Creates and returns a DbCommand - object associated with the IDbConnection. - - A DbCommand object. - - - - Creates and returns a NpgsqlCommand - object associated with the NpgsqlConnection. - - A NpgsqlCommand object. - - - - Releases all resources used by the - NpgsqlConnection. - - true when called from Dispose(); - false when being called from the finalizer. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Returns a copy of the NpgsqlConnectionStringBuilder that contains the parsed connection string values. - - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - Write each key/value pair in the connection string to the log. - - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Refresh the cached _connectionString whenever the builder settings change - - - - - Returns the supported collections - - - - - Returns the schema collection specified by the collection name. - - The collection name. - The collection specified. - - - - Returns the schema collection specified by the collection name filtered by the restrictions. - - The collection name. - - The restriction values to filter the results. A description of the restrictions is contained - in the Restrictions collection. - - The collection specified. - - - - Clear connection pool. - - - - - Clear all connection pools. - - - - - Enlist transation. - - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets or sets the string used to connect to a PostgreSQL database. - Valid values are: -
    -
  • - Server: Address/Name of Postgresql Server; -
  • -
  • - Port: Port to connect to; -
  • -
  • - Protocol: Protocol version to use, instead of automatic; Integer 2 or 3; -
  • -
  • - Database: Database name. Defaults to user name if not specified; -
  • -
  • - User Id: User name; -
  • -
  • - Password: Password for clear text authentication; -
  • -
  • - SSL: True or False. Controls whether to attempt a secure connection. Default = False; -
  • -
  • - Pooling: True or False. Controls whether connection pooling is used. Default = True; -
  • -
  • - MinPoolSize: Min size of connection pool; -
  • -
  • - MaxPoolSize: Max size of connection pool; -
  • -
  • - Timeout: Time to wait for connection open in seconds. Default is 15. -
  • -
  • - CommandTimeout: Time to wait for command to finish execution before throw an exception. In seconds. Default is 20. -
  • -
  • - Sslmode: Mode for ssl connection control. Can be Prefer, Require, Allow or Disable. Default is Disable. Check user manual for explanation of values. -
  • -
  • - ConnectionLifeTime: Time to wait before closing unused connections in the pool in seconds. Default is 15. -
  • -
  • - SyncNotification: Specifies if Npgsql should use synchronous notifications. -
  • -
  • - SearchPath: Changes search path to specified and public schemas. -
  • -
-
- The connection string that includes the server name, - the database name, and other parameters needed to establish - the initial connection. The default value is an empty string. - -
- - - Backend server host name. - - - - - Backend server port. - - - - - If true, the connection will attempt to use SSL. - - - - - Gets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets the name of the current database or the database to be used after a connection is opened. - - The name of the current database or the name of the database to be - used after a connection is opened. The default value is the empty string. - - - - Whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Gets the database server name. - - - - - Gets flag indicating if we are using Synchronous notification or not. - The default value is false. - - - - - Gets the current state of the connection. - - A bitwise combination of the ConnectionState values. The default is Closed. - - - - Gets whether the current state of the connection is Open or Closed - - ConnectionState.Open or ConnectionState.Closed - - - - Compatibility version. - - - - - Version of the PostgreSQL backend. - This can only be called when there is an active connection. - - - - - PostgreSQL server version. - - - - - Protocol version in use. - This can only be called when there is an active connection. - Always retuna Version3 - - - - - Process id of backend server. - This can only be called when there is an active connection. - - - - - Report whether the backend is expecting standard conformant strings. - In version 8.1, Postgres began reporting this value (false), but did not actually support standard conformant strings. - In version 8.2, Postgres began supporting standard conformant strings, but defaulted this flag to false. - As of version 9.1, this flag defaults to true. - - - - - Report whether the backend understands the string literal E prefix (>= 8.1). - - - - - Report whether the backend understands the hex byte format (>= 9.0). - - - - - The connector object connected to the backend. - - - - - Gets the NpgsqlConnectionStringBuilder containing the parsed connection string values. - - - - - User name. - - - - - Use extended types. - - - - - Password. - - - - - Determine if connection pooling will be used for this connection. - - - - - DB provider factory. - - - - - Return an exact copy of this NpgsqlConnectionString. - - - - - No integrated security if we're on mono and .NET 4.5 because of ClaimsIdentity, - see https://github.com/npgsql/Npgsql/issues/133 - - - - - This function will set value for known key, both private member and base[key]. - - - - - value, coerced as needed to the stored type. - - - - The function will modify private member only, not base[key]. - - - - value, coerced as needed to the stored type. - - - - The function will access private member only, not base[key]. - - - value. - - - - Clear the member and assign them to the default value. - - - - - Gets or sets the backend server host name. - - - - - Gets or sets the backend server port. - - - - - Gets or sets the name of the database to be used after a connection is opened. - - The name of the database to be - used after a connection is opened. - - - - Gets or sets the login user name. - - - - - Gets or sets the login password as a UTF8 encoded byte array. - - - - - Sets the login password as a string. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets or sets the schema search path. - - - - - Gets or sets a value indicating whether connection pooling should be used. - - - - - Gets or sets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets or sets the minimum connection pool size. - - - - - Gets or sets the maximum connection pool size. - - - - - Gets or sets a value indicating whether to listen for notifications and report them between command activity. - - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets or sets a value indicating whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Compatibilty version. When possible, behaviour caused by breaking changes will be preserved - if this version is less than that where the breaking change was introduced. - - - - - Gets or sets the ootional application name parameter to be sent to the backend during connection initiation. - - - - - Gets or sets a value indicating whether to silently Prepare() all commands before execution. - - - - - Gets or sets the specified backend communication protocol version. - - - - - Gets the backend encoding. Always returns "UTF8". - - - - - Case insensative accessor for indivual connection string values. - - - - - Set both ImplicitDefault and ExplicitDefault to the 's default value. - - - - - - - - Set ImplicitDefault to the default value of 's type, - and ExplicitDefault to . - - - - - - - - Represents the method that allows the application to provide a certificate collection to be used for SSL clien authentication - - A X509CertificateCollection to be filled with one or more client certificates. - - - - Represents the method that is called to validate the certificate provided by the server during an SSL handshake - - The server's certificate - The certificate chain containing the certificate's CA and any intermediate authorities - Any errors that were detected - - - - !!! Helper class, for compilation only. - Connector implements the logic for the Connection Objects to - access the physical connection to the database, and isolate - the application developer from connection pooling internals. - - - - - Constructor. - - Connection string. - Pooled - Controls whether the connector can be shared. - - - - This method checks if the connector is still ok. - We try to send a simple query text, select 1 as ConnectionTest; - - - - - This method is responsible for releasing all resources associated with this Connector. - - - - - This method is responsible to release all portals used by this Connector. - - - - - Modify the backend statement_timeout value if needed. - - New timeout - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - This method is required to set all the version dependent features flags. - SupportsPrepare means the server can use prepared query plans (7.3+) - - - - - Opens the physical connection to the server. - - Usually called by the RequestConnector - Method of the connection pool manager. - - - - Closes the physical connection to the server. - - - - - Returns next portal index. - - - - - Returns next plan index. - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets the current state of the connection. - - - - - Return Connection String. - - - - - Version of backend server this connector is connected to. - - - - - The physical connection socket to the backend. - - - - - The physical connection stream to the backend. - - - - - The top level stream to the backend. - - - - - Reports if this connector is fully connected. - - - - - The connection mediator. - - - - - Report if the connection is in a transaction. - - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - This class manages all connector objects, pooled AND non-pooled. - - - - Unique static instance of the connector pool - mamager. - - - Map of index to unused pooled connectors, avaliable to the - next RequestConnector() call. - This hashmap will be indexed by connection string. - This key will hold a list of queues of pooled connectors available to be used. - - - Timer for tracking unused connections in pools. - - - - Searches the shared and pooled connector lists for a - matching connector object or creates a new one. - - The NpgsqlConnection that is requesting - the connector. Its ConnectionString will be used to search the - pool for available connectors. - A connector object. - - - - Find a pooled connector. Handle shared/non-shared here. - - - - - Releases a connector, possibly back to the pool for future use. - - - Pooled connectors will be put back into the pool if there is room. - Shared connectors should just have their use count decremented - since they always stay in the shared pool. - - Connection to which the connector is leased. - The connector to release. - - - - Release a pooled connector. Handle shared/non-shared here. - - - - - Find an available pooled connector in the non-shared pool, or create - a new one if none found. - - - - - Put a pooled connector into the pool queue. - - Connection is leased to. - Connector to pool - - - - A queue with an extra Int32 for keeping track of busy connections. - - - - - Connections available to the end user - - - - - Connections currently in use - - - - - Represents information about COPY operation data transfer format as returned by server. - - - - - Only created when a CopyInResponse or CopyOutResponse is received by NpgsqlState.ProcessBackendResponses() - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Represents a PostgreSQL COPY FROM STDIN operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to read data from (if provided by user) - or for writing it (when generated by driver). - Eg. new NpgsqlCopyIn("COPY mytable FROM STDIN", connection, streamToRead).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is run upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is executed upon Start() and all data from fromStream is passed to it as copy data. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, it will be flushed to server as copy data, and operation will be finished immediately. - Otherwise the CopyStream member can be used for writing copy data to server and operation finished with a call to End() or Cancel(). - - - - - Called after writing all data to CopyStream to successfully complete this copy operation. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Will do nothing if current operation is not active. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start(). - User may provide a stream to constructor; it is used to pass to server all data read from it. - Otherwise, call to Start() sets this to a writable NpgsqlCopyInStream that passes all data written to it to server. - In latter case this is only available while the copy operation is active and null otherwise. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields expected on each input row if this operation is currently active, otherwise -1 - - - - - The Command used to execute this copy operation. - - - - - Set before a COPY IN query to define size of internal buffer for reading from given CopyStream. - - - - - Represents an ongoing COPY FROM STDIN operation. - Provides methods to push data to server and end or cancel the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyInResponse. - If CopyStream is already set, it is used to read data to push to server, after which the copy is completed. - Otherwise CopyStream is set to a writable NpgsqlCopyInStream that calls SendCopyData each time it is written to. - - - - - Sends given packet to server as a CopyData message. - Does not check for notifications! Use another thread for that. - - - - - Sends CopyDone message to server. Handles responses, ie. may throw an exception. - - - - - Sends CopyFail message to server. Handles responses, ie. should always throw an exception: - in CopyIn state the server responds to CopyFail with an error response; - outside of a CopyIn state the server responds to CopyFail with an error response; - without network connection or whatever, there's going to eventually be a failure, timeout or user intervention. - - - - - Copy format information returned from server. - - - - - Stream for writing data to a table on a PostgreSQL version 7.4 or newer database during an active COPY FROM STDIN operation. - Passes data exactly as is and when given, so see to it that you use server encoding, correct format and reasonably sized writes! - - - - - Created only by NpgsqlCopyInState.StartCopy() - - - - - Successfully completes copying data to server. Returns after operation is finished. - Does nothing if this stream is not the active copy operation writer. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Does nothing if this stream is not the active copy operation writer. - - - - - Writes given bytes to server. - Fails if this stream is not the active copy operation writer. - - - - - Flushes stream contents to server. - Fails if this stream is not the active copy operation writer. - - - - - Not readable - - - - - Not seekable - - - - - Not supported - - - - - True while this stream can be used to write copy data to server - - - - - False - - - - - True - - - - - False - - - - - Number of bytes written so far - - - - - Number of bytes written so far; not settable - - - - - Represents a PostgreSQL COPY TO STDOUT operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to write results to (if provided by user) - or for reading the results (when generated by driver). - Eg. new NpgsqlCopyOut("COPY (SELECT * FROM mytable) TO STDOUT", connection, streamToWrite).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is run upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is executed upon Start() and all requested copy data is written to toStream immediately. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, all copy data from server will be written to it, and operation will be finished immediately. - Otherwise the CopyStream member can be used for reading copy data from server until no more data is available. - - - - - Flush generated CopyStream at once. Effectively reads and discard all the rest of copy data from server. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start() - - - - - The Command used to execute this copy operation. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Faster alternative to using the generated CopyStream. - - - - - Represents an ongoing COPY TO STDOUT operation. - Provides methods to read data from server or end the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyOutResponse. - If CopyStream is already set, it is used to write data received from server, after which the copy ends. - Otherwise CopyStream is set to a readable NpgsqlCopyOutStream that receives data from server. - - - - - Called from NpgsqlOutStream.Read to read copy data from server. - - - - - Copy format information returned from server. - - - - - Stream for reading data from a table or select on a PostgreSQL version 7.4 or newer database during an active COPY TO STDOUT operation. - Passes data exactly as provided by the server. - - - - - Created only by NpgsqlCopyOutState.StartCopy() - - - - - Discards copy data as long as server pushes it. Returns after operation is finished. - Does nothing if this stream is not the active copy operation reader. - - - - - Not writable. - - - - - Not flushable. - - - - - Copies data read from server to given byte buffer. - Since server returns data row by row, length will differ each time, but it is only zero once the operation ends. - Can be mixed with calls to the more efficient NpgsqlCopyOutStream.Read() : byte[] though that would not make much sense. - - - - - Not seekable - - - - - Not supported - - - - - Returns a whole row of data from server without extra work. - If standard Stream.Read(...) has been called before, it's internal buffers remains are returned. - - - - - True while this stream can be used to read copy data from server - - - - - True - - - - - False - - - - - False - - - - - Number of bytes read so far - - - - - Number of bytes read so far; can not be set. - - - - - Writes given objects into a stream for PostgreSQL COPY in default copy format (not CSV or BINARY). - - - - - Default delimiter. - - - - - Default separator. - - - - - Default null. - - - - - Default escape. - - - - - Default quote. - - - - - Default buffer size. - - - - - Constructor. - - - - - - Flush buffers. - - - - - Flush rows. - - - - - Flush fields. - - - - - Close the serializer. - - - - - Escape sequence for the given character. - - - - - - - Make room for bytes. - - - - - - Add bytes. - - - - - - End row. - - - - - Prefix field. - - - - - Field added. - - - - - Add null. - - - - - Add string. - - - - - - add Int32. - - - - - - Add Int64. - - - - - - Add number. - - - - - - Add bool - - - - - - Add DateTime. - - - - - - Report whether the serializer is active. - - - - - To Stream. - - - - - Delimiter. - - - - - Separator. - - - - - Escape. - - - - - Null. - - - - - Buffer size. - - - - - Report whether space remains in the buffer. - - - - - Strings to escape. - - - - - Escape sequence bytes. - - - - - Represents the method that handles the RowUpdated events. - - The source of the event. - A NpgsqlRowUpdatedEventArgs that contains the event data. - - - - Represents the method that handles the RowUpdating events. - - The source of the event. - A NpgsqlRowUpdatingEventArgs that contains the event data. - - - - This class represents an adapter from many commands: select, update, insert and delete to fill Datasets. - - - - - Default constructor. - - - - - Constructor. - - - - - - Constructor. - - - - - - - Constructor. - - - - - - - Create row updated event. - - - - - - - - - - Create row updating event. - - - - - - - - - - Raise the RowUpdated event. - - - - - - Raise the RowUpdating event. - - - - - - Row updated event. - - - - - Row updating event. - - - - - Delete command. - - - - - Select command. - - - - - Update command. - - - - - Insert command. - - - - - Provides a means of reading a forward-only stream of rows from a PostgreSQL backend. This class cannot be inherited. - - - - - Return the data type name of the column at index . - - - - - Return the data type of the column at index . - - - - - Return the Npgsql specific data type of the column at requested ordinal. - - column position - Appropriate Npgsql type for column. - - - - Return the column name of the column at index . - - - - - Return the data type OID of the column at index . - - FIXME: Why this method returns String? - - - - Has ordinal. - - - - - - - Return the column name of the column named . - - - - - Return the data DbType of the column at index . - - - - - Return the data NpgsqlDbType of the column at index . - - - - - Get specified field value. - /// - - - - - - Get the value of a column as a . - If the differences between and - in handling of days and months is not important to your application, use - instead. - - Index of the field to find. - value of the field. - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Send closed event. - - - - - Gets the value of a column converted to a Guid. - - - - - Gets the value of a column as Int16. - - - - - Gets the value of a column as Int32. - - - - - Gets the value of a column as Int64. - - - - - Gets the value of a column as Single. - - - - - Gets the value of a column as Double. - - - - - Gets the value of a column as String. - - - - - Gets the value of a column as Decimal. - - - - - Gets the value of a column as TimeSpan. - - - - - Copy values from each column in the current row into . - - Destination for column values. - The number of column values copied. - - - - Copy values from each column in the current row into . - - An array appropriately sized to store values from all columns. - The number of column values copied. - - - - Gets the value of a column as Boolean. - - - - - Gets the value of a column as Byte. - - - - - Gets the value of a column as Char. - - - - - Gets the value of a column as DateTime. - - - - - Returns a System.Data.DataTable that describes the column metadata of the DataReader. - - - - - This methods parses the command text and tries to get the tablename - from it. - - - - - Get enumerator. - - - - - - Is raised whenever Close() is called. - - - - - Gets the number of columns in the current row. - - - - - Gets the value of a column in its native format. - - - - - Gets the value of a column in its native format. - - - - - Gets a value indicating the depth of nesting for the current row. Always returns zero. - - - - - Gets a value indicating whether the data reader is closed. - - - - - Contains the column names as the keys - - - - - Contains all unique columns - - - - - This is the primary implementation of NpgsqlDataReader. It is the one used in normal cases (where the - preload-reader option is not set in the connection string to resolve some potential backwards-compatibility - issues), the only implementation used internally, and in cases where CachingDataReader is used, it is still - used to do the actual "leg-work" of turning a response stream from the server into a datareader-style - object - with CachingDataReader then filling it's cache from here. - - - - - Iterate through the objects returned through from the server. - If it's a CompletedResponse the rowsaffected count is updated appropriately, - and we iterate again, otherwise we return it (perhaps updating our cache of pending - rows if appropriate). - - The next we will deal with. - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Closes the data reader object. - - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Advances the data reader to the next row. - - True if the reader was advanced, otherwise false. - - - - Return the value of the column at index . - - - - - Gets raw data from a column. - - - - - Gets raw data from a column. - - - - - Report whether the value in a column is DBNull. - - - - - Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. - - - - - Indicates if NpgsqlDatareader has rows to be read. - - - - - Provides an implementation of NpgsqlDataReader in which all data is pre-loaded into memory. - This operates by first creating a ForwardsOnlyDataReader as usual, and then loading all of it's - Rows into memory. There is a general principle that when there is a trade-off between a class design that - is more efficient and/or scalable on the one hand and one that is less efficient but has more functionality - (in this case the internal-only functionality of caching results) that one can build the less efficent class - from the most efficient without significant extra loss in efficiency, but not the other way around. The relationship - between ForwardsOnlyDataReader and CachingDataReader is an example of this). - Since the interface presented to the user is still forwards-only, queues are used to - store this information, so that dequeueing as we go we give the garbage collector the best opportunity - possible to reclaim any memory that is no longer in use. - ForwardsOnlyDataReader being used to actually - obtain the information from the server means that the "leg-work" is still only done (and need only be - maintained) in one place. - This class exists to allow for certain potential backwards-compatibility issues to be resolved - with little effort on the part of affected users. It is considerably less efficient than ForwardsOnlyDataReader - and hence never used internally. - - - - - This is the base class for NpgsqlDescribeStatement and NpgsqlDescribePortal. - - - - - - This class represents the Statement Describe message sent to PostgreSQL - server. - - - - - - This class represents the Portal Describe message sent to PostgreSQL - server. - - - - - - EventArgs class to send Notice parameters, which are just NpgsqlError's in a lighter context. - - - - - Notice information. - - - - - This class represents the ErrorResponse and NoticeResponse - message sent from PostgreSQL server. - - - - - Return a string representation of this error object. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Terse error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Internal query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Backend protocol version in use. - - - - - Error and notice message field codes - - - - - Severity: the field contents are ERROR, FATAL, or PANIC (in an error message), - or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a localized - translation of one of these. Always present. - - - - - Code: the SQLSTATE code for the error (see Appendix A). Not localizable. Always present. - - - - - Message: the primary human-readable error message. This should be accurate - but terse (typically one line). Always present. - - - - - Detail: an optional secondary error message carrying more detail about the problem. - Might run to multiple lines. - - - - - Hint: an optional suggestion what to do about the problem. This is intended to differ - from Detail in that it offers advice (potentially inappropriate) rather than hard facts. - Might run to multiple lines. - - - - - Position: the field value is a decimal ASCII integer, indicating an error cursor - position as an index into the original query string. The first character has index 1, - and positions are measured in characters not bytes. - - - - - Internal position: this is defined the same as the P field, but it is used when the - cursor position refers to an internally generated command rather than the one submitted - by the client. - The q field will always appear when this field appears. - - - - - Internal query: the text of a failed internally-generated command. - This could be, for example, a SQL query issued by a PL/pgSQL function. - - - - - Where: an indication of the context in which the error occurred. - Presently this includes a call stack traceback of active procedural language functions - and internally-generated queries. The trace is one entry per line, most recent first. - - - - - Schema name: if the error was associated with a specific database object, - the name of the schema containing that object, if any. - - - - - Table name: if the error was associated with a specific table, the name of the table. - (Refer to the schema name field for the name of the table's schema.) - - - - - Column name: if the error was associated with a specific table column, the name of the column. - (Refer to the schema and table name fields to identify the table.) - - - - - Data type name: if the error was associated with a specific data type, the name of the data type. - (Refer to the schema name field for the name of the data type's schema.) - - - - - Constraint name: if the error was associated with a specific constraint, the name of the constraint. - Refer to fields listed above for the associated table or domain. - (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.) - - - - - File: the file name of the source-code location where the error was reported. - - - - - Line: the line number of the source-code location where the error was reported. - - - - - Routine: the name of the source-code routine reporting the error. - - - - - The level of verbosity of the NpgsqlEventLog - - - - - Don't log at all - - - - - Only log the most common issues - - - - - Log everything - - - - - This class handles all the Npgsql event and debug logging - - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - - This method is obsolete and should no longer be used. - It is likely to be removed in future versions of Npgsql - - The message to write to the event log - The minimum LogLevel for which this message should be logged. - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - The ResourceManager to get the localized resources - The name of the resource that should be fetched by the ResourceManager - The minimum LogLevel for which this message should be logged. - The additional parameters that shall be included into the log-message (must be compatible with the string in the resource): - - - - Writes the default log-message for the action of calling the Get-part of an Indexer to the log file. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - - - - Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - The value the Indexer is set to - - - - Writes the default log-message for the action of calling the Get-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - - - - Writes the default log-message for the action of calling the Set-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - The value the Property is set to - - - - Writes the default log-message for the action of calling a Method without Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - - - - Writes the default log-message for the action of calling a Method with one Argument to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the Argument of the Method - - - - Writes the default log-message for the action of calling a Method with two Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - - - - Writes the default log-message for the action of calling a Method with three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - The value of the third Argument of the Method - - - - Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - A Object-Array with zero or more Ojects that are Arguments of the Method. - - - - Sets/Returns the filename to use for logging. - - The filename of the current Log file. - - - - Sets/Returns whether Log messages should be echoed to the console - - true if Log messages are echoed to the console, otherwise false - - - - The exception that is thrown when the PostgreSQL backend reports errors. - - - - - Construct a backend error exception based on a list of one or more - backend errors. The basic Exception.Message will be built from the - first (usually the only) error in the list. - - - - - Get object data. - - - - - - - Format a .NET style exception string. - Include all errors in the list, including any hints. - - - - - Append a line to the given Stream, first checking for zero-length. - - - - - Provide access to the entire list of errors provided by the PostgreSQL backend. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Basic error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Returns the entire list of errors provided by the PostgreSQL backend. - - - - - This class represents the Execute message sent to PostgreSQL - server. - - - - - - A factory to create instances of various Npgsql objects. - - - - - Creates an NpgsqlCommand object. - - - - - This class represents the Flush message sent to PostgreSQL - server. - - - - - - For classes representing simple messages, - consisting only of a message code and length identifier, - sent from the client to the server. - - - - - This class is responsible for serving as bridge between the backend - protocol handling and the core classes. It is used as the mediator for - exchanging data generated/sent from/to backend. - - - - - - The current command timeout on the backend. This is set via "SET statement_timeout = (milliseconds)". - A value of -1 means the backend's timeout value is unknown because it has not yet been set. - - - - - EventArgs class to send Notification parameters. - - - - - Process ID of the PostgreSQL backend that sent this notification. - - - - - Condition that triggered that notification. - - - - - Additional Information From Notifiying Process (for future use, currently postgres always sets this to an empty string) - - - - - This class represents a parameter to a command that will be sent to server - - - - - Initializes a new instance of the NpgsqlParameter class. - - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and a value of the new NpgsqlParameter. - - The m_Name of the parameter to map. - An Object that is the value of the NpgsqlParameter. - -

When you specify an Object - in the value parameter, the DbType is - inferred from the .NET Framework type of the Object.

-

When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. - This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. - Use Convert.ToInt32(value) for example to have compiler calling the correct constructor.

-
-
- - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and the data type. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Reset DBType. - - - - - Creates a new NpgsqlParameter that - is a copy of the current instance. - - A new NpgsqlParameter that is a copy of this instance. - - - - The collection to which this parameter belongs, if any. - - - - - Gets or sets the maximum number of digits used to represent the - Value property. - - The maximum number of digits used to represent the - Value property. - The default value is 0, which indicates that the data provider - sets the precision for Value. - - - - Whether to use an explicit cast when included in a query. - - - - - Gets or sets the number of decimal places to which - Value is resolved. - - The number of decimal places to which - Value is resolved. The default is 0. - - - - Gets or sets the maximum size, in bytes, of the data within the column. - - The maximum size, in bytes, of the data within the column. - The default value is inferred from the parameter value. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets a value indicating whether the parameter is input-only, - output-only, bidirectional, or a stored procedure return value parameter. - - One of the ParameterDirection - values. The default is Input. - - - - Gets or sets a value indicating whether the parameter accepts null values. - - true if null values are accepted; otherwise, false. The default is false. - - - - Gets or sets the m_Name of the NpgsqlParameter. - - The m_Name of the NpgsqlParameter. - The default is an empty string. - - - - The m_Name scrubbed of any optional marker - - - - - Gets or sets the m_Name of the source column that is mapped to the - DataSet and used for loading or - returning the Value. - - The m_Name of the source column that is mapped to the - DataSet. The default is an empty string. - - - - Gets or sets the DataRowVersion - to use when loading Value. - - One of the DataRowVersion values. - The default is Current. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Source column mapping. - - - - - Represents a collection of parameters relevant to a NpgsqlCommand - as well as their respective mappings to columns in a DataSet. - This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlParameterCollection class. - - - - - Invalidate the hash lookup tables. This should be done any time a change - may throw the lookups out of sync with the list. - - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The index of the new NpgsqlParameter object. - - - - Obsolete. Use AddWithValue instead. - - - Use caution when using this overload of the - Add method to specify integer parameter values. - Because this overload takes a value of type Object, - you must convert the integral value to an Object - type when the value is zero, as the following C# example demonstrates. - parameters.Add(":pname", Convert.ToInt32(0)); - If you do not perform this conversion, the compiler will assume you - are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload. - - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The name of the source column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the parameter name and the data type. - - The name of the parameter. - One of the DbType values. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, and the column length. - - The name of the parameter. - One of the DbType values. - The length of the column. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, the column length, and the source column name. - - The name of the parameter. - One of the DbType values. - The length of the column. - The name of the source column. - The index of the new NpgsqlParameter object. - - - - Removes the specified NpgsqlParameter from the collection using the parameter name. - - The name of the NpgsqlParameter object to retrieve. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - true if the collection contains the parameter; otherwise, false. - - - - Gets the location of the NpgsqlParameter in the collection with a specific parameter name. - - The name of the NpgsqlParameter object to find. - The zero-based location of the NpgsqlParameter in the collection. - - - - Removes the specified NpgsqlParameter from the collection using a specific index. - - The zero-based index of the parameter. - - - - Inserts a NpgsqlParameter into the collection at the specified index. - - The zero-based index where the parameter is to be inserted within the collection. - The NpgsqlParameter to add to the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The name of the NpgsqlParameter to remove from the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The NpgsqlParameter to remove from the collection. - - - - Gets a value indicating whether a NpgsqlParameter exists in the collection. - - The value of the NpgsqlParameter object to find. - true if the collection contains the NpgsqlParameter object; otherwise, false. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - A reference to the requested parameter is returned in this out param if it is found in the list. This value is null if the parameter is not found. - true if the collection contains the parameter and param will contain the parameter; otherwise, false. - - - - Removes all items from the collection. - - - - - Gets the location of a NpgsqlParameter in the collection. - - The value of the NpgsqlParameter object to find. - The zero-based index of the NpgsqlParameter object in the collection. - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The zero-based index of the new NpgsqlParameter object. - - - - Copies NpgsqlParameter objects from the NpgsqlParameterCollection to the specified array. - - An Array to which to copy the NpgsqlParameter objects in the collection. - The starting index of the array. - - - - Returns an enumerator that can iterate through the collection. - - An IEnumerator that can be used to iterate through the collection. - - - - Add an Array of parameters to the collection. - - Parameters to add. - - - - Get parameter. - - - - - - - Get parameter. - - - - - - - Set parameter. - - - - - - - Set parameter. - - - - - - - In methods taking an object as argument this method is used to verify - that the argument has the type NpgsqlParameter - - The object to verify - - - - Report the offset within the collection of the given parameter. - - Parameter to find. - Index of the parameter, or -1 if the parameter is not present. - - - - Insert the specified parameter into the collection. - - Index of the existing parameter before which to insert the new one. - Parameter to insert. - - - - Report whether the specified parameter is present in the collection. - - Parameter to find. - True if the parameter was found, otherwise false. - - - - Remove the specified parameter from the collection. - - Parameter to remove. - True if the parameter was found and removed, otherwise false. - - - - Convert collection to a System.Array. - - Destination array. - Starting index in destination array. - - - - Convert collection to a System.Array. - - NpgsqlParameter[] - - - - Gets the NpgsqlParameter with the specified name. - - The name of the NpgsqlParameter to retrieve. - The NpgsqlParameter with the specified name, or a null reference if the parameter is not found. - - - - Gets the NpgsqlParameter at the specified index. - - The zero-based index of the NpgsqlParameter to retrieve. - The NpgsqlParameter at the specified index. - - - - Report whether the collection is read only. Always false. - - - - - Report whether the collection is fixed size. Always false. - - - - - Report whether the collection is synchronized. - - - - - Gets the number of NpgsqlParameter objects in the collection. - - The number of NpgsqlParameter objects in the collection. - - - - Sync root. - - - - - This class represents the ParameterStatus message sent from PostgreSQL - server. - - - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - This class represents a PasswordPacket message sent to backend - PostgreSQL. - - - - - Used when a connection is closed - - - - - This is the abstract base class for NpgsqlAsciiRow and NpgsqlBinaryRow. - - - - - The index of the current field in the stream, i.e. the one that hasn't - been read yet - - - - - This class represents a RowDescription message sent from - the PostgreSQL. - - - - - - This struct represents the internal data of the RowDescription message. - - - - - Provides the underlying mechanism for reading schema information. - - - - - Returns the MetaDataCollections that lists all possible collections. - - The MetaDataCollections - - - - Returns the Restrictions that contains the meaning and position of the values in the restrictions array. - - The Restrictions - - - - Returns the Databases that contains a list of all accessable databases. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Databases - - - - Returns the Tables that contains table and view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Tables - - - - Returns the Columns that contains information about columns in tables. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Columns. - - - - Returns the Views that contains view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Views - - - - Returns the Users containing user names and the sysid of those users. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Users. - - - - This class represents a StartupPacket message of PostgreSQL - protocol. - - - - - - Represents a completed response message. - - - - - This class represents the Sync message sent to PostgreSQL - server. - - - - - - Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited. - - - - - Dispose. - - - - - - Commits the database transaction. - - - - - Rolls back a transaction from a pending state. - - - - - Rolls back a transaction from a pending savepoint state. - - - - - Creates a transaction save point. - - - - - Cancel the transaction without telling the backend about it. This is - used to make the transaction go away when closing a connection. - - - - - Gets the NpgsqlConnection - object associated with the transaction, or a null reference if the - transaction is no longer valid. - - The NpgsqlConnection - object associated with the transaction. - - - - DB connection. - - - - - Specifies the IsolationLevel for this transaction. - - The IsolationLevel for this transaction. - The default is ReadCommitted. - - - - This class provides many util methods to handle - reading and writing of PostgreSQL protocol messages. - - - - - This method takes a ProtocolVersion and returns an integer - version number that the Postgres backend will recognize in a - startup packet. - - - - - This method takes a version string as returned by SELECT VERSION() and returns - a valid version string ("7.2.2" for example). - This is only needed when running protocol version 2. - This does not do any validity checks. - - - - - This method gets a C NULL terminated string from the network stream. - It keeps reading a byte in each time until a NULL byte is returned. - It returns the resultant string of bytes read. - This string is sent from backend. - - - - - Reads requested number of bytes from stream with retries until Stream.Read returns 0 or count is reached. - - Stream to read - byte buffer to fill - starting position to fill the buffer - number of bytes to read - The number of bytes read. May be less than count if no more bytes are available. - - - - Reads requested number of bytes from . If output matches exactly, and == false, is returned directly. - - Source array. - Starting position to read from - Number of bytes to read - Force a copy, even if the output is an exact copy of . - byte[] containing data requested. - - - - This method writes a string to the network stream. - - - - - This method writes a string to the network stream. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a C NULL terminated string limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - This method writes a C NULL terminated byte[] limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - Write a 32-bit integer to the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given array in the correct byte order. - - - - - Write a 16-bit integer to the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given array in the correct byte order. - - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Starting offset in source array. - Number of bytes to copy. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Represent the frontend/backend protocol version. - - - - - Represent the backend server version. - As this class offers no functionality beyond that offered by it has been - deprecated in favour of that class. - - - - - - Returns the string representation of this version in three place dot notation (Major.Minor.Patch). - - - - - Server version major number. - - - - - Server version minor number. - - - - - Server version patch level number. - - - - - A class to handle everything associated with SSPI authentication - - - - - Simplified SecBufferDesc struct with only one SecBuffer - - -
-
diff --git a/src/packages/Npgsql.2.2.3/lib/net40/de/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net40/de/Npgsql.resources.dll deleted file mode 100644 index ad6f40a7f..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/de/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/es/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net40/es/Npgsql.resources.dll deleted file mode 100644 index ed80f9b75..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/es/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/fi/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net40/fi/Npgsql.resources.dll deleted file mode 100644 index d2510695f..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/fi/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/fr/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net40/fr/Npgsql.resources.dll deleted file mode 100644 index 9bf42f30a..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/fr/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/ja/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net40/ja/Npgsql.resources.dll deleted file mode 100644 index 0013a63b2..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/ja/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net40/zh-CN/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net40/zh-CN/Npgsql.resources.dll deleted file mode 100644 index c86b87291..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net40/zh-CN/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/Mono.Security.dll b/src/packages/Npgsql.2.2.3/lib/net45/Mono.Security.dll deleted file mode 100644 index 62ae33940..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/Mono.Security.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/Npgsql.dll b/src/packages/Npgsql.2.2.3/lib/net45/Npgsql.dll deleted file mode 100644 index ac98b763c..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/Npgsql.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/Npgsql.xml b/src/packages/Npgsql.2.2.3/lib/net45/Npgsql.xml deleted file mode 100644 index 332e24dd4..000000000 --- a/src/packages/Npgsql.2.2.3/lib/net45/Npgsql.xml +++ /dev/null @@ -1,6502 +0,0 @@ - - - - Npgsql - - - - - Handles serialisation of .NET array or IEnumeration to pg format. - Arrays of arrays, enumerations of enumerations, arrays of enumerations etc. - are treated as multi-dimensional arrays (in much the same manner as an array of arrays - is used to emulate multi-dimensional arrays in languages that lack native support for them). - If such an enumeration of enumerations is "jagged" (as opposed to rectangular, cuboid, - hypercuboid, hyperhypercuboid, etc) then this class will "correctly" serialise it, but pg - will raise an error as it doesn't allow jagged arrays. - - - - - Create an ArrayNativeToBackendTypeConverter with the element converter passed - - The that would be used to serialise the element type. - - - - Serialise the enumeration or array. - - - - - Convert a System.Array to PG binary format. - Write the array header and prepare to write array data to the stream. - - - - - Append all array data to the binary stream. - - - - - Handles parsing of pg arrays into .NET arrays. - - - - - Takes a string representation of a pg 1-dimensional array - (or a 1-dimensional row within an n-dimensional array) - and allows enumeration of the string represenations of each items. - - - - - Takes a string representation of a pg n-dimensional array - and allows enumeration of the string represenations of the next - lower level of rows (which in turn can be taken as (n-1)-dimensional arrays. - - - - - Takes an ArrayList which may be an ArrayList of ArrayLists, an ArrayList of ArrayLists of ArrayLists - and so on and enumerates the items that aren't ArrayLists (the leaf nodes if we think of the ArrayList - passed as a tree). Simply uses the ArrayLists' own IEnumerators to get that of the next, - pushing them onto a stack until we hit something that isn't an ArrayList. - ArrayList to enumerate - IEnumerable - - - - - Create a new ArrayBackendToNativeTypeConverter - - for the element type. - - - - Creates an array from pg text representation. - - - - - Creates an array list from pg represenation of an array. - Multidimensional arrays are treated as ArrayLists of ArrayLists - - - - - Creates an n-dimensional array from an ArrayList of ArrayLists or - a 1-dimensional array from something else. - - to convert - Type of the elements in the list - produced. - - - - Creates an n-dimensional System.Array from PG binary representation. - This function reads the array header and sets up an n-dimensional System.Array object to hold its data. - PopulateArrayFromBinaryArray() is then called to carry out array population. - - - - - Recursively populates an array from PB binary data representation. - - - - - Takes an array of ints and treats them like the limits of a set of counters. - Retains a matching set of ints that is set to all zeros on the first ++ - On a ++ it increments the "right-most" int. If that int reaches it's - limit it is set to zero and the one before it is incremented, and so on. - - Making this a more general purpose class is pretty straight-forward, but we'll just put what we need here. - - - - - Implements a bit string; a collection of zero or more bits which can each be 1 or 0. - BitString's behave as a list of bools, though like most strings and unlike most collections the position - tends to be of as much significance as the value. - BitStrings are often used as masks, and are commonly cast to and from other values. - - - - - Represents the empty string. - - - - - Create a BitString from an enumeration of boolean values. The BitString will contain - those booleans in the order they came in. - - The boolean values. - - - - Creates a BitString filled with a given number of true or false values. - - The value to fill the string with. - The number of bits to fill. - - - - Creats a bitstring from a string. - The string to copy from. - - - - - - Creates a single-bit element from a boolean value. - - The bool value which determines whether - the bit is 1 or 0. - - - - Creates a bitstring from an unsigned integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - This method is not CLS Compliant, and may not be available to some languages. - - - - Creates a bitstring from an integer value. The string will be the shortest required to - contain the integer (e.g. 1 bit for 0 or 1, 2 for 2 or 3, 3 for 4-7, and so on). - - The integer. - - - - Finds the first instance of a given value - - The value - whether true or false - to search for. - The index of the value found, or -1 if none are present. - - - - True if there is at least one bit with the value looked for. - - The value - true or false - to detect. - True if at least one bit was the same as item, false otherwise. - - - - Copies the bitstring to an array of bools. - - The boolean array to copy to. - The index in the array to start copying from. - - - - Returns an enumerator that enumerates through the string. - - The enumerator. - - - - Creats a bitstring by concatenating another onto this one. - - The string to append to this one. - The combined strings. - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string. - The length of the string to return, must be greater than zero, and may not be - so large that the start + length exceeds the bounds of this instance. - The Bitstring identified - - - - Returns a substring of this string. - - The position to start from, must be between 0 and the length of the string, - the rest of the string is returned. - The Bitstring identified - - - - A logical and between this string and another. The two strings must be the same length. - - Another BitString to AND with this one. - A bitstring with 1 where both BitStrings had 1 and 0 otherwise. - - - - A logical or between this string and another. The two strings must be the same length. - - Another BitString to OR with this one. - A bitstring with 1 where either BitString had 1 and 0 otherwise. - - - - A logical xor between this string and another. The two strings must be the same length. - - Another BitString to XOR with this one. - A bitstring with 1 where one BitStrings and the other had 0, - and 0 where they both had 1 or both had 0. - - - - A bitstring that is the logical inverse of this one. - - A bitstring of the same length as this with 1 where this has 0 and vice-versa. - - - - Shifts the string operand bits to the left, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the left. - A left-shifted bitstring. - The behaviour of LShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a right-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. - - - - - Shifts the string operand bits to the right, filling with zeros to produce a - string of the same length. - - The number of bits to shift to the right. - A right-shifted bitstring. - The behaviour of RShift is closer to what one would expect from dealing - with PostgreSQL bit-strings than in using the same operations on integers in .NET - In particular, negative operands result in a left-shift, and operands greater than - the length of the string will shift it entirely, resulting in a zero-filled string. It also performs - a logical shift, rather than an arithmetic shift, so it always sets the vacated bit positions to zero - (like PostgreSQL and like .NET for unsigned integers but not for signed integers). - - - - - Returns true if the this string is identical to the argument passed. - - - - - Compares two strings. Strings are compared as strings, so while 0 being less than 1 will - mean a comparison between two strings of the same size is the same as treating them as numbers, - in the case of two strings of differing lengths the comparison starts at the right-most (most significant) - bit, and if all bits of the shorter string are exhausted without finding a comparison, then the larger - string is deemed to be greater than the shorter (0010 is greater than 0001 but less than 00100). - - Another string to compare with this one. - A value if the two strings are identical, an integer less - than zero if this is less than the argument, and an integer greater - than zero otherwise. - - - - Compares the string with another object. - - The object to compare with. - If the object is null then this string is considered greater. If the object is another BitString - then they are compared as in the explicit comparison for BitStrings - in any other case a is thrown. - - - - Compares this BitString with an object for equality. - - - - - Returns a code for use in hashing operations. - - - - - Returns a string representation of the BitString. - - - A string which can contain a letter and optionally a number which sets a minimum size for the string - returned. In each case using the lower-case form of the letter will result in a lower-case string - being returned. - - - B - A string of 1s and 0s. - - - X - An hexadecimal string (will result in an error unless the string's length is divisible by 4). - - - G - A string of 1s and 0s in single-quotes preceded by 'B' (Postgres bit string literal syntax). - - Y - An hexadecimal string in single-quotes preceded by 'X' (Postgres bit literal syntax, will result in an error unless the string's length is divisible by 4. - - C - The format produced by format-string "Y" if legal, otherwise that produced by format-string "G". - E - The most compact safe representation for Postgres. If single bit will be either a 0 or a 1. Otherwise if it - can be that produce by format string "Y" it will, otherwise if there are less than 9bits in length it will be that - produced by format-string "G". For longer strings that cannot be represented in hexadecimal it will be a string - representing the first part of the string in format "Y" followed by the PostgreSQL concatenation operator, followed - by the final bits in the format "G". E.g. "X'13DCE'||B'110'" - If format is empty or null, it is treated as if "B" had been passed (the default repreesentation, and that - generally used by PostgreSQL for display). - - The formatted string. - - - - Returns a string representation for the Bitstring - - A string containing '0' and '1' characters. - - - - Returns the same string as . formatProvider is ignored. - - - - - Parses a string to produce a BitString. Most formats that can be produced by - can be accepted, but hexadecimal - can be interpreted with the preceding X' to mark the following characters as - being hexadecimal rather than binary. - - - - - Performs a logical AND on the two operands. - - - - - Performs a logcial OR on the two operands. - - - - - Perofrms a logical EXCLUSIVE-OR on the two operands - - - - - Performs a logical NOT on the operand. - - - - - Concatenates the operands. - - - - - Left-shifts the string BitString. - - - - - Right-shifts the string BitString. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Compares the two operands. - - - - - Interprets the bitstring as a series of bits in an encoded character string, - encoded according to the Encoding passed, and returns that string. - The bitstring must contain a whole number of octets(bytes) and also be - valid according to the Encoding passed. - - The to use in producing the string. - The string that was encoded in the BitString. - - - - Interprets the bitstring as a series of octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - - - - - Interprets the bitstring as a series of signed octets (bytes) and returns those octets. Fails - if the Bitstring does not contain a whole number of octets (its length is not evenly - divisible by 8). - This method is not CLS-Compliant and may not be available to languages that cannot - handle signed bytes. - - - - - Interprets the bitstring as a series of unsigned 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of 16-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 16. - - - - - Interprets the bitstring as a series of unsigned 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 32-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 32. - - - - - Interprets the bitstring as a series of unsigned 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - This method is not CLS-Compliant and may not be available to languages that cannot - handle unsigned integers. - - - - - Interprets the bitstring as a series of signed 64-bit integers and returns those integers. - Fails if the Bitstring's length is not evenly divisible by 64. - - - - - The length of the string. - - - - - Retrieves the value of the bit at the given index. - - - - - Represents the PostgreSQL interval datatype. - PostgreSQL differs from .NET in how it's interval type doesn't assume 24 hours in a day - (to deal with 23- and 25-hour days caused by daylight savings adjustments) and has a concept - of months that doesn't exist in .NET's class. (Neither datatype - has any concessions for leap-seconds). - For most uses just casting to and from TimeSpan will work correctly — in particular, - the results of subtracting one or the PostgreSQL date, time and - timestamp types from another should be the same whether you do so in .NET or PostgreSQL — - but if the handling of days and months in PostgreSQL is important to your application then you - should use this class instead of . - If you don't know whether these differences are important to your application, they - probably arent! Just use and do not use this class directly ☺ - To avoid forcing unnecessary provider-specific concerns on users who need not be concerned - with them a call to on a field containing an - value will return a rather than an - . If you need the extra functionality of - then use . - - - - - - - - - - Represents the number of ticks (100ns periods) in one microsecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one millisecond. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one second. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one minute. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one hour. This field is constant. - - - - - Represents the number of ticks (100ns periods) in one day. This field is constant. - - - - - Represents the number of hours in one day (assuming no daylight savings adjustments). This field is constant. - - - - - Represents the number of days assumed in one month if month justification or unjustifcation is performed. - This is set to 30 for consistency with PostgreSQL. Note that this is means that month adjustments cause - a year to be taken as 30 × 12 = 360 rather than 356/366 days. - - - - - Represents the number of ticks (100ns periods) in one day, assuming 30 days per month. - - - - - Represents the number of months in a year. This field is constant. - - - - - Represents the maximum . This field is read-only. - - - - - Represents the minimum . This field is read-only. - - - - - Represents the zero . This field is read-only. - - - - - Initializes a new to the specified number of ticks. - - A time period expressed in 100ns units. - - - - Initializes a new to hold the same time as a - - A time period expressed in a - - - - Initializes a new to the specified number of months, days - & ticks. - - Number of months. - Number of days. - Number of 100ns units. - - - - Initializes a new to the specified number of - days, hours, minutes & seconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - - - - Initializes a new to the specified number of - days, hours, minutes, seconds & milliseconds. - - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - months, days, hours, minutes, seconds & milliseconds. - - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Initializes a new to the specified number of - years, months, days, hours, minutes, seconds & milliseconds. - Years are calculated exactly equivalent to 12 months. - - Number of years. - Number of months. - Number of days. - Number of hours. - Number of minutes. - Number of seconds. - Number of milliseconds. - - - - Creates an from a number of ticks. - - The number of ticks (100ns units) in the interval. - A d with the given number of ticks. - - - - Creates an from a number of microseconds. - - The number of microseconds in the interval. - A d with the given number of microseconds. - - - - Creates an from a number of milliseconds. - - The number of milliseconds in the interval. - A d with the given number of milliseconds. - - - - Creates an from a number of seconds. - - The number of seconds in the interval. - A d with the given number of seconds. - - - - Creates an from a number of minutes. - - The number of minutes in the interval. - A d with the given number of minutes. - - - - Creates an from a number of hours. - - The number of hours in the interval. - A d with the given number of hours. - - - - Creates an from a number of days. - - The number of days in the interval. - A d with the given number of days. - - - - Creates an from a number of months. - - The number of months in the interval. - A d with the given number of months. - - - - Adds another interval to this instance and returns the result. - - An to add to this instance. - An whose values are the sums of the two instances. - - - - Subtracts another interval from this instance and returns the result. - - An to subtract from this instance. - An whose values are the differences of the two instances. - - - - Returns an whose value is the negated value of this instance. - - An whose value is the negated value of this instance. - - - - This absolute value of this instance. In the case of some, but not all, components being negative, - the rules used for justification are used to determine if the instance is positive or negative. - - An whose value is the absolute value of this instance. - - - - Equivalent to PostgreSQL's justify_days function. - - An based on this one, but with any hours outside of the range [-23, 23] - converted into days. - - - - Opposite to PostgreSQL's justify_days function. - - An based on this one, but with any days converted to multiples of ±24hours. - - - - Equivalent to PostgreSQL's justify_months function. - - An based on this one, but with any days outside of the range [-30, 30] - converted into months. - - - - Opposite to PostgreSQL's justify_months function. - - An based on this one, but with any months converted to multiples of ±30days. - - - - Equivalent to PostgreSQL's justify_interval function. - - An based on this one, - but with any months converted to multiples of ±30days - and then with any days converted to multiples of ±24hours - - - - Opposite to PostgreSQL's justify_interval function. - - An based on this one, but with any months converted to multiples of ±30days and then any days converted to multiples of ±24hours; - - - - Produces a canonical NpgslInterval with 0 months and hours in the range of [-23, 23]. - - - While the fact that for many purposes, two different instances could be considered - equivalent (e.g. one with 2days, 3hours and one with 1day 27hours) there are different possible canonical forms. - - E.g. we could move all excess hours into days and all excess days into months and have the most readable form, - or we could move everything into the ticks and have the form that allows for the easiest arithmetic) the form - chosen has two important properties that make it the best choice. - First, it is closest two how - objects are most often represented. Second, it is compatible with results of many - PostgreSQL functions, particularly with age() and the results of subtracting one date, time or timestamp from - another. - - Note that the results of casting a to is - canonicalised. - - - An based on this one, but with months converted to multiples of ±30days and with any hours outside of the range [-23, 23] - converted into days. - - - - Implicit cast of a to an - - A - An eqivalent, canonical, . - - - - Implicit cast of an to a . - - A . - An equivalent . - - - - Returns true if another is exactly the same as this instance. - - An for comparison. - true if the two instances are exactly the same, - false otherwise. - - - - Returns true if another object is an , that is exactly the same as - this instance - - An for comparison. - true if the argument is an and is exactly the same - as this one, false otherwise. - - - - Compares two instances. - - The first . - The second . - 0 if the two are equal or equivalent. A value greater than zero if x is greater than y, - a value less than zero if x is less than y. - - - - A hash code suitable for uses with hashing algorithms. - - An signed integer. - - - - Compares this instance with another/ - - An to compare this with. - 0 if the instances are equal or equivalent. A value less than zero if - this instance is less than the argument. A value greater than zero if this instance - is greater than the instance. - - - - Compares this instance with another/ - - An object to compare this with. - 0 if the argument is an and the instances are equal or equivalent. - A value less than zero if the argument is an and - this instance is less than the argument. - A value greater than zero if the argument is an and this instance - is greater than the instance. - A value greater than zero if the argument is null. - The argument is not an . - - - - Parses a and returns a instance. - Designed to use the formats generally returned by PostgreSQL. - - The to parse. - An represented by the argument. - The string was null. - A value obtained from parsing the string exceeded the values allowed for the relevant component. - The string was not in a format that could be parsed to produce an . - - - - Attempt to parse a to produce an . - - The to parse. - (out) The produced, or if the parsing failed. - true if the parsing succeeded, false otherwise. - - - - Create a representation of the instance. - The format returned is of the form: - [M mon[s]] [d day[s]] [HH:mm:ss[.f[f[f[f[f[f[f[f[f]]]]]]]]]] - A zero is represented as 00:00:00 - - Ticks are 100ns, Postgress resolution is only to 1µs at most. Hence we lose 1 or more decimal - precision in storing values in the database. Despite this, this method will output that extra - digit of precision. It's forward-compatible with any future increases in resolution up to 100ns, - and also makes this ToString() more applicable to any other use-case. - - - The representation. - - - - Adds two together. - - The first to add. - The second to add. - An whose values are the sum of the arguments. - - - - Subtracts one from another. - - The to subtract the other from. - The to subtract from the other. - An whose values are the difference of the arguments - - - - Returns true if two are exactly the same. - - The first to compare. - The second to compare. - true if the two arguments are exactly the same, false otherwise. - - - - Returns false if two are exactly the same. - - The first to compare. - The second to compare. - false if the two arguments are exactly the same, true otherwise. - - - - Compares two instances to see if the first is less than the second - - The first to compare. - The second to compare. - true if the first is less than second, false otherwise. - - - - Compares two instances to see if the first is less than or equivalent to the second - - The first to compare. - The second to compare. - true if the first is less than or equivalent to second, false otherwise. - - - - Compares two instances to see if the first is greater than the second - - The first to compare. - The second to compare. - true if the first is greater than second, false otherwise. - - - - Compares two instances to see if the first is greater than or equivalent the second - - The first to compare. - The second to compare. - true if the first is greater than or equivalent to the second, false otherwise. - - - - Returns the instance. - - An . - The argument. - - - - Negates an instance. - - An . - The negation of the argument. - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. This ignores the number of days and - months held. If you want them included use first. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - interval(0) - resolution of 1s (1 second) - - - interval(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - interval(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - interval(3) - resolution of 1ms = 0.001s (1 millisecond) - - - interval(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - interval(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - interval(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL interval will - not suffice for those purposes. - In more frequent cases though, the resolution of the interval suffices. - will always suffice to handle the resolution of any interval value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An in the range [-999999, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An in the range [-999, 999]. - - - - - Gets the number of whole seconds held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole minutes held in the instance. - An in the range [-59, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that this can be less than -23 or greater than 23 unless - has been used to produce this instance. - - - - - Gets the number of days held in the instance. - Note that this does not pay attention to a time component with -24 or less hours or - 24 or more hours, unless has been called to produce this instance. - - - - - Gets the number of months held in the instance. - Note that this does not pay attention to a day component with -30 or less days or - 30 or more days, unless has been called to produce this instance. - - - - - Returns a representing the time component of the instance. - Note that this may have a value beyond the range ±23:59:59.9999999 unless - has been called to produce this instance. - - - - - The total number of ticks (100ns units) in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of microseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of milliseconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of seconds in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of minutes in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of hours in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of days in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - The total number of months in the instance, assuming 24 hours in each day and - 30 days in a month. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - The total number of ticks(100ns units) contained. This is the resolution of the - type. - The resolution of the PostgreSQL - interval type is by default 1µs = 1,000 ns. It may be smaller as follows: - - - time(0) - resolution of 1s (1 second) - - - time(1) - resolution of 100ms = 0.1s (100 milliseconds) - - - time(2) - resolution of 10ms = 0.01s (10 milliseconds) - - - time(3) - resolution of 1ms = 0.001s (1 millisecond) - - - time(4) - resolution of 100µs = 0.0001s (100 microseconds) - - - time(5) - resolution of 10µs = 0.00001s (10 microseconds) - - - time(6) or interval - resolution of 1µs = 0.000001s (1 microsecond) - - - As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL time will - not suffice for those purposes. - In more frequent cases though, the resolution of time suffices. - will always suffice to handle the resolution of any time value, and upon - writing to the database, will be rounded to the resolution used. - - The number of ticks in the instance. - - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - Normalise this time; if it is 24:00:00, convert it to 00:00:00 - - This time, normalised - - - - Compares this with another . As per postgres' rules, - first the times are compared as if they were both in the same timezone. If they are equal then - then timezones are compared (+01:00 being "smaller" than -01:00). - - the to compare with. - An integer which is 0 if they are equal, < 0 if this is the smaller and > 0 if this is the larger. - - - - Gets the number of whole microseconds held in the instance. - An integer in the range [0, 999999]. - - - - - Gets the number of whole milliseconds held in the instance. - An integer in the range [0, 999]. - - - - - Gets the number of whole seconds held in the instance. - An interger in the range [0, 59]. - - - - - Gets the number of whole minutes held in the instance. - An integer in the range [0, 59]. - - - - - Gets the number of whole hours held in the instance. - Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a - value will normalised it to 00:00:00. - - - - - This class implements the Fastpath api. - - - - - This maps the functions names to their id's (possible unique just - to a connection). - - - - - Our connection. - - - - - The network stream. - - - - - Initialises the fastpath system. - - BaseConnection to attach to. - The network stream to the backend. - - - - Initialises the fastpath system. - - BaseConnection to attach to. - - - - Send a function call to the PostgreSQL backend. - - Function id. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - Send a function call to the PostgreSQL backend by name. - Note: the mapping for the procedure name to function id needs to exist, - usually to an earlier call to addfunction(). - This is the prefered method to call, as function id's can/may change - between versions of the backend. - For an example of how this works, refer to NpgsqlTypes.LargeObject - - Function name. - True if the result is an integer, false for other results. - FastpathArguments to pass to fastpath. - null if no data, Integer if an integer result, or byte[] otherwise. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Integer result. - - - - This convenience method assumes that the return value is an Integer. - - Function name. - Function arguments. - Array containing result - - - - This adds a function to our lookup table. - User code should use the addFunctions method, which is based upon a - query, rather than hard coding the oid. The oid for a function is not - guaranteed to remain static, even on different servers of the same - version. - - Function name. - Function id. - - - - This takes a ResultSet containing two columns. Column 1 contains the - function name, Column 2 the oid. - It reads the entire ResultSet, loading the values into the function - table. - REMEMBER to close() the resultset after calling this!! - Implementation note about function name lookups: - PostgreSQL stores the function id's and their corresponding names in - the pg_proc table. To speed things up locally, instead of querying each - function from that table when required, a Dictionary is used. Also, only - the function's required are entered into this table, keeping connection - times as fast as possible. - The org.postgresql.largeobject.LargeObject class performs a query upon it's startup, - and passes the returned ResultSet to the addFunctions() method here. - Once this has been done, the LargeObject api refers to the functions by - name. - Dont think that manually converting them to the oid's will work. Ok, - they will for now, but they can change during development (there was some - discussion about this for V7.0), so this is implemented to prevent any - unwarranted headaches in the future. - - ResultSet - - - - This returns the function id associated by its name - If addFunction() or addFunctions() have not been called for this name, - then an NpgsqlException is thrown. - - Function name to lookup. - Function ID for fastpath call. - - - - Fast Path Arg. - - - - - Type of argument, true=integer, false=byte[]. - - - - - Integer value if type=true. - - - - - Byte value if type=false; - - - - - Constructs an argument that consists of an integer value. - - Int value to set. - - - - Constructs an argument that consists of an array of bytes. - - Array to store. - - - - Constructs an argument that consists of part of a byte array. - - Source array. - offset within array. - length of data to include. - - - - Constructs an argument that consists of a String. - - String to store. - - - - This sends this argument down the network stream. - The stream sent consists of the length.int4 then the contents. - Note: This is called from Fastpath, and cannot be called from - client code. - - - - - - Report send size. - - Send size. - - - - Large Object. - - - - - Indicates a seek from the begining of a file. - - - - - Indicates a seek from the current position. - - - - - Indicates a seek from the end of a file. - - - - - This opens a large object. - If the object does not exist, then an NpgsqlException is thrown. - - FastPath API for the connection to use. - OID of the Large Object to open. - Mode of opening the large object - - - - OID getter. - - The OID of this LargeObject. - - - - This method closes the object. You must not call methods in this - object after this is called. - - - - - Reads some data from the object, and return as a byte[] array. - - Number of bytes to read. - Array containing data read. - - - - Reads some data from the object into an existing array. - - Destination array. - Offset within array. - Maximum number of bytes to read. - The number of bytes actually read. - - - - Writes an array to the object. - - Array to write. - - - - Writes some data from an array to the object. - - Destination array. - Offset within array. - Number of bytes to write. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object. - Either SEEK_SET, SEEK_CUR or SEEK_END. - - - - Sets the current position within the object. - This is similar to the fseek() call in the standard C library. It - allows you to have random access to the large object. - - Position within object from begining. - - - - Report the current position within the object. - - The current position within the object. - - - - This method is inefficient, as the only way to find out the size of - the object is to seek to the end, record the current position, then - return to the original position. - A better method will be found in the future. - - The size of the large object. - - - - OID. - - - - - Large Object Manager. - - - - - This mode indicates we want to write to an object - - - - - This mode indicates we want to read an object - - - - - This mode is the default. It indicates we want read and write access to - - - - - Constructs the LargeObject API. - There should only be one LargeObjectManager per Connection. The - org.postgresql.Connection class keeps track of the various extension API's - and it's advised you use those to gain access, and not going direct. - - - - - - This opens an existing large object, based on its OID. This method - assumes that READ and WRITE access is required (the default). - - OID of large object. - LargeObject instance providing access to the object - - - - This opens an existing large object, based on its OID. - - OID of large object. - Mode of open. - - - - - This creates a large object, returning its OID. - - OID of new object. - - - - This creates a large object, returning its OID. - - Bitmask describing different attributes of the new object. - OID of new object. - - - - This deletes a large object. - - OID describing object to delete. - - - - This deletes a large object. - It is identical to the Delete() method, and is supplied as the C API uses unlink. - - OID describing object to delete. - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - Clone the current object. - - A new NativeToBackendTypeConverterOptions object. - - - - Clone the current object with a different OID/Name mapping. - - OID/Name mapping object to use in the new instance. - A new NativeToBackendTypeConverterOptions object. - - - - Provide event handlers to convert all native supported basic data types from their backend - text representation to a .NET object. - - - - - Convert UTF8 encoded text a string. - - - - - Byte array from bytea encoded as ASCII text, escaped or hex format. - - - - - Byte array from bytea encoded as binary. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql bit to a System.Boolean. - - - - - Convert a postgresql datetime to a System.DateTime. - - - - - Convert a postgresql date to a System.DateTime. - - - - - Convert a postgresql time to a System.DateTime. - - - - - Convert a postgresql money to a System.Decimal. - - - - - Convert a postgresql float4 or float8 to a System.Float or System.Double respectively. - - - - - Provide event handlers to convert extended native supported data types from their backend - text representation to a .NET object. - - - - - Convert a postgresql point to a System.NpgsqlPoint. - - - - - Convert a postgresql point to a System.RectangleF. - - - - - LDeg. - - - - - Path. - - - - - Polygon. - - - - - Circle. - - - - - Inet. - - - - - MAC Address. - - - - - interval - - - - - Provide event handlers to convert the basic native supported data types from - native form to backend representation. - - - - - Convert a string to UTF8 encoded text, escaped and quoted as required. - - - - - Convert a string to UTF8 encoded text. - - - - - Binary data, escaped and quoted as required. - - - - - Binary data with possible older style octal escapes, quoted. - - - - - Binary data in the new hex format (>= 9.0), quoted. - - - - - Binary data, raw. - - - - - Convert to a postgresql boolean text format. - - - - - Convert to a postgresql boolean binary format. - - - - - Convert to a postgresql binary int2. - - - - - Convert to a postgresql binary int4. - - - - - Convert to a postgresql binary int8. - - - - - Convert to a postgresql bit. - - - - - Convert to a postgresql timestamp. - - - - - Convert to a postgresql date. - - - - - Convert to a postgresql time. - - - - - Convert to a postgres money. - - - - - Convert to a postgres double with maximum precision. - - - - - Convert a System.Float to a postgres float4. - - - - - Convert a System.Double to a postgres float8. - - - - - Provide event handlers to convert extended native supported data types from - native form to backend representation. - - - - - Point. - - - - - Box. - - - - - LSeg. - - - - - Open path. - - - - - Polygon. - - - - - Convert to a postgres MAC Address. - - - - - Circle. - - - - - Convert to a postgres inet. - - - - - Convert to a postgres interval - - - - - Delegate called to convert the given backend text data to its native representation. - - - - - Delegate called to convert the given backend binary data to its native representation. - - - - - Represents a backend data type. - This class can be called upon to convert a backend field representation to a native object. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - fieldValueSize - Type modifier field sent from the backend. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - TypeSize - Type modifier field sent from the backend. - - - - Type OID provided by the backend server. - - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - NpgsqlDbType. - - - - - Provider type to convert fields of this type to. - - - - - System type to convert fields of this type to. - - - - - Reports whether a backend binary to native decoder is available for this type. - - - - - Delegate called to convert the given native data to its backand representation. - - - - - Represents a backend data type. - This class can be called upon to convert a native object to its backend field representation, - - - - - Returns an NpgsqlNativeTypeInfo for an array where the elements are of the type - described by the NpgsqlNativeTypeInfo supplied. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type name provided by the backend server. - DbType - Quote - NpgsqlDbType - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended queries). - - - - Perform a data conversion from a native object to - a backend representation. - DBNull and null values are handled differently depending if a plain query is used - When - - Native .NET object to be converted. - Specifies that the value should be formatted for the extended query syntax. - Options to guide serialization. If null, a default options set is used. - Specifies that the value should be formatted as an extended query array element. - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - DbType. - - - - - Apply quoting. - - - - - Use parameter size information. - - - - - Reports whether a native to backend binary encoder is available for this type. - - - - - Provide mapping between type OID, type name, and a NpgsqlBackendTypeInfo object that represents it. - - - - - Construct an empty mapping. - - - - - Copy constuctor. - - - - - Add the given NpgsqlBackendTypeInfo to this mapping. - - - - - Add a new NpgsqlBackendTypeInfo with the given attributes and conversion handlers to this mapping. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - DbType - System type to convert fields of this type to. - Data conversion handler for text encoding. - Data conversion handler for binary data. - - - - Make a shallow copy of this type mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type OID exists in this mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type OID, or null if none found. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type name, or null if none found. - - - - - Provide mapping between type Type, NpgsqlDbType and a NpgsqlNativeTypeInfo object that represents it. - - - - - Add the given NpgsqlNativeTypeInfo to this mapping. - - - - - Add a new NpgsqlNativeTypeInfo with the given attributes and conversion handlers to this mapping. - - Type name provided by the backend server. - NpgsqlDbType - DbType - Quote - Data conversion handler for text backend encoding. - Data conversion handler for binary backend encoding (for extended query). - - - - Retrieve the NpgsqlNativeTypeInfo with the given NpgsqlDbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given DbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given Type. - - - - - Determine if a NpgsqlNativeTypeInfo with the given backend type name exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given NpgsqlDbType exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given Type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Represents a PostgreSQL Point type - - - - - Represents a PostgreSQL Line Segment type. - - - - - Represents a PostgreSQL Path type. - - - - - Represents a PostgreSQL Polygon type. - - - - - Represents a PostgreSQL Circle type. - - - - - Represents a PostgreSQL inet type. - - - - - Represents a PostgreSQL MacAddress type. - - - - - - - The macAddr parameter must contain a string that can only consist of numbers - and upper-case letters as hexadecimal digits. (See PhysicalAddress.Parse method on MSDN) - - - - This class contains helper methods for type conversion between - the .Net type system and postgresql. - - - - - A cache of basic datatype mappings keyed by server version. This way we don't - have to load the basic type mappings for every connection. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given DbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given System.Type. - - - - - This method is responsible to convert the byte[] received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - This method is responsible to convert the string received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - Create the one and only native to backend type map. - This map is used when formatting native data - types to backend representations. - - - - - This method creates (or retrieves from cache) a mapping between type and OID - of all natively supported postgresql data types. - This is needed as from one version to another, this mapping can be changed and - so we avoid hardcoding them. - - NpgsqlTypeMapping containing all known data types. The mapping must be - cloned before it is modified because it is cached; changes made by one connection may - effect another connection. - - - - - Attempt to map types by issuing a query against pg_type. - This function takes a list of NpgsqlTypeInfo and attempts to resolve the OID field - of each by querying pg_type. If the mapping is found, the type info object is - updated (OID) and added to the provided NpgsqlTypeMapping object. - - NpgsqlConnector to send query through. - Mapping object to add types too. - List of types that need to have OID's mapped. - - - - Summary description for NpgsqlQuery - - - - - For classes representing messages sent from the client to the server. - - - - - Set Cache Size. The default value is 20. - - - - - Lookup cached entity. null will returned if not match. - For both get{} and set{} apply LRU rule. - - key - - - - - The globally available text encoding used for frontend/backend communication. - - - - This class represents the base class for the state pattern design pattern - implementation. - - - This class represents the base class for the state pattern design pattern - implementation. - - - - - - This method is used by the states to change the state of the context. - - - - - Call ProcessBackendResponsesEnum(), and scan and discard all results. - - - - - This method is responsible to handle all protocol messages sent from the backend. - It holds all the logic to do it. - To exchange data, it uses a Mediator object from which it reads/writes information - to handle backend requests. - - - - - - Checks for context socket availability. - Socket.Poll supports integer as microseconds parameter. - This limits the usable command timeout value - to 2,147 seconds: (2,147 x 1,000,000 less than max_int). - In order to bypass this limit, the availability of - the socket is checked in 2,147 seconds cycles - - true, if for context socket availability was checked, false otherwise. - Context. - Select mode. - - - - Called from constructor of derived class. - - - - - Finalizer for HashAlgorithm - - - - - Computes the entire hash of all the bytes in the byte array. - - - - - When overridden in a derived class, drives the hashing function. - - - - - - - - When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created. - - - - - When overridden in a derived class, initializes the object to prepare for hashing. - - - - - Used for stream chaining. Computes hash as data passes through it. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - The buffer to write the copied data to. - At what point in the outputBuffer to write the data at. - - - - Used for stream chaining. Computes hash as data passes through it. Finishes off the hash. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - - - - Get whether or not the hash can transform multiple blocks at a time. - Note: MUST be overriden if descendant can transform multiple block - on a single call! - - - - - Gets the previously computed hash. - - - - - Returns the size in bits of the hash. - - - - - Must be overriden if not 1 - - - - - Must be overriden if not 1 - - - - - Common base class for all derived MD5 implementations. - - - - - Called from constructor of derived class. - - - - - Creates the default derived class. - - - - - C# implementation of the MD5 cryptographic hash function. - - - - - Creates a new MD5CryptoServiceProvider. - - - - - Drives the hashing function. - - Byte array containing the data to hash. - Where in the input buffer to start. - Size in bytes of the data in the buffer to hash. - - - - This finalizes the hash. Takes the data from the chaining variables and returns it. - - - - - Resets the class after use. Called automatically after hashing is done. - - - - - This is the meat of the hash function. It is what processes each block one at a time. - - Byte array to process data from. - Where in the byte array to start processing. - - - - Pads and then processes the final block. - - Buffer to grab data from. - Position in buffer in bytes to get data from. - How much data in bytes in the buffer to use. - - - - Implements for version 3 of the protocol. - - - - - Reads a row, field by field, allowing a DataRow to be built appropriately. - - - - - Marker interface which identifies a class which may take possession of a stream for the duration of - it's lifetime (possibly temporarily giving that possession to another class for part of that time. - - It inherits from IDisposable, since any such class must make sure it leaves the stream in a valid state. - - The most important such class is that compiler-generated from ProcessBackendResponsesEnum. Of course - we can't make that inherit from this interface, alas. - - - - - Marker interface which identifies a class which represents part of - a response from the server. - - - - - Reads part of a field, as needed (for - and - - - - - Adds further functionality to stream that is dependant upon the type of data read. - - - - - Completes the implementation of Streamer for char data. - - - - - Completes the implementation of Streamer for byte data. - - - - - This class represents a BackEndKeyData message received - from PostgreSQL - - - - - This class represents the Bind message sent to PostgreSQL - server. - - - - - - This class represents the CancelRequest message sent to PostgreSQL - server. - - - - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlCommand class. - - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query. - - The text of the query. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query and a NpgsqlConnection. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query, a NpgsqlConnection, and the NpgsqlTransaction. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - The NpgsqlTransaction in which the NpgsqlCommand executes. - - - - Used to execute internal commands. - - - - - Attempts to cancel the execution of a NpgsqlCommand. - - This Method isn't implemented yet. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Creates a new instance of an DbParameter object. - - An DbParameter object. - - - - Creates a new instance of a NpgsqlParameter object. - - A NpgsqlParameter object. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Internal query shortcut for use in cases where the number - of affected rows is of no interest. - - - - - Special adaptation of ExecuteBlind() that sets statement_timeout. - This exists to prevent Connector.SetBackendCommandTimeout() from calling Command.ExecuteBlind(), - which will cause an endless recursive loop. - - - Timeout in seconds. - - - - Executes a SQL statement against the connection and returns the number of rows affected. - - The number of rows affected if known; -1 otherwise. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader. - - A NpgsqlDataReader object. - - - - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. - - One of the CommandBehavior values. - A NpgsqlDataReader object. - Currently the CommandBehavior parameter is ignored. - - - - This method binds the parameters from parameters collection to the bind - message. - - - - - Executes the query, and returns the first column of the first row - in the result set returned by the query. Extra columns or rows are ignored. - - The first column of the first row in the result set, - or a null reference if the result set is empty. - - - - Creates a prepared version of the command on a PostgreSQL server. - - - - - This method checks the connection state to see if the connection - is set or it is open. If one of this conditions is not met, throws - an InvalidOperationException - - - - - This method substitutes the Parameters, if exist, in the command - to their actual values. - The parameter name format is :ParameterName. - - A version of CommandText with the Parameters inserted. - - - - Process this.commandText, trimming each distinct command and substituting paramater - tokens. - - - UTF8 encoded command ready to be sent to the backend. - - - - Append a region of a source command text to an output command, performing parameter token - substitutions. - - Stream to which to append output. - Command text. - - - false if the query has multiple statements which are not allowed - - - - Gets or sets the SQL statement or function (stored procedure) to execute at the data source. - - The Transact-SQL statement or stored procedure to execute. The default is an empty string. - - - - Gets or sets the wait time before terminating the attempt - to execute a command and generating an error. - - The time (in seconds) to wait for the command to execute. - The default is 20 seconds. - - - - Gets or sets a value indicating how the - CommandText property is to be interpreted. - - One of the CommandType values. The default is CommandType.Text. - - - - DB connection. - - - - - Gets or sets the NpgsqlConnection - used by this instance of the NpgsqlCommand. - - The connection to a data source. The default value is a null reference. - - - - DB parameter collection. - - - - - Gets the NpgsqlParameterCollection. - - The parameters of the SQL statement or function (stored procedure). The default is an empty collection. - - - - DB transaction. - - - - - Gets or sets the NpgsqlTransaction - within which the NpgsqlCommand executes. - - The NpgsqlTransaction. - The default value is a null reference. - - - - Gets or sets how command results are applied to the DataRow - when used by the Update - method of the DbDataAdapter. - - One of the UpdateRowSource values. - - - - Returns oid of inserted row. This is only updated when using executenonQuery and when command inserts just a single row. If table is created without oids, this will always be 0. - - - - - Returns whether this query will execute as a prepared (compiled) query. - - - - - Design time visible. - - - - - This class is responsible to create database commands for automatic insert, update and delete operations. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The adapter. - - - - - This method is reponsible to derive the command parameter list with values obtained from function definition. - It clears the Parameters collection of command. Also, if there is any parameter type which is not supported by Npgsql, an InvalidOperationException will be thrown. - Parameters name will be parameter1, parameter2, ... - - NpgsqlCommand whose function parameters will be obtained. - - - - Gets the automatically generated object required - to perform insertions at the data source. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated object required to perform insertions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform insertions. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform updates at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform updates. - - - - - Gets the automatically generated object required to perform updates - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform updates. - - - - - Gets the automatically generated System.Data.Common.DbCommand object required - to perform deletions at the data source. - - - The automatically generated System.Data.Common.DbCommand object required to perform deletions. - - - - - Gets the automatically generated object required to perform deletions - at the data source, optionally using columns for parameter names. - - - If true, generate parameter names matching column names, if possible. - If false, generate @p1, @p2, and so on. - - - The automatically generated object required to perform deletions. - - - - - Applies the parameter information. - - The parameter. - The row. - Type of the statement. - if set to true [where clause]. - - - - Returns the name of the specified parameter in the format of @p#. - - The number to be included as part of the parameter's name.. - - The name of the parameter with the specified number appended as part of the parameter name. - - - - - Returns the full parameter name, given the partial parameter name. - - The partial name of the parameter. - - The full parameter name corresponding to the partial parameter name requested. - - - - - Returns the placeholder for the parameter in the associated SQL statement. - - The number to be included as part of the parameter's name. - - The name of the parameter with the specified number appended. - - - - - Registers the to handle the event for a . - - The to be used for the update. - - - - Adds an event handler for the event. - - The sender - A instance containing information about the event. - - - - Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier, including properly escaping any embedded quotes in the identifier. - - The original unquoted identifier. - - The quoted version of the identifier. Embedded quotes within the identifier are properly escaped. - - - - - Unquoted identifier parameter cannot be null - - - - Given a quoted identifier, returns the correct unquoted form of that identifier, including properly un-escaping any embedded quotes in the identifier. - - The identifier that will have its embedded quotes removed. - - The unquoted identifier, with embedded quotes properly un-escaped. - - - - - Quoted identifier parameter cannot be null - - - - Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The beginning character or characters to use. The default is an empty string. - - - - - - - - Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. - - - The ending character or characters to use. The default is an empty string. - - - - - - - - Represents the method that handles the Notice events. - - The source of the event. - A NpgsqlNoticeEventArgs that contains the event data. - - - - Represents the method that handles the Notification events. - - The source of the event. - A NpgsqlNotificationEventArgs that contains the event data. - - - - This class represents a connection to a - PostgreSQL server. - - - - - Initializes a new instance of the - NpgsqlConnection class. - - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - An DbTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Begins a database transaction. - - A NpgsqlTransaction - object representing the new transaction. - - Currently there's no support for nested transactions. - - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - A NpgsqlTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Opens a database connection with the property settings specified by the - ConnectionString. - - - - - This method changes the current database by disconnecting from the actual - database and connecting to the specified. - - The name of the database to use in place of the current database. - - - - Releases the connection to the database. If the connection is pooled, it will be - made available for re-use. If it is non-pooled, the actual connection will be shutdown. - - - - - When a connection is closed within an enclosing TransactionScope and the transaction - hasn't been promoted, we defer the actual closing until the scope ends. - - - - - Creates and returns a DbCommand - object associated with the IDbConnection. - - A DbCommand object. - - - - Creates and returns a NpgsqlCommand - object associated with the NpgsqlConnection. - - A NpgsqlCommand object. - - - - Releases all resources used by the - NpgsqlConnection. - - true when called from Dispose(); - false when being called from the finalizer. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Returns a copy of the NpgsqlConnectionStringBuilder that contains the parsed connection string values. - - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - Write each key/value pair in the connection string to the log. - - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Sets the `settings` ConnectionStringBuilder based on the given `connectionString` - - The connection string to load the builder from - - - - Refresh the cached _connectionString whenever the builder settings change - - - - - Returns the supported collections - - - - - Returns the schema collection specified by the collection name. - - The collection name. - The collection specified. - - - - Returns the schema collection specified by the collection name filtered by the restrictions. - - The collection name. - - The restriction values to filter the results. A description of the restrictions is contained - in the Restrictions collection. - - The collection specified. - - - - Clear connection pool. - - - - - Clear all connection pools. - - - - - Enlist transation. - - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets or sets the string used to connect to a PostgreSQL database. - Valid values are: -
    -
  • - Server: Address/Name of Postgresql Server; -
  • -
  • - Port: Port to connect to; -
  • -
  • - Protocol: Protocol version to use, instead of automatic; Integer 2 or 3; -
  • -
  • - Database: Database name. Defaults to user name if not specified; -
  • -
  • - User Id: User name; -
  • -
  • - Password: Password for clear text authentication; -
  • -
  • - SSL: True or False. Controls whether to attempt a secure connection. Default = False; -
  • -
  • - Pooling: True or False. Controls whether connection pooling is used. Default = True; -
  • -
  • - MinPoolSize: Min size of connection pool; -
  • -
  • - MaxPoolSize: Max size of connection pool; -
  • -
  • - Timeout: Time to wait for connection open in seconds. Default is 15. -
  • -
  • - CommandTimeout: Time to wait for command to finish execution before throw an exception. In seconds. Default is 20. -
  • -
  • - Sslmode: Mode for ssl connection control. Can be Prefer, Require, Allow or Disable. Default is Disable. Check user manual for explanation of values. -
  • -
  • - ConnectionLifeTime: Time to wait before closing unused connections in the pool in seconds. Default is 15. -
  • -
  • - SyncNotification: Specifies if Npgsql should use synchronous notifications. -
  • -
  • - SearchPath: Changes search path to specified and public schemas. -
  • -
-
- The connection string that includes the server name, - the database name, and other parameters needed to establish - the initial connection. The default value is an empty string. - -
- - - Backend server host name. - - - - - Backend server port. - - - - - If true, the connection will attempt to use SSL. - - - - - Gets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets the name of the current database or the database to be used after a connection is opened. - - The name of the current database or the name of the database to be - used after a connection is opened. The default value is the empty string. - - - - Whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Gets the database server name. - - - - - Gets flag indicating if we are using Synchronous notification or not. - The default value is false. - - - - - Gets the current state of the connection. - - A bitwise combination of the ConnectionState values. The default is Closed. - - - - Gets whether the current state of the connection is Open or Closed - - ConnectionState.Open or ConnectionState.Closed - - - - Compatibility version. - - - - - Version of the PostgreSQL backend. - This can only be called when there is an active connection. - - - - - PostgreSQL server version. - - - - - Protocol version in use. - This can only be called when there is an active connection. - Always retuna Version3 - - - - - Process id of backend server. - This can only be called when there is an active connection. - - - - - Report whether the backend is expecting standard conformant strings. - In version 8.1, Postgres began reporting this value (false), but did not actually support standard conformant strings. - In version 8.2, Postgres began supporting standard conformant strings, but defaulted this flag to false. - As of version 9.1, this flag defaults to true. - - - - - Report whether the backend understands the string literal E prefix (>= 8.1). - - - - - Report whether the backend understands the hex byte format (>= 9.0). - - - - - The connector object connected to the backend. - - - - - Gets the NpgsqlConnectionStringBuilder containing the parsed connection string values. - - - - - User name. - - - - - Use extended types. - - - - - Password. - - - - - Determine if connection pooling will be used for this connection. - - - - - DB provider factory. - - - - - Return an exact copy of this NpgsqlConnectionString. - - - - - No integrated security if we're on mono and .NET 4.5 because of ClaimsIdentity, - see https://github.com/npgsql/Npgsql/issues/133 - - - - - This function will set value for known key, both private member and base[key]. - - - - - value, coerced as needed to the stored type. - - - - The function will modify private member only, not base[key]. - - - - value, coerced as needed to the stored type. - - - - The function will access private member only, not base[key]. - - - value. - - - - Clear the member and assign them to the default value. - - - - - Gets or sets the backend server host name. - - - - - Gets or sets the backend server port. - - - - - Gets or sets the name of the database to be used after a connection is opened. - - The name of the database to be - used after a connection is opened. - - - - Gets or sets the login user name. - - - - - Gets or sets the login password as a UTF8 encoded byte array. - - - - - Sets the login password as a string. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets a value indicating whether to attempt to use SSL. - - - - - Gets or sets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets or sets the schema search path. - - - - - Gets or sets a value indicating whether connection pooling should be used. - - - - - Gets or sets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets or sets the minimum connection pool size. - - - - - Gets or sets the maximum connection pool size. - - - - - Gets or sets a value indicating whether to listen for notifications and report them between command activity. - - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets or sets a value indicating whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Compatibilty version. When possible, behaviour caused by breaking changes will be preserved - if this version is less than that where the breaking change was introduced. - - - - - Gets or sets the ootional application name parameter to be sent to the backend during connection initiation. - - - - - Gets or sets a value indicating whether to silently Prepare() all commands before execution. - - - - - Gets or sets the specified backend communication protocol version. - - - - - Gets the backend encoding. Always returns "UTF8". - - - - - Case insensative accessor for indivual connection string values. - - - - - Set both ImplicitDefault and ExplicitDefault to the 's default value. - - - - - - - - Set ImplicitDefault to the default value of 's type, - and ExplicitDefault to . - - - - - - - - Represents the method that allows the application to provide a certificate collection to be used for SSL clien authentication - - A X509CertificateCollection to be filled with one or more client certificates. - - - - Represents the method that is called to validate the certificate provided by the server during an SSL handshake - - The server's certificate - The certificate chain containing the certificate's CA and any intermediate authorities - Any errors that were detected - - - - !!! Helper class, for compilation only. - Connector implements the logic for the Connection Objects to - access the physical connection to the database, and isolate - the application developer from connection pooling internals. - - - - - Constructor. - - Connection string. - Pooled - Controls whether the connector can be shared. - - - - This method checks if the connector is still ok. - We try to send a simple query text, select 1 as ConnectionTest; - - - - - This method is responsible for releasing all resources associated with this Connector. - - - - - This method is responsible to release all portals used by this Connector. - - - - - Modify the backend statement_timeout value if needed. - - New timeout - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Default SSL ValidateRemoteCertificateCallback implementation. - - - - - This method is required to set all the version dependent features flags. - SupportsPrepare means the server can use prepared query plans (7.3+) - - - - - Opens the physical connection to the server. - - Usually called by the RequestConnector - Method of the connection pool manager. - - - - Closes the physical connection to the server. - - - - - Returns next portal index. - - - - - Returns next plan index. - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Called to validate server's certificate during SSL handshake - - - - - Gets the current state of the connection. - - - - - Return Connection String. - - - - - Version of backend server this connector is connected to. - - - - - The physical connection socket to the backend. - - - - - The physical connection stream to the backend. - - - - - The top level stream to the backend. - - - - - Reports if this connector is fully connected. - - - - - The connection mediator. - - - - - Report if the connection is in a transaction. - - - - - Options that control certain aspects of native to backend conversions that depend - on backend version and status. - - - - - This class manages all connector objects, pooled AND non-pooled. - - - - Unique static instance of the connector pool - mamager. - - - Map of index to unused pooled connectors, avaliable to the - next RequestConnector() call. - This hashmap will be indexed by connection string. - This key will hold a list of queues of pooled connectors available to be used. - - - Timer for tracking unused connections in pools. - - - - Searches the shared and pooled connector lists for a - matching connector object or creates a new one. - - The NpgsqlConnection that is requesting - the connector. Its ConnectionString will be used to search the - pool for available connectors. - A connector object. - - - - Find a pooled connector. Handle shared/non-shared here. - - - - - Releases a connector, possibly back to the pool for future use. - - - Pooled connectors will be put back into the pool if there is room. - Shared connectors should just have their use count decremented - since they always stay in the shared pool. - - Connection to which the connector is leased. - The connector to release. - - - - Release a pooled connector. Handle shared/non-shared here. - - - - - Find an available pooled connector in the non-shared pool, or create - a new one if none found. - - - - - Put a pooled connector into the pool queue. - - Connection is leased to. - Connector to pool - - - - A queue with an extra Int32 for keeping track of busy connections. - - - - - Connections available to the end user - - - - - Connections currently in use - - - - - Represents information about COPY operation data transfer format as returned by server. - - - - - Only created when a CopyInResponse or CopyOutResponse is received by NpgsqlState.ProcessBackendResponses() - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Represents a PostgreSQL COPY FROM STDIN operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to read data from (if provided by user) - or for writing it (when generated by driver). - Eg. new NpgsqlCopyIn("COPY mytable FROM STDIN", connection, streamToRead).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is run upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is executed upon Start() and all data from fromStream is passed to it as copy data. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, it will be flushed to server as copy data, and operation will be finished immediately. - Otherwise the CopyStream member can be used for writing copy data to server and operation finished with a call to End() or Cancel(). - - - - - Called after writing all data to CopyStream to successfully complete this copy operation. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Will do nothing if current operation is not active. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start(). - User may provide a stream to constructor; it is used to pass to server all data read from it. - Otherwise, call to Start() sets this to a writable NpgsqlCopyInStream that passes all data written to it to server. - In latter case this is only available while the copy operation is active and null otherwise. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields expected on each input row if this operation is currently active, otherwise -1 - - - - - The Command used to execute this copy operation. - - - - - Set before a COPY IN query to define size of internal buffer for reading from given CopyStream. - - - - - Represents an ongoing COPY FROM STDIN operation. - Provides methods to push data to server and end or cancel the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyInResponse. - If CopyStream is already set, it is used to read data to push to server, after which the copy is completed. - Otherwise CopyStream is set to a writable NpgsqlCopyInStream that calls SendCopyData each time it is written to. - - - - - Sends given packet to server as a CopyData message. - Does not check for notifications! Use another thread for that. - - - - - Sends CopyDone message to server. Handles responses, ie. may throw an exception. - - - - - Sends CopyFail message to server. Handles responses, ie. should always throw an exception: - in CopyIn state the server responds to CopyFail with an error response; - outside of a CopyIn state the server responds to CopyFail with an error response; - without network connection or whatever, there's going to eventually be a failure, timeout or user intervention. - - - - - Copy format information returned from server. - - - - - Stream for writing data to a table on a PostgreSQL version 7.4 or newer database during an active COPY FROM STDIN operation. - Passes data exactly as is and when given, so see to it that you use server encoding, correct format and reasonably sized writes! - - - - - Created only by NpgsqlCopyInState.StartCopy() - - - - - Successfully completes copying data to server. Returns after operation is finished. - Does nothing if this stream is not the active copy operation writer. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Does nothing if this stream is not the active copy operation writer. - - - - - Writes given bytes to server. - Fails if this stream is not the active copy operation writer. - - - - - Flushes stream contents to server. - Fails if this stream is not the active copy operation writer. - - - - - Not readable - - - - - Not seekable - - - - - Not supported - - - - - True while this stream can be used to write copy data to server - - - - - False - - - - - True - - - - - False - - - - - Number of bytes written so far - - - - - Number of bytes written so far; not settable - - - - - Represents a PostgreSQL COPY TO STDOUT operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to write results to (if provided by user) - or for reading the results (when generated by driver). - Eg. new NpgsqlCopyOut("COPY (SELECT * FROM mytable) TO STDOUT", connection, streamToWrite).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is run upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is executed upon Start() and all requested copy data is written to toStream immediately. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, all copy data from server will be written to it, and operation will be finished immediately. - Otherwise the CopyStream member can be used for reading copy data from server until no more data is available. - - - - - Flush generated CopyStream at once. Effectively reads and discard all the rest of copy data from server. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start() - - - - - The Command used to execute this copy operation. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Faster alternative to using the generated CopyStream. - - - - - Represents an ongoing COPY TO STDOUT operation. - Provides methods to read data from server or end the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyOutResponse. - If CopyStream is already set, it is used to write data received from server, after which the copy ends. - Otherwise CopyStream is set to a readable NpgsqlCopyOutStream that receives data from server. - - - - - Called from NpgsqlOutStream.Read to read copy data from server. - - - - - Copy format information returned from server. - - - - - Stream for reading data from a table or select on a PostgreSQL version 7.4 or newer database during an active COPY TO STDOUT operation. - Passes data exactly as provided by the server. - - - - - Created only by NpgsqlCopyOutState.StartCopy() - - - - - Discards copy data as long as server pushes it. Returns after operation is finished. - Does nothing if this stream is not the active copy operation reader. - - - - - Not writable. - - - - - Not flushable. - - - - - Copies data read from server to given byte buffer. - Since server returns data row by row, length will differ each time, but it is only zero once the operation ends. - Can be mixed with calls to the more efficient NpgsqlCopyOutStream.Read() : byte[] though that would not make much sense. - - - - - Not seekable - - - - - Not supported - - - - - Returns a whole row of data from server without extra work. - If standard Stream.Read(...) has been called before, it's internal buffers remains are returned. - - - - - True while this stream can be used to read copy data from server - - - - - True - - - - - False - - - - - False - - - - - Number of bytes read so far - - - - - Number of bytes read so far; can not be set. - - - - - Writes given objects into a stream for PostgreSQL COPY in default copy format (not CSV or BINARY). - - - - - Default delimiter. - - - - - Default separator. - - - - - Default null. - - - - - Default escape. - - - - - Default quote. - - - - - Default buffer size. - - - - - Constructor. - - - - - - Flush buffers. - - - - - Flush rows. - - - - - Flush fields. - - - - - Close the serializer. - - - - - Escape sequence for the given character. - - - - - - - Make room for bytes. - - - - - - Add bytes. - - - - - - End row. - - - - - Prefix field. - - - - - Field added. - - - - - Add null. - - - - - Add string. - - - - - - add Int32. - - - - - - Add Int64. - - - - - - Add number. - - - - - - Add bool - - - - - - Add DateTime. - - - - - - Report whether the serializer is active. - - - - - To Stream. - - - - - Delimiter. - - - - - Separator. - - - - - Escape. - - - - - Null. - - - - - Buffer size. - - - - - Report whether space remains in the buffer. - - - - - Strings to escape. - - - - - Escape sequence bytes. - - - - - Represents the method that handles the RowUpdated events. - - The source of the event. - A NpgsqlRowUpdatedEventArgs that contains the event data. - - - - Represents the method that handles the RowUpdating events. - - The source of the event. - A NpgsqlRowUpdatingEventArgs that contains the event data. - - - - This class represents an adapter from many commands: select, update, insert and delete to fill Datasets. - - - - - Default constructor. - - - - - Constructor. - - - - - - Constructor. - - - - - - - Constructor. - - - - - - - Create row updated event. - - - - - - - - - - Create row updating event. - - - - - - - - - - Raise the RowUpdated event. - - - - - - Raise the RowUpdating event. - - - - - - Row updated event. - - - - - Row updating event. - - - - - Delete command. - - - - - Select command. - - - - - Update command. - - - - - Insert command. - - - - - Provides a means of reading a forward-only stream of rows from a PostgreSQL backend. This class cannot be inherited. - - - - - Return the data type name of the column at index . - - - - - Return the data type of the column at index . - - - - - Return the Npgsql specific data type of the column at requested ordinal. - - column position - Appropriate Npgsql type for column. - - - - Return the column name of the column at index . - - - - - Return the data type OID of the column at index . - - FIXME: Why this method returns String? - - - - Has ordinal. - - - - - - - Return the column name of the column named . - - - - - Return the data DbType of the column at index . - - - - - Return the data NpgsqlDbType of the column at index . - - - - - Get specified field value. - /// - - - - - - Get the value of a column as a . - If the differences between and - in handling of days and months is not important to your application, use - instead. - - Index of the field to find. - value of the field. - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Get specified field value. - /// - - - - - - Send closed event. - - - - - Gets the value of a column converted to a Guid. - - - - - Gets the value of a column as Int16. - - - - - Gets the value of a column as Int32. - - - - - Gets the value of a column as Int64. - - - - - Gets the value of a column as Single. - - - - - Gets the value of a column as Double. - - - - - Gets the value of a column as String. - - - - - Gets the value of a column as Decimal. - - - - - Gets the value of a column as TimeSpan. - - - - - Copy values from each column in the current row into . - - Destination for column values. - The number of column values copied. - - - - Copy values from each column in the current row into . - - An array appropriately sized to store values from all columns. - The number of column values copied. - - - - Gets the value of a column as Boolean. - - - - - Gets the value of a column as Byte. - - - - - Gets the value of a column as Char. - - - - - Gets the value of a column as DateTime. - - - - - Returns a System.Data.DataTable that describes the column metadata of the DataReader. - - - - - This methods parses the command text and tries to get the tablename - from it. - - - - - Get enumerator. - - - - - - Is raised whenever Close() is called. - - - - - Gets the number of columns in the current row. - - - - - Gets the value of a column in its native format. - - - - - Gets the value of a column in its native format. - - - - - Gets a value indicating the depth of nesting for the current row. Always returns zero. - - - - - Gets a value indicating whether the data reader is closed. - - - - - Contains the column names as the keys - - - - - Contains all unique columns - - - - - This is the primary implementation of NpgsqlDataReader. It is the one used in normal cases (where the - preload-reader option is not set in the connection string to resolve some potential backwards-compatibility - issues), the only implementation used internally, and in cases where CachingDataReader is used, it is still - used to do the actual "leg-work" of turning a response stream from the server into a datareader-style - object - with CachingDataReader then filling it's cache from here. - - - - - Iterate through the objects returned through from the server. - If it's a CompletedResponse the rowsaffected count is updated appropriately, - and we iterate again, otherwise we return it (perhaps updating our cache of pending - rows if appropriate). - - The next we will deal with. - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Closes the data reader object. - - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Advances the data reader to the next row. - - True if the reader was advanced, otherwise false. - - - - Return the value of the column at index . - - - - - Gets raw data from a column. - - - - - Gets raw data from a column. - - - - - Report whether the value in a column is DBNull. - - - - - Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. - - - - - Indicates if NpgsqlDatareader has rows to be read. - - - - - Provides an implementation of NpgsqlDataReader in which all data is pre-loaded into memory. - This operates by first creating a ForwardsOnlyDataReader as usual, and then loading all of it's - Rows into memory. There is a general principle that when there is a trade-off between a class design that - is more efficient and/or scalable on the one hand and one that is less efficient but has more functionality - (in this case the internal-only functionality of caching results) that one can build the less efficent class - from the most efficient without significant extra loss in efficiency, but not the other way around. The relationship - between ForwardsOnlyDataReader and CachingDataReader is an example of this). - Since the interface presented to the user is still forwards-only, queues are used to - store this information, so that dequeueing as we go we give the garbage collector the best opportunity - possible to reclaim any memory that is no longer in use. - ForwardsOnlyDataReader being used to actually - obtain the information from the server means that the "leg-work" is still only done (and need only be - maintained) in one place. - This class exists to allow for certain potential backwards-compatibility issues to be resolved - with little effort on the part of affected users. It is considerably less efficient than ForwardsOnlyDataReader - and hence never used internally. - - - - - This is the base class for NpgsqlDescribeStatement and NpgsqlDescribePortal. - - - - - - This class represents the Statement Describe message sent to PostgreSQL - server. - - - - - - This class represents the Portal Describe message sent to PostgreSQL - server. - - - - - - EventArgs class to send Notice parameters, which are just NpgsqlError's in a lighter context. - - - - - Notice information. - - - - - This class represents the ErrorResponse and NoticeResponse - message sent from PostgreSQL server. - - - - - Return a string representation of this error object. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Terse error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Internal query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Backend protocol version in use. - - - - - Error and notice message field codes - - - - - Severity: the field contents are ERROR, FATAL, or PANIC (in an error message), - or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a localized - translation of one of these. Always present. - - - - - Code: the SQLSTATE code for the error (see Appendix A). Not localizable. Always present. - - - - - Message: the primary human-readable error message. This should be accurate - but terse (typically one line). Always present. - - - - - Detail: an optional secondary error message carrying more detail about the problem. - Might run to multiple lines. - - - - - Hint: an optional suggestion what to do about the problem. This is intended to differ - from Detail in that it offers advice (potentially inappropriate) rather than hard facts. - Might run to multiple lines. - - - - - Position: the field value is a decimal ASCII integer, indicating an error cursor - position as an index into the original query string. The first character has index 1, - and positions are measured in characters not bytes. - - - - - Internal position: this is defined the same as the P field, but it is used when the - cursor position refers to an internally generated command rather than the one submitted - by the client. - The q field will always appear when this field appears. - - - - - Internal query: the text of a failed internally-generated command. - This could be, for example, a SQL query issued by a PL/pgSQL function. - - - - - Where: an indication of the context in which the error occurred. - Presently this includes a call stack traceback of active procedural language functions - and internally-generated queries. The trace is one entry per line, most recent first. - - - - - Schema name: if the error was associated with a specific database object, - the name of the schema containing that object, if any. - - - - - Table name: if the error was associated with a specific table, the name of the table. - (Refer to the schema name field for the name of the table's schema.) - - - - - Column name: if the error was associated with a specific table column, the name of the column. - (Refer to the schema and table name fields to identify the table.) - - - - - Data type name: if the error was associated with a specific data type, the name of the data type. - (Refer to the schema name field for the name of the data type's schema.) - - - - - Constraint name: if the error was associated with a specific constraint, the name of the constraint. - Refer to fields listed above for the associated table or domain. - (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.) - - - - - File: the file name of the source-code location where the error was reported. - - - - - Line: the line number of the source-code location where the error was reported. - - - - - Routine: the name of the source-code routine reporting the error. - - - - - The level of verbosity of the NpgsqlEventLog - - - - - Don't log at all - - - - - Only log the most common issues - - - - - Log everything - - - - - This class handles all the Npgsql event and debug logging - - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - - This method is obsolete and should no longer be used. - It is likely to be removed in future versions of Npgsql - - The message to write to the event log - The minimum LogLevel for which this message should be logged. - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - The ResourceManager to get the localized resources - The name of the resource that should be fetched by the ResourceManager - The minimum LogLevel for which this message should be logged. - The additional parameters that shall be included into the log-message (must be compatible with the string in the resource): - - - - Writes the default log-message for the action of calling the Get-part of an Indexer to the log file. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - - - - Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - The value the Indexer is set to - - - - Writes the default log-message for the action of calling the Get-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - - - - Writes the default log-message for the action of calling the Set-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - The value the Property is set to - - - - Writes the default log-message for the action of calling a Method without Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - - - - Writes the default log-message for the action of calling a Method with one Argument to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the Argument of the Method - - - - Writes the default log-message for the action of calling a Method with two Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - - - - Writes the default log-message for the action of calling a Method with three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - The value of the third Argument of the Method - - - - Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - A Object-Array with zero or more Ojects that are Arguments of the Method. - - - - Sets/Returns the filename to use for logging. - - The filename of the current Log file. - - - - Sets/Returns whether Log messages should be echoed to the console - - true if Log messages are echoed to the console, otherwise false - - - - The exception that is thrown when the PostgreSQL backend reports errors. - - - - - Construct a backend error exception based on a list of one or more - backend errors. The basic Exception.Message will be built from the - first (usually the only) error in the list. - - - - - Get object data. - - - - - - - Format a .NET style exception string. - Include all errors in the list, including any hints. - - - - - Append a line to the given Stream, first checking for zero-length. - - - - - Provide access to the entire list of errors provided by the PostgreSQL backend. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Basic error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Schema name which relates to the error. PostgreSQL 9.3 and up. - - - - - Table name which relates to the error. PostgreSQL 9.3 and up. - - - - - Column name which relates to the error. PostgreSQL 9.3 and up. - - - - - Data type of column which relates to the error. PostgreSQL 9.3 and up. - - - - - Constraint name which relates to the error. PostgreSQL 9.3 and up. - - - - - String containing the sql sent which produced this error. - - - - - Returns the entire list of errors provided by the PostgreSQL backend. - - - - - This class represents the Execute message sent to PostgreSQL - server. - - - - - - A factory to create instances of various Npgsql objects. - - - - - Creates an NpgsqlCommand object. - - - - - This class represents the Flush message sent to PostgreSQL - server. - - - - - - For classes representing simple messages, - consisting only of a message code and length identifier, - sent from the client to the server. - - - - - This class is responsible for serving as bridge between the backend - protocol handling and the core classes. It is used as the mediator for - exchanging data generated/sent from/to backend. - - - - - - The current command timeout on the backend. This is set via "SET statement_timeout = (milliseconds)". - A value of -1 means the backend's timeout value is unknown because it has not yet been set. - - - - - EventArgs class to send Notification parameters. - - - - - Process ID of the PostgreSQL backend that sent this notification. - - - - - Condition that triggered that notification. - - - - - Additional Information From Notifiying Process (for future use, currently postgres always sets this to an empty string) - - - - - This class represents a parameter to a command that will be sent to server - - - - - Initializes a new instance of the NpgsqlParameter class. - - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and a value of the new NpgsqlParameter. - - The m_Name of the parameter to map. - An Object that is the value of the NpgsqlParameter. - -

When you specify an Object - in the value parameter, the DbType is - inferred from the .NET Framework type of the Object.

-

When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. - This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. - Use Convert.ToInt32(value) for example to have compiler calling the correct constructor.

-
-
- - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and the data type. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the NpgsqlDbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Initializes a new instance of the NpgsqlParameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Reset DBType. - - - - - Creates a new NpgsqlParameter that - is a copy of the current instance. - - A new NpgsqlParameter that is a copy of this instance. - - - - The collection to which this parameter belongs, if any. - - - - - Gets or sets the maximum number of digits used to represent the - Value property. - - The maximum number of digits used to represent the - Value property. - The default value is 0, which indicates that the data provider - sets the precision for Value. - - - - Whether to use an explicit cast when included in a query. - - - - - Gets or sets the number of decimal places to which - Value is resolved. - - The number of decimal places to which - Value is resolved. The default is 0. - - - - Gets or sets the maximum size, in bytes, of the data within the column. - - The maximum size, in bytes, of the data within the column. - The default value is inferred from the parameter value. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets a value indicating whether the parameter is input-only, - output-only, bidirectional, or a stored procedure return value parameter. - - One of the ParameterDirection - values. The default is Input. - - - - Gets or sets a value indicating whether the parameter accepts null values. - - true if null values are accepted; otherwise, false. The default is false. - - - - Gets or sets the m_Name of the NpgsqlParameter. - - The m_Name of the NpgsqlParameter. - The default is an empty string. - - - - The m_Name scrubbed of any optional marker - - - - - Gets or sets the m_Name of the source column that is mapped to the - DataSet and used for loading or - returning the Value. - - The m_Name of the source column that is mapped to the - DataSet. The default is an empty string. - - - - Gets or sets the DataRowVersion - to use when loading Value. - - One of the DataRowVersion values. - The default is Current. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Source column mapping. - - - - - Represents a collection of parameters relevant to a NpgsqlCommand - as well as their respective mappings to columns in a DataSet. - This class cannot be inherited. - - - - - Initializes a new instance of the NpgsqlParameterCollection class. - - - - - Invalidate the hash lookup tables. This should be done any time a change - may throw the lookups out of sync with the list. - - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The index of the new NpgsqlParameter object. - - - - Obsolete. Use AddWithValue instead. - - - Use caution when using this overload of the - Add method to specify integer parameter values. - Because this overload takes a value of type Object, - you must convert the integral value to an Object - type when the value is zero, as the following C# example demonstrates. - parameters.Add(":pname", Convert.ToInt32(0)); - If you do not perform this conversion, the compiler will assume you - are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload. - - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. - - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - One of the NpgsqlDbType values. - The length of the column. - The name of the source column. - The paramater that was added. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the parameter name and the data type. - - The name of the parameter. - One of the DbType values. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, and the column length. - - The name of the parameter. - One of the DbType values. - The length of the column. - The index of the new NpgsqlParameter object. - - - - Adds a NpgsqlParameter to the NpgsqlParameterCollection with the parameter name, the data type, the column length, and the source column name. - - The name of the parameter. - One of the DbType values. - The length of the column. - The name of the source column. - The index of the new NpgsqlParameter object. - - - - Removes the specified NpgsqlParameter from the collection using the parameter name. - - The name of the NpgsqlParameter object to retrieve. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - true if the collection contains the parameter; otherwise, false. - - - - Gets the location of the NpgsqlParameter in the collection with a specific parameter name. - - The name of the NpgsqlParameter object to find. - The zero-based location of the NpgsqlParameter in the collection. - - - - Removes the specified NpgsqlParameter from the collection using a specific index. - - The zero-based index of the parameter. - - - - Inserts a NpgsqlParameter into the collection at the specified index. - - The zero-based index where the parameter is to be inserted within the collection. - The NpgsqlParameter to add to the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The name of the NpgsqlParameter to remove from the collection. - - - - Removes the specified NpgsqlParameter from the collection. - - The NpgsqlParameter to remove from the collection. - - - - Gets a value indicating whether a NpgsqlParameter exists in the collection. - - The value of the NpgsqlParameter object to find. - true if the collection contains the NpgsqlParameter object; otherwise, false. - - - - Gets a value indicating whether a NpgsqlParameter with the specified parameter name exists in the collection. - - The name of the NpgsqlParameter object to find. - A reference to the requested parameter is returned in this out param if it is found in the list. This value is null if the parameter is not found. - true if the collection contains the parameter and param will contain the parameter; otherwise, false. - - - - Removes all items from the collection. - - - - - Gets the location of a NpgsqlParameter in the collection. - - The value of the NpgsqlParameter object to find. - The zero-based index of the NpgsqlParameter object in the collection. - - - - Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. - - The NpgsqlParameter to add to the collection. - The zero-based index of the new NpgsqlParameter object. - - - - Copies NpgsqlParameter objects from the NpgsqlParameterCollection to the specified array. - - An Array to which to copy the NpgsqlParameter objects in the collection. - The starting index of the array. - - - - Returns an enumerator that can iterate through the collection. - - An IEnumerator that can be used to iterate through the collection. - - - - Add an Array of parameters to the collection. - - Parameters to add. - - - - Get parameter. - - - - - - - Get parameter. - - - - - - - Set parameter. - - - - - - - Set parameter. - - - - - - - In methods taking an object as argument this method is used to verify - that the argument has the type NpgsqlParameter - - The object to verify - - - - Report the offset within the collection of the given parameter. - - Parameter to find. - Index of the parameter, or -1 if the parameter is not present. - - - - Insert the specified parameter into the collection. - - Index of the existing parameter before which to insert the new one. - Parameter to insert. - - - - Report whether the specified parameter is present in the collection. - - Parameter to find. - True if the parameter was found, otherwise false. - - - - Remove the specified parameter from the collection. - - Parameter to remove. - True if the parameter was found and removed, otherwise false. - - - - Convert collection to a System.Array. - - Destination array. - Starting index in destination array. - - - - Convert collection to a System.Array. - - NpgsqlParameter[] - - - - Gets the NpgsqlParameter with the specified name. - - The name of the NpgsqlParameter to retrieve. - The NpgsqlParameter with the specified name, or a null reference if the parameter is not found. - - - - Gets the NpgsqlParameter at the specified index. - - The zero-based index of the NpgsqlParameter to retrieve. - The NpgsqlParameter at the specified index. - - - - Report whether the collection is read only. Always false. - - - - - Report whether the collection is fixed size. Always false. - - - - - Report whether the collection is synchronized. - - - - - Gets the number of NpgsqlParameter objects in the collection. - - The number of NpgsqlParameter objects in the collection. - - - - Sync root. - - - - - This class represents the ParameterStatus message sent from PostgreSQL - server. - - - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - This class represents a PasswordPacket message sent to backend - PostgreSQL. - - - - - Used when a connection is closed - - - - - This is the abstract base class for NpgsqlAsciiRow and NpgsqlBinaryRow. - - - - - The index of the current field in the stream, i.e. the one that hasn't - been read yet - - - - - This class represents a RowDescription message sent from - the PostgreSQL. - - - - - - This struct represents the internal data of the RowDescription message. - - - - - Provides the underlying mechanism for reading schema information. - - - - - Returns the MetaDataCollections that lists all possible collections. - - The MetaDataCollections - - - - Returns the Restrictions that contains the meaning and position of the values in the restrictions array. - - The Restrictions - - - - Returns the Databases that contains a list of all accessable databases. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Databases - - - - Returns the Tables that contains table and view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Tables - - - - Returns the Columns that contains information about columns in tables. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Columns. - - - - Returns the Views that contains view names and the database and schema they come from. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Views - - - - Returns the Users containing user names and the sysid of those users. - - The database connection on which to run the metadataquery. - The restrictions to filter the collection. - The Users. - - - - This class represents a StartupPacket message of PostgreSQL - protocol. - - - - - - Represents a completed response message. - - - - - This class represents the Sync message sent to PostgreSQL - server. - - - - - - Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited. - - - - - Dispose. - - - - - - Commits the database transaction. - - - - - Rolls back a transaction from a pending state. - - - - - Rolls back a transaction from a pending savepoint state. - - - - - Creates a transaction save point. - - - - - Cancel the transaction without telling the backend about it. This is - used to make the transaction go away when closing a connection. - - - - - Gets the NpgsqlConnection - object associated with the transaction, or a null reference if the - transaction is no longer valid. - - The NpgsqlConnection - object associated with the transaction. - - - - DB connection. - - - - - Specifies the IsolationLevel for this transaction. - - The IsolationLevel for this transaction. - The default is ReadCommitted. - - - - This class provides many util methods to handle - reading and writing of PostgreSQL protocol messages. - - - - - This method takes a ProtocolVersion and returns an integer - version number that the Postgres backend will recognize in a - startup packet. - - - - - This method takes a version string as returned by SELECT VERSION() and returns - a valid version string ("7.2.2" for example). - This is only needed when running protocol version 2. - This does not do any validity checks. - - - - - This method gets a C NULL terminated string from the network stream. - It keeps reading a byte in each time until a NULL byte is returned. - It returns the resultant string of bytes read. - This string is sent from backend. - - - - - Reads requested number of bytes from stream with retries until Stream.Read returns 0 or count is reached. - - Stream to read - byte buffer to fill - starting position to fill the buffer - number of bytes to read - The number of bytes read. May be less than count if no more bytes are available. - - - - Reads requested number of bytes from . If output matches exactly, and == false, is returned directly. - - Source array. - Starting position to read from - Number of bytes to read - Force a copy, even if the output is an exact copy of . - byte[] containing data requested. - - - - This method writes a string to the network stream. - - - - - This method writes a string to the network stream. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a byte to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a C NULL terminated string limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - This method writes a C NULL terminated byte[] limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - Write a 32-bit integer to the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given array in the correct byte order. - - - - - Write a 16-bit integer to the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given array in the correct byte order. - - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Copy and possibly reverse a byte array, depending on host architecture endienness. - - Source byte array. - Starting offset in source array. - Number of bytes to copy. - Force a copy even if no swap is performed. - , reversed if on a little-endian architecture, copied if required. - - - - Represent the frontend/backend protocol version. - - - - - Represent the backend server version. - As this class offers no functionality beyond that offered by it has been - deprecated in favour of that class. - - - - - - Returns the string representation of this version in three place dot notation (Major.Minor.Patch). - - - - - Server version major number. - - - - - Server version minor number. - - - - - Server version patch level number. - - - - - A class to handle everything associated with SSPI authentication - - - - - Simplified SecBufferDesc struct with only one SecBuffer - - -
-
diff --git a/src/packages/Npgsql.2.2.3/lib/net45/de/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net45/de/Npgsql.resources.dll deleted file mode 100644 index 15b259ecd..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/de/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/es/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net45/es/Npgsql.resources.dll deleted file mode 100644 index 851d5a16e..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/es/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/fi/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net45/fi/Npgsql.resources.dll deleted file mode 100644 index a70fc30c7..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/fi/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/fr/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net45/fr/Npgsql.resources.dll deleted file mode 100644 index 21ff7941e..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/fr/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/ja/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net45/ja/Npgsql.resources.dll deleted file mode 100644 index db5efcd11..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/ja/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/Npgsql.2.2.3/lib/net45/zh-CN/Npgsql.resources.dll b/src/packages/Npgsql.2.2.3/lib/net45/zh-CN/Npgsql.resources.dll deleted file mode 100644 index a7986990a..000000000 Binary files a/src/packages/Npgsql.2.2.3/lib/net45/zh-CN/Npgsql.resources.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/content/net20/x64/SQLite.Interop.dll b/src/packages/System.Data.SQLite.1.0.88.0/content/net20/x64/SQLite.Interop.dll deleted file mode 100644 index 9835396e8..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/content/net20/x64/SQLite.Interop.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/content/net20/x86/SQLite.Interop.dll b/src/packages/System.Data.SQLite.1.0.88.0/content/net20/x86/SQLite.Interop.dll deleted file mode 100644 index a761d867c..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/content/net20/x86/SQLite.Interop.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/content/net40/x64/SQLite.Interop.dll b/src/packages/System.Data.SQLite.1.0.88.0/content/net40/x64/SQLite.Interop.dll deleted file mode 100644 index 8dad2ac22..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/content/net40/x64/SQLite.Interop.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/content/net40/x86/SQLite.Interop.dll b/src/packages/System.Data.SQLite.1.0.88.0/content/net40/x86/SQLite.Interop.dll deleted file mode 100644 index 37627fdef..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/content/net40/x86/SQLite.Interop.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/content/net45/x64/SQLite.Interop.dll b/src/packages/System.Data.SQLite.1.0.88.0/content/net45/x64/SQLite.Interop.dll deleted file mode 100644 index 9b2b7561a..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/content/net45/x64/SQLite.Interop.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/content/net45/x86/SQLite.Interop.dll b/src/packages/System.Data.SQLite.1.0.88.0/content/net45/x86/SQLite.Interop.dll deleted file mode 100644 index be66ce85e..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/content/net45/x86/SQLite.Interop.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/lib/net20/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.1.0.88.0/lib/net20/System.Data.SQLite.Linq.dll deleted file mode 100644 index 75383af81..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/lib/net20/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/lib/net20/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.1.0.88.0/lib/net20/System.Data.SQLite.dll deleted file mode 100644 index c5974f5fb..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/lib/net20/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/lib/net40/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.1.0.88.0/lib/net40/System.Data.SQLite.Linq.dll deleted file mode 100644 index 8077d765b..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/lib/net40/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/lib/net40/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.1.0.88.0/lib/net40/System.Data.SQLite.dll deleted file mode 100644 index b8665d7a8..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/lib/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/lib/net45/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.1.0.88.0/lib/net45/System.Data.SQLite.Linq.dll deleted file mode 100644 index 3d1095e74..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/lib/net45/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/lib/net45/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.1.0.88.0/lib/net45/System.Data.SQLite.dll deleted file mode 100644 index 6561f5a82..000000000 Binary files a/src/packages/System.Data.SQLite.1.0.88.0/lib/net45/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.1.0.88.0/tools/install.ps1 b/src/packages/System.Data.SQLite.1.0.88.0/tools/install.ps1 deleted file mode 100644 index a4293924a..000000000 --- a/src/packages/System.Data.SQLite.1.0.88.0/tools/install.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################### -# -# install.ps1 -- -# -# Written by Joe Mistachkin. -# Released to the public domain, use at your own risk! -# -############################################################################### - -param($installPath, $toolsPath, $package, $project) - -$platformNames = "x86", "x64" -$fileName = "SQLite.Interop.dll" -$propertyName = "CopyToOutputDirectory" - -foreach($platformName in $platformNames) { - $folder = $project.ProjectItems.Item($platformName) - - if ($folder -eq $null) { - continue - } - - $item = $folder.ProjectItems.Item($fileName) - - if ($item -eq $null) { - continue - } - - $property = $item.Properties.Item($propertyName) - - if ($property -eq $null) { - continue - } - - $property.Value = 1 -} diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net20/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net20/System.Data.SQLite.dll deleted file mode 100644 index 00463085f..000000000 Binary files a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net20/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net20/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net20/System.Data.SQLite.xml deleted file mode 100644 index 73ad8b01c..000000000 --- a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net20/System.Data.SQLite.xml +++ /dev/null @@ -1,13534 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The fallback default database type when one cannot be obtained from an - existing connection instance. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The fallback default database type name when one cannot be obtained from - an existing connection instance. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws an exception - upon failure. - - - The object value to convert. - - - The format provider to use. - - - If non-zero, a string value will be converted using the - - method; otherwise, the - method will be used. - - - The converted boolean value. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the default database type name to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default database type name to use. - - - - - If applicable, issues a trace log message warning about falling back to - the default database type name. - - - The database value type. - - - The flags associated with the parent connection object. - - - The textual name of the database type. - - - - - If applicable, issues a trace log message warning about falling back to - the default database value type. - - - The textual name of the database type. - - - The flags associated with the parent connection object. - - - The database value type. - - - - - For a given database value type, return the "closest-match" textual database type name. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - Determines if a database type is considered to be a string. - - - The database type to check. - - - Non-zero if the database type is considered to be a string, zero - otherwise. - - - - - Determines and returns the runtime configuration setting string that - should be used in place of the specified object value. - - - The object value to convert to a string. - - - Either the string to use in place of the object value -OR- null if it - cannot be determined. - - - - - Determines the default value to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default value to use. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be an - value. - - - The textual value to inspect. - - - Non-zero if the text looks like an value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The object instance configured with - the chosen format. - - - The textual value to inspect. - - - Non-zero if the text looks like a in the - configured format, zero otherwise. - - - - - For a given textual database type name, return the "closest-match" database type. - This method is called during query result processing; therefore, its performance - is critical. - - The connection context for custom type mappings, if any. - The textual name of the database type to match. - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - - - - - - Creates temporary tables on the connection so schema information can be queried. - - - The connection upon which to build the schema tables. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When the property is used, it - should return non-zero if there were ever any rows in the associated - result sets. - - - - - Enable "strict" transaction enlistment semantics. Setting this flag - will cause an exception to be thrown if an attempt is made to enlist - in a transaction with an unavailable or unsupported isolation level. - In the future, more extensive checks may be enabled by this flag as - well. - - - - - Enable mapping of unsupported transaction isolation levels to the - closest supported transaction isolation level. - - - - - When returning column values, attempt to detect the affinity of - textual values by checking if they fully conform to those of the - , - , - , - or types. - - - - - When returning column values, attempt to detect the type of - string values by checking if they fully conform to those of - the , - , - , - or types. - - - - - Skip querying runtime configuration settings for use by the - class, including the default - value and default database type name. - NOTE: If the - and/or - properties are not set explicitly nor set via their connection - string properties and repeated calls to determine these runtime - configuration settings are seen to be a problem, this flag - should be set. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - The default extra flags for new connections with all logging enabled. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The "invalid value" for the enumeration used - by the property. This constant is shared - by this class and the SQLiteConnectionStringBuilder class. - - - - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - The extra connection flags to be used for all opened connections. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - The cached values for all settings that have been fetched on behalf - of this connection. This cache may be cleared by calling the - method. - - - - - The default databse type for this connection. This value will only - be used if the - flag is set. - - - - - The default databse type name for this connection. This value will only - be used if the - flag is set. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection cached settings. - - - The total number of per-connection settings cleared. - - - - - Queries and returns the value of the specified setting, using the - cached setting names and values for this connection, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the cached setting is stored here if found; otherwise, - the value of is stored here. - - - Non-zero if the cached setting was found; otherwise, zero. - - - - - Adds or sets the cached setting specified by - to the value specified by . - - - The name of the cached setting to add or replace. - - - The new value of the cached setting. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Determines the transaction isolation level that should be used by - the caller, primarily based upon the one specified by the caller. - If mapping of transaction isolation levels is enabled, the returned - transaction isolation level may be significantly different than the - originally specified one. - - - The originally specified transaction isolation level. - - - The transaction isolation level that should be used. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Sets the chunk size for the primary file associated with this database - connection. - - - The new chunk size for the main database, in bytes. - - - Zero for success, non-zero for error. - - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Gets/sets the default database type for this connection. This value - will only be used when not null. - - - - - Gets/sets the default database type name for this connection. This - value will only be used when not null. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - The extra connection flags to be used for all opened connections. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - Gets/sets the default database type for the connection. - - - - - Gets/sets the default type name for the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - If enabled, skip using the configured shared connection flags. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - A command is being disposed. - - - - - A data reader is being disposed. - - - - - A data reader is being closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - Constructs a default instance of this type. - - - - - Constructs an instance of this type with the specified field values. - - - The type affinity to use for the new instance. - - - The database type to use for the new instance. - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - The flags pertaining to the associated connection (via the command). - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - The number of calls to Step() that have returned true (i.e. the number of rows that - have been read in the current result set). - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - Forces the connection flags cached by this data reader to be refreshed - from the underlying connection. - - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - Retrieves the SQLiteType for a given column and row value. - - - The original SQLiteType structure, based only on the column. - - - The textual value of the column for a given row. - - - The SQLiteType structure. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The flags associated with the parent connection object. - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of rows seen so far in the current result set. - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net40/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net40/System.Data.SQLite.dll deleted file mode 100644 index 3ac522be4..000000000 Binary files a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net40/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net40/System.Data.SQLite.xml deleted file mode 100644 index 2fec3951a..000000000 --- a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net40/System.Data.SQLite.xml +++ /dev/null @@ -1,13534 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The fallback default database type when one cannot be obtained from an - existing connection instance. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The fallback default database type name when one cannot be obtained from - an existing connection instance. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws an exception - upon failure. - - - The object value to convert. - - - The format provider to use. - - - If non-zero, a string value will be converted using the - - method; otherwise, the - method will be used. - - - The converted boolean value. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the default database type name to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default database type name to use. - - - - - If applicable, issues a trace log message warning about falling back to - the default database type name. - - - The database value type. - - - The flags associated with the parent connection object. - - - The textual name of the database type. - - - - - If applicable, issues a trace log message warning about falling back to - the default database value type. - - - The textual name of the database type. - - - The flags associated with the parent connection object. - - - The database value type. - - - - - For a given database value type, return the "closest-match" textual database type name. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - Determines if a database type is considered to be a string. - - - The database type to check. - - - Non-zero if the database type is considered to be a string, zero - otherwise. - - - - - Determines and returns the runtime configuration setting string that - should be used in place of the specified object value. - - - The object value to convert to a string. - - - Either the string to use in place of the object value -OR- null if it - cannot be determined. - - - - - Determines the default value to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default value to use. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be an - value. - - - The textual value to inspect. - - - Non-zero if the text looks like an value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The object instance configured with - the chosen format. - - - The textual value to inspect. - - - Non-zero if the text looks like a in the - configured format, zero otherwise. - - - - - For a given textual database type name, return the "closest-match" database type. - This method is called during query result processing; therefore, its performance - is critical. - - The connection context for custom type mappings, if any. - The textual name of the database type to match. - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - - - - - - Creates temporary tables on the connection so schema information can be queried. - - - The connection upon which to build the schema tables. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When the property is used, it - should return non-zero if there were ever any rows in the associated - result sets. - - - - - Enable "strict" transaction enlistment semantics. Setting this flag - will cause an exception to be thrown if an attempt is made to enlist - in a transaction with an unavailable or unsupported isolation level. - In the future, more extensive checks may be enabled by this flag as - well. - - - - - Enable mapping of unsupported transaction isolation levels to the - closest supported transaction isolation level. - - - - - When returning column values, attempt to detect the affinity of - textual values by checking if they fully conform to those of the - , - , - , - or types. - - - - - When returning column values, attempt to detect the type of - string values by checking if they fully conform to those of - the , - , - , - or types. - - - - - Skip querying runtime configuration settings for use by the - class, including the default - value and default database type name. - NOTE: If the - and/or - properties are not set explicitly nor set via their connection - string properties and repeated calls to determine these runtime - configuration settings are seen to be a problem, this flag - should be set. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - The default extra flags for new connections with all logging enabled. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The "invalid value" for the enumeration used - by the property. This constant is shared - by this class and the SQLiteConnectionStringBuilder class. - - - - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - The extra connection flags to be used for all opened connections. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - The cached values for all settings that have been fetched on behalf - of this connection. This cache may be cleared by calling the - method. - - - - - The default databse type for this connection. This value will only - be used if the - flag is set. - - - - - The default databse type name for this connection. This value will only - be used if the - flag is set. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection cached settings. - - - The total number of per-connection settings cleared. - - - - - Queries and returns the value of the specified setting, using the - cached setting names and values for this connection, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the cached setting is stored here if found; otherwise, - the value of is stored here. - - - Non-zero if the cached setting was found; otherwise, zero. - - - - - Adds or sets the cached setting specified by - to the value specified by . - - - The name of the cached setting to add or replace. - - - The new value of the cached setting. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Determines the transaction isolation level that should be used by - the caller, primarily based upon the one specified by the caller. - If mapping of transaction isolation levels is enabled, the returned - transaction isolation level may be significantly different than the - originally specified one. - - - The originally specified transaction isolation level. - - - The transaction isolation level that should be used. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Sets the chunk size for the primary file associated with this database - connection. - - - The new chunk size for the main database, in bytes. - - - Zero for success, non-zero for error. - - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Gets/sets the default database type for this connection. This value - will only be used when not null. - - - - - Gets/sets the default database type name for this connection. This - value will only be used when not null. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - The extra connection flags to be used for all opened connections. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - Gets/sets the default database type for the connection. - - - - - Gets/sets the default type name for the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - If enabled, skip using the configured shared connection flags. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - A command is being disposed. - - - - - A data reader is being disposed. - - - - - A data reader is being closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - Constructs a default instance of this type. - - - - - Constructs an instance of this type with the specified field values. - - - The type affinity to use for the new instance. - - - The database type to use for the new instance. - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - The flags pertaining to the associated connection (via the command). - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - The number of calls to Step() that have returned true (i.e. the number of rows that - have been read in the current result set). - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - Forces the connection flags cached by this data reader to be refreshed - from the underlying connection. - - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - Retrieves the SQLiteType for a given column and row value. - - - The original SQLiteType structure, based only on the column. - - - The textual value of the column for a given row. - - - The SQLiteType structure. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The flags associated with the parent connection object. - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of rows seen so far in the current result set. - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net45/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net45/System.Data.SQLite.dll deleted file mode 100644 index f27d25751..000000000 Binary files a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net45/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net45/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net45/System.Data.SQLite.xml deleted file mode 100644 index 2fec3951a..000000000 --- a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net45/System.Data.SQLite.xml +++ /dev/null @@ -1,13534 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The fallback default database type when one cannot be obtained from an - existing connection instance. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The fallback default database type name when one cannot be obtained from - an existing connection instance. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws an exception - upon failure. - - - The object value to convert. - - - The format provider to use. - - - If non-zero, a string value will be converted using the - - method; otherwise, the - method will be used. - - - The converted boolean value. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the default database type name to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default database type name to use. - - - - - If applicable, issues a trace log message warning about falling back to - the default database type name. - - - The database value type. - - - The flags associated with the parent connection object. - - - The textual name of the database type. - - - - - If applicable, issues a trace log message warning about falling back to - the default database value type. - - - The textual name of the database type. - - - The flags associated with the parent connection object. - - - The database value type. - - - - - For a given database value type, return the "closest-match" textual database type name. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - Determines if a database type is considered to be a string. - - - The database type to check. - - - Non-zero if the database type is considered to be a string, zero - otherwise. - - - - - Determines and returns the runtime configuration setting string that - should be used in place of the specified object value. - - - The object value to convert to a string. - - - Either the string to use in place of the object value -OR- null if it - cannot be determined. - - - - - Determines the default value to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default value to use. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be an - value. - - - The textual value to inspect. - - - Non-zero if the text looks like an value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The object instance configured with - the chosen format. - - - The textual value to inspect. - - - Non-zero if the text looks like a in the - configured format, zero otherwise. - - - - - For a given textual database type name, return the "closest-match" database type. - This method is called during query result processing; therefore, its performance - is critical. - - The connection context for custom type mappings, if any. - The textual name of the database type to match. - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - - - - - - Creates temporary tables on the connection so schema information can be queried. - - - The connection upon which to build the schema tables. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When the property is used, it - should return non-zero if there were ever any rows in the associated - result sets. - - - - - Enable "strict" transaction enlistment semantics. Setting this flag - will cause an exception to be thrown if an attempt is made to enlist - in a transaction with an unavailable or unsupported isolation level. - In the future, more extensive checks may be enabled by this flag as - well. - - - - - Enable mapping of unsupported transaction isolation levels to the - closest supported transaction isolation level. - - - - - When returning column values, attempt to detect the affinity of - textual values by checking if they fully conform to those of the - , - , - , - or types. - - - - - When returning column values, attempt to detect the type of - string values by checking if they fully conform to those of - the , - , - , - or types. - - - - - Skip querying runtime configuration settings for use by the - class, including the default - value and default database type name. - NOTE: If the - and/or - properties are not set explicitly nor set via their connection - string properties and repeated calls to determine these runtime - configuration settings are seen to be a problem, this flag - should be set. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - The default extra flags for new connections with all logging enabled. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The "invalid value" for the enumeration used - by the property. This constant is shared - by this class and the SQLiteConnectionStringBuilder class. - - - - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - The extra connection flags to be used for all opened connections. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - The cached values for all settings that have been fetched on behalf - of this connection. This cache may be cleared by calling the - method. - - - - - The default databse type for this connection. This value will only - be used if the - flag is set. - - - - - The default databse type name for this connection. This value will only - be used if the - flag is set. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection cached settings. - - - The total number of per-connection settings cleared. - - - - - Queries and returns the value of the specified setting, using the - cached setting names and values for this connection, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the cached setting is stored here if found; otherwise, - the value of is stored here. - - - Non-zero if the cached setting was found; otherwise, zero. - - - - - Adds or sets the cached setting specified by - to the value specified by . - - - The name of the cached setting to add or replace. - - - The new value of the cached setting. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Determines the transaction isolation level that should be used by - the caller, primarily based upon the one specified by the caller. - If mapping of transaction isolation levels is enabled, the returned - transaction isolation level may be significantly different than the - originally specified one. - - - The originally specified transaction isolation level. - - - The transaction isolation level that should be used. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Sets the chunk size for the primary file associated with this database - connection. - - - The new chunk size for the main database, in bytes. - - - Zero for success, non-zero for error. - - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Gets/sets the default database type for this connection. This value - will only be used when not null. - - - - - Gets/sets the default database type name for this connection. This - value will only be used when not null. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - The extra connection flags to be used for all opened connections. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - Gets/sets the default database type for the connection. - - - - - Gets/sets the default type name for the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - If enabled, skip using the configured shared connection flags. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - A command is being disposed. - - - - - A data reader is being disposed. - - - - - A data reader is being closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - Constructs a default instance of this type. - - - - - Constructs an instance of this type with the specified field values. - - - The type affinity to use for the new instance. - - - The database type to use for the new instance. - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - The flags pertaining to the associated connection (via the command). - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - The number of calls to Step() that have returned true (i.e. the number of rows that - have been read in the current result set). - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - Forces the connection flags cached by this data reader to be refreshed - from the underlying connection. - - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - Retrieves the SQLiteType for a given column and row value. - - - The original SQLiteType structure, based only on the column. - - - The textual value of the column for a given row. - - - The SQLiteType structure. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The flags associated with the parent connection object. - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of rows seen so far in the current result set. - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net451/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net451/System.Data.SQLite.dll deleted file mode 100644 index c6fa054cf..000000000 Binary files a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net451/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net451/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net451/System.Data.SQLite.xml deleted file mode 100644 index 2fec3951a..000000000 --- a/src/packages/System.Data.SQLite.Core.1.0.94.0/lib/net451/System.Data.SQLite.xml +++ /dev/null @@ -1,13534 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The fallback default database type when one cannot be obtained from an - existing connection instance. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The fallback default database type name when one cannot be obtained from - an existing connection instance. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws an exception - upon failure. - - - The object value to convert. - - - The format provider to use. - - - If non-zero, a string value will be converted using the - - method; otherwise, the - method will be used. - - - The converted boolean value. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the default database type name to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default database type name to use. - - - - - If applicable, issues a trace log message warning about falling back to - the default database type name. - - - The database value type. - - - The flags associated with the parent connection object. - - - The textual name of the database type. - - - - - If applicable, issues a trace log message warning about falling back to - the default database value type. - - - The textual name of the database type. - - - The flags associated with the parent connection object. - - - The database value type. - - - - - For a given database value type, return the "closest-match" textual database type name. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - Determines if a database type is considered to be a string. - - - The database type to check. - - - Non-zero if the database type is considered to be a string, zero - otherwise. - - - - - Determines and returns the runtime configuration setting string that - should be used in place of the specified object value. - - - The object value to convert to a string. - - - Either the string to use in place of the object value -OR- null if it - cannot be determined. - - - - - Determines the default value to be used when a - per-connection value is not available. - - - The connection context for type mappings, if any. - - - The default value to use. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be an - value. - - - The textual value to inspect. - - - Non-zero if the text looks like an value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The textual value to inspect. - - - Non-zero if the text looks like a value, - zero otherwise. - - - - - Determines if the specified textual value appears to be a - value. - - - The object instance configured with - the chosen format. - - - The textual value to inspect. - - - Non-zero if the text looks like a in the - configured format, zero otherwise. - - - - - For a given textual database type name, return the "closest-match" database type. - This method is called during query result processing; therefore, its performance - is critical. - - The connection context for custom type mappings, if any. - The textual name of the database type to match. - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - - - - - - Creates temporary tables on the connection so schema information can be queried. - - - The connection upon which to build the schema tables. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When the property is used, it - should return non-zero if there were ever any rows in the associated - result sets. - - - - - Enable "strict" transaction enlistment semantics. Setting this flag - will cause an exception to be thrown if an attempt is made to enlist - in a transaction with an unavailable or unsupported isolation level. - In the future, more extensive checks may be enabled by this flag as - well. - - - - - Enable mapping of unsupported transaction isolation levels to the - closest supported transaction isolation level. - - - - - When returning column values, attempt to detect the affinity of - textual values by checking if they fully conform to those of the - , - , - , - or types. - - - - - When returning column values, attempt to detect the type of - string values by checking if they fully conform to those of - the , - , - , - or types. - - - - - Skip querying runtime configuration settings for use by the - class, including the default - value and default database type name. - NOTE: If the - and/or - properties are not set explicitly nor set via their connection - string properties and repeated calls to determine these runtime - configuration settings are seen to be a problem, this flag - should be set. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - The default extra flags for new connections with all logging enabled. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The "invalid value" for the enumeration used - by the property. This constant is shared - by this class and the SQLiteConnectionStringBuilder class. - - - - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - The extra connection flags to be used for all opened connections. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - The cached values for all settings that have been fetched on behalf - of this connection. This cache may be cleared by calling the - method. - - - - - The default databse type for this connection. This value will only - be used if the - flag is set. - - - - - The default databse type name for this connection. This value will only - be used if the - flag is set. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection cached settings. - - - The total number of per-connection settings cleared. - - - - - Queries and returns the value of the specified setting, using the - cached setting names and values for this connection, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the cached setting is stored here if found; otherwise, - the value of is stored here. - - - Non-zero if the cached setting was found; otherwise, zero. - - - - - Adds or sets the cached setting specified by - to the value specified by . - - - The name of the cached setting to add or replace. - - - The new value of the cached setting. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Determines the transaction isolation level that should be used by - the caller, primarily based upon the one specified by the caller. - If mapping of transaction isolation levels is enabled, the returned - transaction isolation level may be significantly different than the - originally specified one. - - - The originally specified transaction isolation level. - - - The transaction isolation level that should be used. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Sets the chunk size for the primary file associated with this database - connection. - - - The new chunk size for the main database, in bytes. - - - Zero for success, non-zero for error. - - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Gets/sets the default database type for this connection. This value - will only be used when not null. - - - - - Gets/sets the default database type name for this connection. This - value will only be used when not null. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - The extra connection flags to be used for all opened connections. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - Gets/sets the default database type for the connection. - - - - - Gets/sets the default type name for the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - If enabled, skip using the configured shared connection flags. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - A command is being disposed. - - - - - A data reader is being disposed. - - - - - A data reader is being closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - Constructs a default instance of this type. - - - - - Constructs an instance of this type with the specified field values. - - - The type affinity to use for the new instance. - - - The database type to use for the new instance. - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - The flags pertaining to the associated connection (via the command). - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - The number of calls to Step() that have returned true (i.e. the number of rows that - have been read in the current result set). - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - Forces the connection flags cached by this data reader to be refreshed - from the underlying connection. - - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - Retrieves the SQLiteType for a given column and row value. - - - The original SQLiteType structure, based only on the column. - - - The textual value of the column for a given row. - - - The SQLiteType structure. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The flags associated with the parent connection object. - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of rows seen so far in the current result set. - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net20/app.config.transform b/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net20/app.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net20/app.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net20/web.config.transform b/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net20/web.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net20/web.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net40/app.config.transform b/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net40/app.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net40/app.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net40/web.config.transform b/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net40/web.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/content/net40/web.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.Linq.dll deleted file mode 100644 index d1bca6b2b..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.dll deleted file mode 100644 index 6df043044..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net20/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.EF6.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.EF6.dll deleted file mode 100644 index 7175502fb..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.EF6.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.Linq.dll deleted file mode 100644 index ba9e07a01..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.dll deleted file mode 100644 index bbdb3cde9..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net40/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.EF6.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.EF6.dll deleted file mode 100644 index aefc53cb1..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.EF6.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.Linq.dll deleted file mode 100644 index dc297778a..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.dll deleted file mode 100644 index 8fd5aa928..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net45/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.EF6.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.EF6.dll deleted file mode 100644 index fdb73ea6f..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.EF6.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.Linq.dll deleted file mode 100644 index fa0a7ceae..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.dll deleted file mode 100644 index 177555558..000000000 Binary files a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x64.1.0.91.0/lib/net451/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net20/app.config.transform b/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net20/app.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net20/app.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net20/web.config.transform b/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net20/web.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net20/web.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net40/app.config.transform b/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net40/app.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net40/app.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net40/web.config.transform b/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net40/web.config.transform deleted file mode 100644 index 36f2788da..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/content/net40/web.config.transform +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.Linq.dll deleted file mode 100644 index d1bca6b2b..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.dll deleted file mode 100644 index d0baab06c..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net20/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.EF6.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.EF6.dll deleted file mode 100644 index 7175502fb..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.EF6.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.Linq.dll deleted file mode 100644 index ba9e07a01..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.dll deleted file mode 100644 index 91140f0d1..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net40/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.EF6.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.EF6.dll deleted file mode 100644 index aefc53cb1..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.EF6.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.Linq.dll deleted file mode 100644 index dc297778a..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.dll deleted file mode 100644 index 14e3c14c4..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net45/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.EF6.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.EF6.dll deleted file mode 100644 index fdb73ea6f..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.EF6.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.Linq.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.Linq.dll deleted file mode 100644 index fa0a7ceae..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.Linq.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.dll b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.dll deleted file mode 100644 index c6ed8d82f..000000000 Binary files a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.dll and /dev/null differ diff --git a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.xml b/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.xml deleted file mode 100644 index 6df7eb75d..000000000 --- a/src/packages/System.Data.SQLite.x86.1.0.91.0/lib/net451/System.Data.SQLite.xml +++ /dev/null @@ -1,13100 +0,0 @@ - - - - System.Data.SQLite - - - - - Defines a source code identifier custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code identifier value. - - - The source code identifier value to use. - - - - - Gets the source code identifier value. - - - - - Defines a source code time-stamp custom attribute for an assembly - manifest. - - - - - Constructs an instance of this attribute class using the specified - source code time-stamp value. - - - The source code time-stamp value to use. - - - - - Gets the source code time-stamp value. - - - - - This is the method signature for the SQLite core library logging callback - function for use with sqlite3_log() and the SQLITE_CONFIG_LOG. - - WARNING: This delegate is used more-or-less directly by native code, do - not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET - - - - - This internal class provides the foundation of SQLite support. It defines all the abstract members needed to implement - a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite. - - - - - This base class provides datatype conversion services for the SQLite provider. - - - - - The format string for DateTime values when using the InvariantCulture or CurrentCulture formats. - - - - - The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC). - - - - - The value of the OLE Automation epoch represented as a Julian day. - - - - - An array of ISO-8601 DateTime formats that we support parsing. - - - - - The internal default format for UTC DateTime values when converting - to a string. - - - - - The internal default format for local DateTime values when converting - to a string. - - - - - An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 - - - - - The default DateTime format for this instance. - - - - - The default DateTimeKind for this instance. - - - - - The default DateTime format string for this instance. - - - - - Initializes the conversion class - - The default date/time format to use for this instance - The DateTimeKind to use. - The DateTime format string to use. - - - - Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. - - The string to convert to UTF-8 - A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. - - - - Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. - - - This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the - string result. - - The DateTime to convert. - The UTF-8 encoded string, including a 0 terminating byte at the end of the array. - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a UTF-8 encoded IntPtr of the specified length into a .NET string - - The pointer to the memory where the UTF-8 string is encoded - The number of bytes to decode - A string containing the translated character(s) - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - A DateTime value - - - - Converts a string into a DateTime, using the specified DateTimeFormat, - DateTimeKind and DateTimeFormatString. - - - Acceptable ISO8601 DateTime formats are: - - THHmmssK - THHmmK - HH:mm:ss.FFFFFFFK - HH:mm:ssK - HH:mmK - yyyy-MM-dd HH:mm:ss.FFFFFFFK - yyyy-MM-dd HH:mm:ssK - yyyy-MM-dd HH:mmK - yyyy-MM-ddTHH:mm:ss.FFFFFFFK - yyyy-MM-ddTHH:mmK - yyyy-MM-ddTHH:mm:ssK - yyyyMMddHHmmssK - yyyyMMddHHmmK - yyyyMMddTHHmmssFFFFFFFK - THHmmss - THHmm - HH:mm:ss.FFFFFFF - HH:mm:ss - HH:mm - yyyy-MM-dd HH:mm:ss.FFFFFFF - yyyy-MM-dd HH:mm:ss - yyyy-MM-dd HH:mm - yyyy-MM-ddTHH:mm:ss.FFFFFFF - yyyy-MM-ddTHH:mm - yyyy-MM-ddTHH:mm:ss - yyyyMMddHHmmss - yyyyMMddHHmm - yyyyMMddTHHmmssFFFFFFF - yyyy-MM-dd - yyyyMMdd - yy-MM-dd - - If the string cannot be matched to one of the above formats -OR- - the DateTimeFormatString if one was provided, an exception will - be thrown. - - The string containing either a long integer number of 100-nanosecond units since - System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a - culture-independent formatted date and time string, a formatted date and time string in the current - culture, or an ISO8601-format string. - The SQLiteDateFormats to use. - The DateTimeKind to use. - The DateTime format string to use. - A DateTime value - - - - Converts a julianday value into a DateTime - - The value to convert - A .NET DateTime - - - - Converts a julianday value into a DateTime - - The value to convert - The DateTimeKind to use. - A .NET DateTime - - - - Converts the specified number of seconds from the Unix epoch into a - value. - - - The number of whole seconds since the Unix epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts the specified number of ticks since the epoch into a - value. - - - The number of whole ticks since the epoch. - - - Either Utc or Local time. - - - The new value. - - - - - Converts a DateTime struct to a JulianDay double - - The DateTime to convert - The JulianDay value the Datetime represents - - - - Converts a DateTime struct to the whole number of seconds since the - Unix epoch. - - The DateTime to convert - The whole number of seconds since the Unix epoch - - - - Returns the DateTime format string to use for the specified DateTimeKind. - If is not null, it will be returned verbatim. - - The DateTimeKind to use. - The DateTime format string to use. - - The DateTime format string to use for the specified DateTimeKind. - - - - - Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind, - and DateTimeFormatString specified for the connection when it was opened. - - The DateTime value to convert - Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a - Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time - string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. - - - - Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. - - - This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls - ToDateTime() on the string to return a DateTime. - - A pointer to the UTF-8 encoded string - The length in bytes of the string - The parsed DateTime value - - - - Smart method of splitting a string. Skips quoted elements, removes the quotes. - - - This split function works somewhat like the String.Split() function in that it breaks apart a string into - pieces and returns the pieces as an array. The primary differences are: - - Only one character can be provided as a separator character - Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. - - Thus, if splitting the following string looking for a comma:
- One,Two, "Three, Four", Five
-
- The resulting array would contain
- [0] One
- [1] Two
- [2] Three, Four
- [3] Five
-
- Note that the leading and trailing spaces were removed from each item during the split. -
- Source string to split apart - Separator character - A string array of the split up elements -
- - - Splits the specified string into multiple strings based on a separator - and returns the result as an array of strings. - - - The string to split into pieces based on the separator character. If - this string is null, null will always be returned. If this string is - empty, an array of zero strings will always be returned. - - - The character used to divide the original string into sub-strings. - This character cannot be a backslash or a double-quote; otherwise, no - work will be performed and null will be returned. - - - If this parameter is non-zero, all double-quote characters will be - retained in the returned list of strings; otherwise, they will be - dropped. - - - Upon failure, this parameter will be modified to contain an appropriate - error message. - - - The new array of strings or null if the input string is null -OR- the - separator character is a backslash or a double-quote -OR- the string - contains an unbalanced backslash or double-quote character. - - - - - Queries and returns the string representation for an object, using the - specified (or current) format provider. - - - The object instance to return the string representation for. - - - The format provider to use -OR- null if the current format provider for - the thread should be used instead. - - - The string representation for the object instance -OR- null if the - object instance is also null. - - - - - Convert a value to true or false. - - A string or number representing true or false - - - - - Convert a string to true or false. - - A string representing true or false - - - "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be - converted to a proper boolean value. - - - - - Converts a SQLiteType to a .NET Type object - - The SQLiteType to convert - Returns a .NET Type object - - - - For a given intrinsic type, return a DbType - - The native type to convert - The corresponding (closest match) DbType - - - - Returns the ColumnSize for the given DbType - - The DbType to get the size of - - - - - Determines the type name for the given database value type. - - The connection context for custom type mappings, if any. - The database value type. - The flags associated with the parent connection object. - The type name or an empty string if it cannot be determined. - - - - Convert a DbType to a Type - - The DbType to convert from - The closest-match .NET type - - - - For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types. - - The type to evaluate - The SQLite type affinity for that type. - - - - Builds and returns a map containing the database column types - recognized by this provider. - - - A map containing the database column types recognized by this - provider. - - - - - For a given type name, return a closest-match .NET type - - The connection context for custom type mappings, if any. - The name of the type to match - The flags associated with the parent connection object. - The .NET DBType the text evaluates to. - - - - The error code used for logging exceptions caught in user-provided - code. - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Shutdown the SQLite engine so that it can be restarted with different config options. - We depend on auto initialization to recover. - - - - - Determines if the associated native connection handle is open. - - - Non-zero if a database connection is open. - - - - - Opens a database. - - - Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection - to bind all attributed user-defined functions and collating sequences to the new connection. - - The filename of the database to open. SQLite automatically creates it if it doesn't exist. - The flags associated with the parent connection object - The open flags to use when creating the connection - The maximum size of the pool for the given filename - If true, the connection can be pulled from the connection pool - - - - Closes the currently-open database. - - - After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated - memory associated with the user-defined functions and collating sequences tied to the closed connection. - - Non-zero if the operation is allowed to throw exceptions, zero otherwise. - - - - Sets the busy timeout on the connection. SQLiteCommand will call this before executing any command. - - The number of milliseconds to wait before returning SQLITE_BUSY - - - - Returns the text of the last error issued by SQLite - - - - - - Returns the text of the last error issued by SQLite -OR- the specified default error text if - none is available from the SQLite core library. - - - The error text to return in the event that one is not available from the SQLite core library. - - - The error text. - - - - - When pooling is enabled, force this connection to be disposed rather than returned to the pool - - - - - When pooling is enabled, returns the number of pool entries matching the current file name. - - The number of pool entries matching the current file name. - - - - Prepares a SQL statement for execution. - - The source connection preparing the command. Can be null for any caller except LINQ - The SQL command text to prepare - The previous statement in a multi-statement command, or null if no previous statement exists - The timeout to wait before aborting the prepare - The remainder of the statement that was not processed. Each call to prepare parses the - SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned - here for a subsequent call to Prepare() until all the text has been processed. - Returns an initialized SQLiteStatement. - - - - Steps through a prepared statement. - - The SQLiteStatement to step through - True if a row was returned, False if not. - - - - Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, - transparently attempt to rebuild the SQL statement and throw an error if that was not possible. - - The statement to reset - Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined functions to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Enables or disabled extened result codes returned by SQLite - - true to enable extended result codes, false to disable. - - - - - Returns the numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Result code - - - - Returns the extended numeric result code for the most recent failed SQLite API call - associated with the database connection. - - Extended result code - - - - Add a log message via the SQLite sqlite3_log interface. - - Error code to be logged with the message. - String to be logged. Unlike the SQLite sqlite3_log() - interface, this should be pre-formatted. Consider using the - String.Format() function. - - - - - Checks if the SQLite core library has been initialized in the current process. - - - Non-zero if the SQLite core library has been initialized in the current process, - zero otherwise. - - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy or negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Returns the error message for the specified SQLite return code using - the internal static lookup table. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the error message for the specified SQLite return code using - the sqlite3_errstr() function, falling back to the internal lookup - table if necessary. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns a string representing the active version of SQLite - - - - - Returns an integer representing the active version of SQLite - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of changes the last executing insert/update caused. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. This is not really a per-connection - value, it is global to the process. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - This is not really a per-connection value, it is global to the process. - - - - - Returns non-zero if the underlying native connection handle is owned by this instance. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - The opaque pointer returned to us by the sqlite provider - - - - - The user-defined functions registered on this connection - - - - - The modules created using this connection. - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - This method attempts to dispose of all the derived - object instances currently associated with the native database connection. - - - - - Attempts to interrupt the query currently executing on the associated - native database connection. - - - - - This function binds a user-defined function to the connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Attempts to free as much heap memory as possible for the database connection. - - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - Returns a standard SQLite result code. - - - - Shutdown the SQLite engine so that it can be restarted with different - configuration options. We depend on auto initialization to recover. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. This parameter has no - effect on non-Windows operating systems. - - Returns a standard SQLite result code. - - - - Determines if the associated native connection handle is open. - - - Non-zero if the associated native connection handle is open. - - - - - Calls the native SQLite core library in order to create a disposable - module containing the implementation of a virtual table. - - - The module object to be used when creating the native disposable module. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to cleanup the resources - associated with a module containing the implementation of a virtual table. - - - The module object previously passed to the - method. - - - The flags for the associated object instance. - - - - - Calls the native SQLite core library in order to declare a virtual table - in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - being declared. - - - The string containing the SQL statement describing the virtual table to - be declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual table - function in response to a call into the - or virtual table methods. - - - The virtual table module that is to be responsible for the virtual table - function being declared. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon failure, - it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Enables or disabled extension loading by SQLite. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - Enables or disabled extended result codes returned by SQLite - - - Gets the last SQLite error code - - - Gets the last SQLite extended error code - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Allows the setting of a logging callback invoked by SQLite when a - log event occurs. Only one callback may be set. If NULL is passed, - the logging callback is unregistered. - - The callback function to invoke. - Returns a result code - - - - Creates a new SQLite backup object based on the provided destination - database connection. The source database connection is the one - associated with this object. The source and destination database - connections cannot be the same. - - The destination database connection. - The destination database name. - The source database name. - The newly created backup object. - - - - Copies up to N pages from the source database to the destination - database associated with the specified backup object. - - The backup object to use. - - The number of pages to copy, negative to copy all remaining pages. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True if there are more pages to be copied, false otherwise. - - - - - Returns the number of pages remaining to be copied from the source - database to the destination database associated with the specified - backup object. - - The backup object to check. - The number of pages remaining to be copied. - - - - Returns the total number of pages in the source database associated - with the specified backup object. - - The backup object to check. - The total number of pages in the source database. - - - - Destroys the backup object, rolling back any backup that may be in - progess. - - The backup object to destroy. - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Determines if the SQLite core library has been initialized for the - current process. - - - A boolean indicating whether or not the SQLite core library has been - initialized for the current process. - - - - - Helper function to retrieve a column of data from an active statement. - - The statement being step()'d through - The flags associated with the connection. - The column index to retrieve - The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. - Returns the data in the column - - - - Returns non-zero if the underlying native connection handle is owned - by this instance. - - - - - Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) - - - - - Constructs the object used to interact with the SQLite core library - using the UTF-8 text encoding. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - The native handle to be associated with the database connection. - - - The fully qualified file name associated with . - - - Non-zero if the newly created object instance will need to dispose - of when it is no longer needed. - - - - - Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 - - A pointer to a UTF-16 string - The length (IN BYTES) of the string - A .NET string - - - - Represents a single SQL backup in SQLite. - - - - - The underlying SQLite object this backup is bound to. - - - - - The actual backup handle. - - - - - The destination database for the backup. - - - - - The destination database name for the backup. - - - - - The source database for the backup. - - - - - The source database name for the backup. - - - - - The last result from the StepBackup method of the SQLite3 class. - This is used to determine if the call to the FinishBackup method of - the SQLite3 class should throw an exception when it receives a non-Ok - return code from the core SQLite library. - - - - - Initializes the backup. - - The base SQLite object. - The backup handle. - The destination database for the backup. - The destination database name for the backup. - The source database for the backup. - The source database name for the backup. - - - - Disposes and finalizes the backup. - - - - - The extra behavioral flags that can be applied to a connection. - - - - - No extra flags. - - - - - Enable logging of all SQL statements to be prepared. - - - - - Enable logging of all bound parameter types and raw values. - - - - - Enable logging of all bound parameter strongly typed values. - - - - - Enable logging of all exceptions caught from user-provided - managed code called from native code via delegates. - - - - - Enable logging of backup API errors. - - - - - Skip adding the extension functions provided by the native - interop assembly. - - - - - When binding parameter values with the - type, use the interop method that accepts an - value. - - - - - When binding parameter values, always bind them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - When returning column values, always return them as though they were - plain text (i.e. no numeric, date/time, or other conversions should - be attempted). - - - - - Prevent this object instance from - loading extensions. - - - - - Prevent this object instance from - creating virtual table modules. - - - - - Skip binding any functions provided by other managed assemblies when - opening the connection. - - - - - Skip setting the logging related properties of the - object instance that was passed to - the method. - - - - - Enable logging of all virtual table module errors seen by the - method. - - - - - Enable logging of certain virtual table module exceptions that cannot - be easily discovered via other means. - - - - - Enable tracing of potentially important [non-fatal] error conditions - that cannot be easily reported through other means. - - - - - When binding parameter values, always use the invariant culture when - converting their values from strings. - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings. - - - - - Disable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using the connection pool by default. If the "Pooling" - connection string property is specified, its value will override - this flag. The precise outcome of combining this flag with the - flag is unspecified; however, - one of the flags will be in effect. - - - - - Enable using per-connection mappings between type names and - values. Also see the - , - , and - methods. These - per-connection mappings, when present, override the corresponding - global mappings. - - - - - Disable using global mappings between type names and - values. This may be useful in some very narrow - cases; however, if there are no per-connection type mappings, the - fallback defaults will be used for both type names and their - associated values. Therefore, use of this flag - is not recommended. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted). - - - - - When binding parameter values, always use the invariant culture when - converting their values to strings or from strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings. - - - - - When binding parameter values or returning column values, always - treat them as though they were plain text (i.e. no numeric, - date/time, or other conversions should be attempted) and always - use the invariant culture when converting their values to strings - or from strings. - - - - - Enable all logging. - - - - - The default extra flags for new connections. - - - - - SQLite implementation of DbCommand. - - - - - The default connection string to be used when creating a temporary - connection to execute a command via the static - or - - methods. - - - - - The command text this command is based on - - - - - The connection the command is associated with - - - - - The version of the connection the command is associated with - - - - - Indicates whether or not a DataReader is active on the command. - - - - - The timeout for the command, kludged because SQLite doesn't support per-command timeout values - - - - - Designer support - - - - - Used by DbDataAdapter to determine updating behavior - - - - - The collection of parameters for the command - - - - - The SQL command text, broken into individual SQL statements as they are executed - - - - - Unprocessed SQL text that has not been executed - - - - - Transaction associated with this command - - - - - Constructs a new SQLiteCommand - - - Default constructor - - - - - Initializes the command with the given command text - - The SQL command text - - - - Initializes the command with the given SQL command text and attach the command to the specified - connection. - - The SQL command text - The connection to associate with the command - - - - Initializes the command and associates it with the specified connection. - - The connection to associate with the command - - - - Initializes a command with the given SQL, connection and transaction - - The SQL command text - The connection to associate with the command - The transaction the command should be associated with - - - - Disposes of the command and clears all member variables - - Whether or not the class is being explicitly or implicitly disposed - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The command containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Clears and destroys all statements currently prepared - - - - - Builds an array of prepared statements for each complete SQL statement in the command text - - - - - Not implemented - - - - - Forwards to the local CreateParameter() function - - - - - - Create a new parameter - - - - - - This function ensures there are no active readers, that we have a valid connection, - that the connection is open, that all statements are prepared and all parameters are assigned - in preparation for allocating a data reader. - - - - - Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements - - The behavior the data reader should adopt - Returns a SQLiteDataReader object - - - - This method creates a new connection, executes the query using the given - execution type, closes the connection, and returns the results. If the - connection string is null, a temporary in-memory database connection will - be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - This method creates a new connection, executes the query using the given - execution type and command behavior, closes the connection, and returns - the results. If the connection string is null, a temporary in-memory - database connection will be used. - - - The text of the command to be executed. - - - The execution type for the command. This is used to determine which method - of the command object to call, which then determines the type of results - returned, if any. - - - The command behavior flags for the command. - - - The connection string to the database to be opened, used, and closed. If - this parameter is null, a temporary in-memory databse will be used. - - - The SQL parameter values to be used when building the command object to be - executed, if any. - - - The results of the query -OR- null if no results were produced from the - given execution type. - - - - - Overrides the default behavior to return a SQLiteDataReader specialization class - - The flags to be associated with the reader. - A SQLiteDataReader - - - - Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class - - A SQLiteDataReader - - - - Called by the SQLiteDataReader when the data reader is closed. - - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The number of rows inserted/updated affected by it. - - - - Execute the command and return the number of rows inserted/updated affected by it. - - The flags to be associated with the reader. - The number of rows inserted/updated affected by it. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The first column of the first row of the first resultset from the query. - - - - Execute the command and return the first column of the first row of the resultset - (if present), or null if no resultset was returned. - - The flags to be associated with the reader. - The first column of the first row of the first resultset from the query. - - - - Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. - - - - - Clones a command, including all its parameters - - A new SQLiteCommand with the same commandtext, connection and parameters - - - - The SQL command text associated with the command - - - - - The amount of time to wait for the connection to become available before erroring out - - - - - The type of the command. SQLite only supports CommandType.Text - - - - - The connection associated with this command - - - - - Forwards to the local Connection property - - - - - Returns the SQLiteParameterCollection for the given command - - - - - Forwards to the local Parameters property - - - - - The transaction associated with this command. SQLite only supports one transaction per connection, so this property forwards to the - command's underlying connection. - - - - - Forwards to the local Transaction property - - - - - Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. - - - - - Determines if the command is visible at design time. Defaults to True. - - - - - SQLite implementation of DbCommandBuilder. - - - - - Default constructor - - - - - Initializes the command builder and associates it with the specified data adapter. - - - - - - Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema - - The parameter to use in applying custom behaviors to a row - The row to apply the parameter to - The type of statement - Whether the application of the parameter is part of a WHERE clause - - - - Returns a valid named parameter - - The name of the parameter - Error - - - - Returns a named parameter for the given ordinal - - The i of the parameter - Error - - - - Returns a placeholder character for the specified parameter i. - - The index of the parameter to provide a placeholder for - Returns a named parameter - - - - Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL - statements that may not have previously been generated. - - A data adapter to receive events on. - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - Returns the automatically-generated SQLite command to delete rows from the database - - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - Returns the automatically-generated SQLite command to update rows in the database - - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - Returns the automatically-generated SQLite command to insert rows into the database - - - - - - - Places brackets around an identifier - - The identifier to quote - The bracketed identifier - - - - Removes brackets around an identifier - - The quoted (bracketed) identifier - The undecorated identifier - - - - Override helper, which can help the base command builder choose the right keys for the given query - - - - - - - Gets/sets the DataAdapter for this CommandBuilder - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Overridden to hide its property from the designer - - - - - Event data for connection event handlers. - - - - - The type of event being raised. - - - - - The associated with this event, if any. - - - - - The transaction associated with this event, if any. - - - - - The command associated with this event, if any. - - - - - The data reader associated with this event, if any. - - - - - The critical handle associated with this event, if any. - - - - - Command or message text associated with this event, if any. - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - The type of event being raised. - The base associated - with this event, if any. - The transaction associated with this event, if any. - The command associated with this event, if any. - The data reader associated with this event, if any. - The critical handle associated with this event, if any. - The command or message text, if any. - The extra data, if any. - - - - Raised when an event pertaining to a connection occurs. - - The connection involved. - Extra information about the event. - - - - SQLite implentation of DbConnection. - - - The property can contain the following parameter(s), delimited with a semi-colon: - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that make - use of COM (either directly or indirectly) due to possible deadlocks that - can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - The default "stub" (i.e. placeholder) base schema name to use when - returning column schema information. Used as the initial value of - the BaseSchemaName property. This should start with "sqlite_*" - because those names are reserved for use by SQLite (i.e. they cannot - be confused with the names of user objects). - - - - - The managed assembly containing this type. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - State of the current connection - - - - - The connection string - - - - - Nesting level of the transactions open on the connection - - - - - If set, then the connection is currently being disposed. - - - - - The default isolation level for new transactions - - - - - Whether or not the connection is enlisted in a distrubuted transaction - - - - - The per-connection mappings between type names and - values. These mappings override the corresponding global mappings. - - - - - The base SQLite object to interop with - - - - - The database filename minus path and extension - - - - - Temporary password storage, emptied after the database has been opened - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. - - - - - The extra behavioral flags for this connection, if any. See the - enumeration for a list of - possible values. - - - - - Default command timeout - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Constructs a new SQLiteConnection object - - - Default constructor - - - - - Initializes the connection with the specified connection string. - - The connection string to use. - - - - Initializes the connection with a pre-existing native connection handle. - This constructor overload is intended to be used only by the private - method. - - - The native connection handle to use. - - - The file name corresponding to the native connection handle. - - - Non-zero if this instance owns the native connection handle and - should dispose of it when it is no longer needed. - - - - - Initializes the connection with the specified connection string. - - - The connection string to use. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Clones the settings and connection string from an existing connection. If the existing connection is already open, this - function will open its own connection, enumerate any attached databases of the original connection, and automatically - attach to them. - - The connection to copy the settings from. - - - - Raises the event. - - - The connection associated with this event. If this parameter is not - null and the specified connection cannot raise events, then the - registered event handlers will not be invoked. - - - A that contains the event data. - - - - - Creates and returns a new managed database connection handle. This - method is intended to be used by implementations of the - interface only. In theory, it - could be used by other classes; however, that usage is not supported. - - - This must be a native database connection handle returned by the - SQLite core library and it must remain valid and open during the - entire duration of the calling method. - - - The new managed database connection handle or null if it cannot be - created. - - - - - Backs up the database, using the specified database connection as the - destination. - - The destination database connection. - The destination database name. - The source database name. - - The number of pages to copy or negative to copy all remaining pages. - - - The method to invoke between each step of the backup process. This - parameter may be null (i.e. no callbacks will be performed). - - - The number of milliseconds to sleep after encountering a locking error - during the backup process. A value less than zero means that no sleep - should be performed. - - - - - Clears the per-connection type mappings. - - - The total number of per-connection type mappings cleared. - - - - - Returns the per-connection type mappings. - - - The per-connection type mappings -OR- null if they are unavailable. - - - - - Adds a per-connection type mapping, possibly replacing one or more - that already exist. - - - The case-insensitive database type name (e.g. "MYDATE"). The value - of this parameter cannot be null. Using an empty string value (or - a string value consisting entirely of whitespace) for this parameter - is not recommended. - - - The value that should be associated with the - specified type name. - - - Non-zero if this mapping should be considered to be the primary one - for the specified . - - - A negative value if nothing was done. Zero if no per-connection type - mappings were replaced (i.e. it was a pure add operation). More than - zero if some per-connection type mappings were replaced. - - - - - Attempts to bind the specified object - instance to this connection. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - - - Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection - will also be opened. - - - - - - Creates a database file. This just creates a zero-byte file which SQLite - will turn into a database when the file is opened properly. - - The file to create - - - - Raises the state change event when the state of the connection changes - - The new connection state. If this is different - from the previous state, the event is - raised. - The event data created for the raised event, if - it was actually raised. - - - - Determines and returns the fallback default isolation level when one cannot be - obtained from an existing connection instance. - - - The fallback default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - Determines and returns the default isolation level for this connection instance. - - - The default isolation level for this connection instance -OR- - if it cannot be determined. - - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - This parameter is ignored. - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. - - When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer - environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already active on the connection. - - Supported isolation levels are Serializable, ReadCommitted and Unspecified. - - Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the - connection string, Serializable is used. - Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads - may begin a transaction. Other threads may read from the database, but not write. - With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start - a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread - has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. - - Returns a SQLiteTransaction object. - - - - Creates a new if one isn't already - active on the connection. - - Returns the new transaction object. - - - - Forwards to the local function - - Supported isolation levels are Unspecified, Serializable, and ReadCommitted - - - - - This method is not implemented; however, the - event will still be raised. - - - - - - When the database connection is closed, all commands linked to this connection are automatically reset. - - - - - Clears the connection pool associated with the connection. Any other active connections using the same database file - will be discarded instead of returned to the pool when they are closed. - - - - - - Clears all connection pools. Any active connections will be discarded instead of sent to the pool when they are closed. - - - - - Create a new and associate it with this connection. - - Returns a new command object already assigned to this connection. - - - - Forwards to the local function. - - - - - - Parses the connection string into component parts using the custom - connection string parser. - - The connection string to parse - An array of key-value pairs representing each parameter of the connection string - - - - Parses a connection string using the built-in (i.e. framework provided) - connection string parser class and returns the key/value pairs. An - exception may be thrown if the connection string is invalid or cannot be - parsed. When compiled for the .NET Compact Framework, the custom - connection string parser is always used instead because the framework - provided one is unavailable there. - - - The connection string to parse. - - - Non-zero to throw an exception if any connection string values are not of - the type. - - The list of key/value pairs. - - - - Manual distributed transaction enlistment support - - The distributed transaction to enlist in - - - - Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value - - The list to look in - The key to find - The default value to return if the key is not found - The value corresponding to the specified key, or the default value if not found. - - - - Attempts to convert the string value to an enumerated value of the specified type. - - The enumerated type to convert the string value to. - The string value to be converted. - Non-zero to make the conversion case-insensitive. - The enumerated value upon success or null upon error. - - - - Attempts to convert an input string into a byte value. - - - The string value to be converted. - - - The number styles to use for the conversion. - - - Upon sucess, this will contain the parsed byte value. - Upon failure, the value of this parameter is undefined. - - - Non-zero upon success; zero on failure. - - - - - Enables or disabled extension loading. - - - True to enable loading of extensions, false to disable. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - - - Loads a SQLite extension library from the named dynamic link library file. - - - The name of the dynamic link library file containing the extension. - - - The name of the exported function used to initialize the extension. - If null, the default "sqlite3_extension_init" will be used. - - - - - Creates a disposable module containing the implementation of a virtual - table. - - - The module object to be used when creating the disposable module. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - Creates and returns a string containing the hexadecimal encoded byte - values from the input array. - - - The input array of bytes. - - - The resulting string or null upon failure. - - - - - Parses a string containing a sequence of zero or more hexadecimal - encoded byte values and returns the resulting byte array. The - "0x" prefix is not allowed on the input string. - - - The input string containing zero or more hexadecimal encoded byte - values. - - - Upon failure, this will contain an appropriate error message. - - - A byte array containing the parsed byte values or null if an error - was encountered. - - - - - This method figures out what the default connection pool setting should - be based on the connection flags. When present, the "Pooling" connection - string property value always overrides the value returned by this method. - - - Non-zero if the connection pool should be enabled by default; otherwise, - zero. - - - - - Opens the connection using the parameters found in the . - - - - - Opens the connection using the parameters found in the and then returns it. - - The current connection object. - - - - This method causes any pending database operation to abort and return at - its earliest opportunity. This routine is typically called in response - to a user action such as pressing "Cancel" or Ctrl-C where the user wants - a long query operation to halt immediately. It is safe to call this - routine from any thread. However, it is not safe to call this routine - with a database connection that is closed or might close before this method - returns. - - - - - Returns various global memory statistics for the SQLite core library via - a dictionary of key/value pairs. Currently, only the "MemoryUsed" and - "MemoryHighwater" keys are returned and they have values that correspond - to the values that could be obtained via the - and connection properties. - - - This dictionary will be populated with the global memory statistics. It - will be created if necessary. - - - - - Attempts to free as much heap memory as possible for this database connection. - - - - - Attempts to free N bytes of heap memory by deallocating non-essential memory - allocations held by the database library. Memory used to cache database pages - to improve performance is an example of non-essential memory. This is a no-op - returning zero if the SQLite core library was not compiled with the compile-time - option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or - compact the Win32 native heap, if applicable. - - - The requested number of bytes to free. - - - Non-zero to attempt a heap reset. - - - Non-zero to attempt heap compaction. - - - The number of bytes actually freed. This value may be zero. - - - This value will be non-zero if the heap reset was successful. - - - The size of the largest committed free block in the heap, in bytes. - This value will be zero unless heap compaction is enabled. - - - A standard SQLite return code (i.e. zero for success and non-zero - for failure). - - - - - Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. - If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is - global to the process. - - Non-zero to enable memory usage tracking, zero otherwise. - A standard SQLite return code (i.e. zero for success and non-zero for failure). - - - - Passes a shutdown request to the SQLite core library. Does not throw - an exception if the shutdown request fails. - - - A standard SQLite return code (i.e. zero for success and non-zero for - failure). - - - - - Passes a shutdown request to the SQLite core library. Throws an - exception if the shutdown request fails and the no-throw parameter - is non-zero. - - - Non-zero to reset the database and temporary directories to their - default values, which should be null for both. - - - When non-zero, throw an exception if the shutdown request fails. - - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Enables or disabled extended result codes returned by SQLite - - - Add a log message via the SQLite sqlite3_log interface. - - - Add a log message via the SQLite sqlite3_log interface. - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Change the password (or assign a password) to an open database. - - - No readers or writers may be active for this process. The database must already be open - and if it already was password protected, the existing password must already have been supplied. - - The new password to assign to the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Sets the password for a password-protected database. A password-protected database is - unusable for any operation until the password has been set. - - The password for the database - - - - Queries or modifies the number of retries or the retry interval (in milliseconds) for - certain I/O operations that may fail due to anti-virus software. - - The number of times to retry the I/O operation. A negative value - will cause the current count to be queried and replace that negative value. - The number of milliseconds to wait before retrying the I/O - operation. This number is multiplied by the number of retry attempts so far to come - up with the final number of milliseconds to wait. A negative value will cause the - current interval to be queried and replace that negative value. - Zero for success, non-zero for error. - - - - Removes one set of surrounding single -OR- double quotes from the string - value and returns the resulting string value. If the string is null, empty, - or contains quotes that are not balanced, nothing is done and the original - string value will be returned. - - The string value to process. - - The string value, modified to remove one set of surrounding single -OR- - double quotes, if applicable. - - - - - Expand the filename of the data source, resolving the |DataDirectory| - macro as appropriate. - - The database filename to expand - - Non-zero if the returned file name should be converted to a full path - (except when using the .NET Compact Framework). - - The expanded path and filename of the filename - - - - The following commands are used to extract schema information out of the database. Valid schema types are: - - - MetaDataCollections - - - DataSourceInformation - - - Catalogs - - - Columns - - - ForeignKeys - - - Indexes - - - IndexColumns - - - Tables - - - Views - - - ViewColumns - - - - - Returns the MetaDataCollections schema - - A DataTable of the MetaDataCollections schema - - - - Returns schema information of the specified collection - - The schema collection to retrieve - A DataTable of the specified collection - - - - Retrieves schema information using the specified constraint(s) for the specified collection - - The collection to retrieve - The restrictions to impose - A DataTable of the specified collection - - - - Builds a MetaDataCollections schema datatable - - DataTable - - - - Builds a DataSourceInformation datatable - - DataTable - - - - Build a Columns schema - - The catalog (attached database) to query, can be null - The table to retrieve schema information for, must not be null - The column to retrieve schema information for, can be null - DataTable - - - - Returns index information for the given database and catalog - - The catalog (attached database) to query, can be null - The name of the index to retrieve information for, can be null - The table to retrieve index information for, can be null - DataTable - - - - Retrieves table schema information for the database and catalog - - The catalog (attached database) to retrieve tables on - The table to retrieve, can be null - The table type, can be null - DataTable - - - - Retrieves view schema information for the database - - The catalog (attached database) to retrieve views on - The view name, can be null - DataTable - - - - Retrieves catalog (attached databases) schema information for the database - - The catalog to retrieve, can be null - DataTable - - - - Returns the base column information for indexes in a database - - The catalog to retrieve indexes for (can be null) - The table to restrict index information by (can be null) - The index to restrict index information by (can be null) - The source column to restrict index information by (can be null) - A DataTable containing the results - - - - Returns detailed column information for a specified view - - The catalog to retrieve columns for (can be null) - The view to restrict column information by (can be null) - The source column to restrict column information by (can be null) - A DataTable containing the results - - - - Retrieves foreign key information from the specified set of filters - - An optional catalog to restrict results on - An optional table to restrict results on - An optional foreign key name to restrict results on - A DataTable with the results of the query - - - - Static variable to store the connection event handlers to call. - - - - - This event is raised whenever the database is opened or closed. - - - - - This event is raised when events related to the lifecycle of a - SQLiteConnection object occur. - - - - - This property is used to obtain or set the custom connection pool - implementation to use, if any. Setting this property to null will - cause the default connection pool implementation to be used. - - - - - Returns the number of pool entries for the file name associated with this connection. - - - - - The connection string containing the parameters for the connection - - - - - Parameter - Values - Required - Default - - - Data Source - - This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). - Starting with release 1.0.86.0, in order to use more than one consecutive backslash (e.g. for a - UNC path), each of the adjoining backslash characters must be doubled (e.g. "\\Network\Share\test.db" - would become "\\\\Network\Share\test.db"). - - Y - - - - Version - 3 - N - 3 - - - UseUTF16Encoding - True
False
- N - False -
- - DateTimeFormat - - Ticks - Use the value of DateTime.Ticks.
- ISO8601 - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC - DateTime values and "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values).
- JulianDay - The interval of time in days and fractions of a day since January 1, 4713 BC.
- UnixEpoch - The whole number of seconds since the Unix epoch (January 1, 1970).
- InvariantCulture - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
- CurrentCulture - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
- N - ISO8601 -
- - DateTimeKind - Unspecified - Not specified as either UTC or local time.
Utc - The time represented is UTC.
Local - The time represented is local time.
- N - Unspecified -
- - DateTimeFormatString - The exact DateTime format string to use for all formatting and parsing of all DateTime - values for this connection. - N - null - - - BaseSchemaName - Some base data classes in the framework (e.g. those that build SQL queries dynamically) - assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting - alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used - as a placeholder and removed prior to preparing any SQL statements that may contain it. - N - sqlite_default_schema - - - BinaryGUID - True - Store GUID columns in binary form
False - Store GUID columns as text
- N - True -
- - Cache Size - {size in bytes} - N - 2000 - - - Synchronous - Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
- N - Full -
- - Page Size - {size in bytes} - N - 1024 - - - Password - {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - HexPassword - {hexPassword} - Must contain a sequence of zero or more hexadecimal encoded byte values without a leading "0x" prefix. Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. - N - - - - Enlist - Y - Automatically enlist in distributed transactions
N - No automatic enlistment
- N - Y -
- - Pooling - - True - Use connection pooling.
- False - Do not use connection pooling.

- WARNING: When using the default connection pool implementation, - setting this property to True should be avoided by applications that - make use of COM (either directly or indirectly) due to possible - deadlocks that can occur during the finalization of some COM objects. -
- N - False -
- - FailIfMissing - True - Don't create the database if it does not exist, throw an error instead
False - Automatically create the database if it does not exist
- N - False -
- - Max Page Count - {size in pages} - Limits the maximum number of pages (limits the size) of the database - N - 0 - - - Legacy Format - True - Use the more compatible legacy 3.x database format
False - Use the newer 3.3x database format which compresses numbers more effectively
- N - False -
- - Default Timeout - {time in seconds}
The default command timeout
- N - 30 -
- - Journal Mode - Delete - Delete the journal file after a commit
Persist - Zero out and leave the journal file on disk after a commit
Off - Disable the rollback journal entirely
- N - Delete -
- - Read Only - True - Open the database for read only access
False - Open the database for normal read/write access
- N - False -
- - Max Pool Size - The maximum number of connections for the given connection string that can be in the connection pool - N - 100 - - - Default IsolationLevel - The default transaciton isolation level - N - Serializable - - - Foreign Keys - Enable foreign key constraints - N - False - - - Flags - Extra behavioral flags for the connection. See the enumeration for possible values. - N - Default - - - SetDefaults - - True - Apply the default connection settings to the opened database.
- False - Skip applying the default connection settings to the opened database. -
- N - True -
- - ToFullPath - - True - Attempt to expand the data source file name to a fully qualified path before opening.
- False - Skip attempting to expand the data source file name to a fully qualified path before opening. -
- N - True -
-
-
-
- - - Returns the data source file name without extension or path. - - - - - Returns the string "main". - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - This can also be set in the ConnectionString with "Default Timeout" - - - - - Non-zero if the built-in (i.e. framework provided) connection string - parser should be used when opening the connection. - - - - - Gets/sets the extra behavioral flags for this connection. See the - enumeration for a list of - possible values. - - - - - Returns non-zero if the underlying native connection handle is - owned by this instance. - - - - - Returns the version of the underlying SQLite database engine - - - - - Returns the rowid of the most recent successful INSERT into the database from this connection. - - - - - Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on - this connection. - - - - - Returns non-zero if the given database connection is in autocommit mode. - Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN - statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK. - - - - - Returns the amount of memory (in bytes) currently in use by the SQLite core library. - - - - - Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. - - - - - Returns a string containing the define constants (i.e. compile-time - options) used to compile the core managed assembly, delimited with - spaces. - - - - - Returns the version of the underlying SQLite core library. - - - - - This method returns the string whose value is the same as the - SQLITE_SOURCE_ID C preprocessor macro used when compiling the - SQLite core library. - - - - - Returns a string containing the compile-time options used to - compile the SQLite core native library, delimited with spaces. - - - - - This method returns the version of the interop SQLite assembly - used. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the interop - assembly. If the SQLite interop assembly is not in use or the - necessary information cannot be obtained for any reason, a null - value may be returned. - - - - - Returns a string containing the compile-time options used to - compile the SQLite interop assembly, delimited with spaces. - - - - - This method returns the version of the managed components used - to interact with the SQLite core library. If the necessary - information cannot be obtained for any reason, a null value may - be returned. - - - - - This method returns the string whose value contains the unique - identifier for the source checkout used to build the managed - components currently executing. If the necessary information - cannot be obtained for any reason, a null value may be returned. - - - - - Returns the state of the connection. - - - - - This event is raised whenever SQLite encounters an action covered by the - authorizer during query preparation. Changing the value of the - property will determine if - the specific action will be allowed, ignored, or denied. For the entire - duration of the event, the associated connection and statement objects - must not be modified, either directly or indirectly, by the called code. - - - - - This event is raised whenever SQLite makes an update/delete/insert into the database on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is committing a transaction. - Return non-zero to trigger a rollback. - - - - - This event is raised whenever SQLite statement first begins executing on - this connection. It only applies to the given connection. - - - - - This event is raised whenever SQLite is rolling back a transaction. - - - - - Returns the instance. - - - - - The I/O file cache flushing behavior for the connection - - - - - Normal file flushing at critical sections of the code - - - - - Full file flushing after every write operation - - - - - Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing - - - - - Raised when authorization is required to perform an action contained - within a SQL query. - - The connection performing the action. - A that contains the - event data. - - - - Raised when a transaction is about to be committed. To roll back a transaction, set the - rollbackTrans boolean value to true. - - The connection committing the transaction - Event arguments on the transaction - - - - Raised when data is inserted, updated and deleted on a given connection - - The connection committing the transaction - The event parameters which triggered the event - - - - Raised when a statement first begins executing on a given connection - - The connection executing the statement - Event arguments of the trace - - - - Raised between each backup step. - - - The source database connection. - - - The source database name. - - - The destination database connection. - - - The destination database name. - - - The number of pages copied with each step. - - - The number of pages remaining to be copied. - - - The total number of pages in the source database. - - - Set to true if the operation needs to be retried due to database - locking issues; otherwise, set to false. - - - True to continue with the backup process or false to halt the backup - process, rolling back any changes that have been made so far. - - - - - The data associated with a call into the authorizer. - - - - - The user-defined native data associated with this event. Currently, - this will always contain the value of . - - - - - The action code responsible for the current call into the authorizer. - - - - - The first string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The second string argument for the current call into the authorizer. - The exact value will vary based on the action code, see the - enumeration for possible - values. - - - - - The database name for the current call into the authorizer, if - applicable. - - - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - - - The return code for the current call into the authorizer. - - - - - Constructs an instance of this class with default property values. - - - - - Constructs an instance of this class with specific property values. - - - The user-defined native data associated with this event. - - - The authorizer action code. - - - The first authorizer argument. - - - The second authorizer argument. - - - The database name, if applicable. - - - The name of the inner-most trigger or view that is responsible for - the access attempt or a null value if this access attempt is directly - from top-level SQL code. - - - The authorizer return code. - - - - - Whenever an update event is triggered on a connection, this enum will indicate - exactly what type of operation is being performed. - - - - - A row is being deleted from the given database and table - - - - - A row is being inserted into the table. - - - - - A row is being updated in the table. - - - - - Passed during an Update callback, these event arguments detail the type of update operation being performed - on the given connection. - - - - - The name of the database being updated (usually "main" but can be any attached or temporary database) - - - - - The name of the table being updated - - - - - The type of update being performed (insert/update/delete) - - - - - The RowId affected by this update. - - - - - Event arguments raised when a transaction is being committed - - - - - Set to true to abort the transaction and trigger a rollback - - - - - Passed during an Trace callback, these event arguments contain the UTF-8 rendering of the SQL statement text - - - - - SQL statement text as the statement first begins executing - - - - - This interface represents a custom connection pool implementation - usable by System.Data.SQLite. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This default method implementations in this class should not be used by - applications that make use of COM (either directly or indirectly) due - to possible deadlocks that can occur during finalization of some COM - objects. - - - - - This field is used to synchronize access to the private static data - in this class. - - - - - When this field is non-null, it will be used to provide the - implementation of all the connection pool methods; otherwise, - the default method implementations will be used. - - - - - The dictionary of connection pools, based on the normalized file - name of the SQLite database. - - - - - The default version number new pools will get. - - - - - The number of connections successfully opened from any pool. - This value is incremented by the Remove method. - - - - - The number of connections successfully closed from any pool. - This value is incremented by the Add method. - - - - - Counts the number of pool entries matching the specified file name. - - - The file name to match or null to match all files. - - - The pool entry counts for each matching file. - - - The total number of connections successfully opened from any pool. - - - The total number of connections successfully closed from any pool. - - - The total number of pool entries for all matching files. - - - - - Disposes of all pooled connections associated with the specified - database file name. - - - The database file name. - - - - - Disposes of all pooled connections. - - - - - Adds a connection to the pool of those associated with the - specified database file name. - - - The database file name. - - - The database connection handle. - - - The connection pool version at the point the database connection - handle was received from the connection pool. This is also the - connection pool version that the database connection handle was - created under. - - - - - Removes a connection from the pool of those associated with the - specified database file name with the intent of using it to - interact with the database. - - - The database file name. - - - The new maximum size of the connection pool for the specified - database file name. - - - The connection pool version associated with the returned database - connection handle, if any. - - - The database connection handle associated with the specified - database file name or null if it cannot be obtained. - - - - - This method is used to obtain a reference to the custom connection - pool implementation currently in use, if any. - - - The custom connection pool implementation or null if the default - connection pool implementation should be used. - - - - - This method is used to set the reference to the custom connection - pool implementation to use, if any. - - - The custom connection pool implementation to use or null if the - default connection pool implementation should be used. - - - - - We do not have to thread-lock anything in this function, because it - is only called by other functions above which already take the lock. - - - The pool queue to resize. - - - If a function intends to add to the pool, this is true, which - forces the resize to take one more than it needs from the pool. - - - - - Keeps track of connections made on a specified file. The PoolVersion - dictates whether old objects get returned to the pool or discarded - when no longer in use. - - - - - The queue of weak references to the actual database connection - handles. - - - - - This pool version associated with the database connection - handles in this pool queue. - - - - - The maximum size of this pool queue. - - - - - Constructs a connection pool queue using the specified version - and maximum size. Normally, all the database connection - handles in this pool are associated with a single database file - name. - - - The initial pool version for this connection pool queue. - - - The initial maximum size for this connection pool queue. - - - - - SQLite implementation of DbConnectionStringBuilder. - - - - - Properties of this class - - - - - Constructs a new instance of the class - - - Default constructor - - - - - Constructs a new instance of the class using the specified connection string. - - The connection string to parse - - - - Private initializer, which assigns the connection string and resets the builder - - The connection string to assign - - - - Helper function for retrieving values from the connectionstring - - The keyword to retrieve settings for - The resulting parameter value - Returns true if the value was found and returned - - - - Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties() - - The hashtable to fill with property descriptors - - - - Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. - - - - - Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal". - - - - - Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. - - - - - Gets/Sets whether or not to use connection pooling. The default is "False" - - - - - Gets/Sets whethor not to store GUID's in binary format. The default is True - which saves space in the database. - - - - - Gets/Sets the filename to open on the connection string. - - - - - An alternate to the data source property - - - - - An alternate to the data source property that uses the SQLite URI syntax. - - - - - Gets/sets the default command timeout for newly-created commands. This is especially useful for - commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. - - - - - Determines whether or not the connection will automatically participate - in the current distributed transaction (if one exists) - - - - - If set to true, will throw an exception if the database specified in the connection - string does not exist. If false, the database will be created automatically. - - - - - If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger - database sizes. - - - - - When enabled, the database will be opened for read-only access and writing will be disabled. - - - - - Gets/sets the database encryption password - - - - - Gets/sets the database encryption hexadecimal password - - - - - Gets/Sets the page size for the connection. - - - - - Gets/Sets the maximum number of pages the database may hold - - - - - Gets/Sets the cache size for the connection. - - - - - Gets/Sets the DateTime format for the connection. - - - - - Gets/Sets the DateTime kind for the connection. - - - - - Gets/sets the DateTime format string used for formatting - and parsing purposes. - - - - - Gets/Sets the placeholder base schema name used for - .NET Framework compatibility purposes. - - - - - Determines how SQLite handles the transaction journal file. - - - - - Sets the default isolation level for transactions on the connection. - - - - - If enabled, use foreign key constraints - - - - - Gets/Sets the extra behavioral flags. - - - - - If enabled, apply the default connection settings to opened databases. - - - - - If enabled, attempt to resolve the provided data source file name to a - full path before opening. - - - - - SQLite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types SQLite - understands. The DateTime extension to the spec is for internal use only. - - - - - Not used - - - - - All integers in SQLite default to Int64 - - - - - All floating point numbers in SQLite default to double - - - - - The default data type of SQLite is text - - - - - Typically blob types are only seen when returned from a function - - - - - Null types can be returned from functions - - - - - Used internally by this provider - - - - - Used internally by this provider - - - - - These are the event types associated with the - - delegate (and its corresponding event) and the - class. - - - - - Not used. - - - - - Not used. - - - - - The connection is being opened. - - - - - The connection string has been parsed. - - - - - The connection was opened. - - - - - The method was called on the - connection. - - - - - A transaction was created using the connection. - - - - - The connection was enlisted into a transaction. - - - - - A command was created using the connection. - - - - - A data reader was created using the connection. - - - - - An instance of a derived class has - been created to wrap a native resource. - - - - - The connection is being closed. - - - - - The connection was closed. - - - - - This implementation of SQLite for ADO.NET can process date/time fields in - databases in one of six formats. - - - ISO8601 format is more compatible, readable, fully-processable, but less - accurate as it does not provide time down to fractions of a second. - JulianDay is the numeric format the SQLite uses internally and is arguably - the most compatible with 3rd party tools. It is not readable as text - without post-processing. Ticks less compatible with 3rd party tools that - query the database, and renders the DateTime field unreadable as text - without post-processing. UnixEpoch is more compatible with Unix systems. - InvariantCulture allows the configured format for the invariant culture - format to be used and is human readable. CurrentCulture allows the - configured format for the current culture to be used and is also human - readable. - - The preferred order of choosing a DateTime format is JulianDay, ISO8601, - and then Ticks. Ticks is mainly present for legacy code support. - - - - - Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ. - - - - - Use the ISO-8601 format. Uses the "yyyy-MM-dd HH:mm:ss.FFFFFFFK" format for UTC DateTime values and - "yyyy-MM-dd HH:mm:ss.FFFFFFF" format for local DateTime values). - - - - - The interval of time in days and fractions of a day since January 1, 4713 BC. - - - - - The whole number of seconds since the Unix epoch (January 1, 1970). - - - - - Any culture-independent string value that the .NET Framework can interpret as a valid DateTime. - - - - - Any string value that the .NET Framework can interpret as a valid DateTime using the current culture. - - - - - The default format for this provider. - - - - - This enum determines how SQLite treats its journal file. - - - By default SQLite will create and delete the journal file when needed during a transaction. - However, for some computers running certain filesystem monitoring tools, the rapid - creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite. - - If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file" - when starting a transaction. If this is happening, you may want to change the default journal mode to Persist. - - - - - The default mode, this causes SQLite to use the existing journaling mode for the database. - - - - - SQLite will create and destroy the journal file as-needed. - - - - - When this is set, SQLite will keep the journal file even after a transaction has completed. It's contents will be erased, - and the journal re-used as often as needed. If it is deleted, it will be recreated the next time it is needed. - - - - - This option disables the rollback journal entirely. Interrupted transactions or a program crash can cause database - corruption in this mode! - - - - - SQLite will truncate the journal file to zero-length instead of deleting it. - - - - - SQLite will store the journal in volatile RAM. This saves disk I/O but at the expense of database safety and integrity. - If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the - database file will very likely go corrupt. - - - - - SQLite uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling mode is persistent; - after being set it stays in effect across multiple database connections and after closing and reopening the database. A database - in WAL journaling mode can only be accessed by SQLite version 3.7.0 or later. - - - - - Possible values for the "synchronous" database setting. This setting determines - how often the database engine calls the xSync method of the VFS. - - - - - Use the default "synchronous" database setting. Currently, this should be - the same as using the FULL mode. - - - - - The database engine continues without syncing as soon as it has handed - data off to the operating system. If the application running SQLite - crashes, the data will be safe, but the database might become corrupted - if the operating system crashes or the computer loses power before that - data has been written to the disk surface. - - - - - The database engine will still sync at the most critical moments, but - less often than in FULL mode. There is a very small (though non-zero) - chance that a power failure at just the wrong time could corrupt the - database in NORMAL mode. - - - - - The database engine will use the xSync method of the VFS to ensure that - all content is safely written to the disk surface prior to continuing. - This ensures that an operating system crash or power failure will not - corrupt the database. FULL synchronous is very safe, but it is also - slower. - - - - - The requested command execution type. This controls which method of the - object will be called. - - - - - Do nothing. No method will be called. - - - - - The command is not expected to return a result -OR- the result is not - needed. The or - method - will be called. - - - - - The command is expected to return a scalar result -OR- the result should - be limited to a scalar result. The - or method will - be called. - - - - - The command is expected to return result. - The or - method will - be called. - - - - - Use the default command execution type. Using this value is the same - as using the value. - - - - - The action code responsible for the current call into the authorizer. - - - - - No action is being performed. This value should not be used from - external code. - - - - - No longer used. - - - - - An index will be created. The action-specific arguments are the - index name and the table name. - - - - - - A table will be created. The action-specific arguments are the - table name and a null value. - - - - - A temporary index will be created. The action-specific arguments - are the index name and the table name. - - - - - A temporary table will be created. The action-specific arguments - are the table name and a null value. - - - - - A temporary trigger will be created. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be created. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be created. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be created. The action-specific arguments are the view - name and a null value. - - - - - A DELETE statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - An index will be dropped. The action-specific arguments are the - index name and the table name. - - - - - A table will be dropped. The action-specific arguments are the tables - name and a null value. - - - - - A temporary index will be dropped. The action-specific arguments are - the index name and the table name. - - - - - A temporary table will be dropped. The action-specific arguments are - the table name and a null value. - - - - - A temporary trigger will be dropped. The action-specific arguments - are the trigger name and the table name. - - - - - A temporary view will be dropped. The action-specific arguments are - the view name and a null value. - - - - - A trigger will be dropped. The action-specific arguments are the - trigger name and the table name. - - - - - A view will be dropped. The action-specific arguments are the view - name and a null value. - - - - - An INSERT statement will be executed. The action-specific arguments - are the table name and a null value. - - - - - A PRAGMA statement will be executed. The action-specific arguments - are the name of the PRAGMA and the new value or a null value. - - - - - A table column will be read. The action-specific arguments are the - table name and the column name. - - - - - A SELECT statement will be executed. The action-specific arguments - are both null values. - - - - - A transaction will be started, committed, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - COMMIT, or ROLLBACK) and a null value. - - - - - An UPDATE statement will be executed. The action-specific arguments - are the table name and the column name. - - - - - A database will be attached to the connection. The action-specific - arguments are the database file name and a null value. - - - - - A database will be detached from the connection. The action-specific - arguments are the database name and a null value. - - - - - The schema of a table will be altered. The action-specific arguments - are the database name and the table name. - - - - - An index will be deleted and then recreated. The action-specific - arguments are the index name and a null value. - - - - - A table will be analyzed to gathers statistics about it. The - action-specific arguments are the table name and a null value. - - - - - A virtual table will be created. The action-specific arguments are - the table name and the module name. - - - - - A virtual table will be dropped. The action-specific arguments are - the table name and the module name. - - - - - A SQL function will be called. The action-specific arguments are a - null value and the function name. - - - - - A savepoint will be created, released, or rolled back. The - action-specific arguments are the name of the operation (BEGIN, - RELEASE, or ROLLBACK) and the savepoint name. - - - - - A recursive query will be executed. The action-specific arguments - are two null values. - - - - - The return code for the current call into the authorizer. - - - - - The action will be allowed. - - - - - The overall action will be disallowed and an error message will be - returned from the query preparation method. - - - - - The specific action will be disallowed; however, the overall action - will continue. The exact effects of this return code vary depending - on the specific action, please refer to the SQLite core library - documentation for futher details. - - - - - Class used internally to determine the datatype of a column in a resultset - - - - - The DbType of the column, or DbType.Object if it cannot be determined - - - - - The affinity of a column, used for expressions or when Type is DbType.Object - - - - - SQLite implementation of DbDataAdapter. - - - - - This class is just a shell around the DbDataAdapter. Nothing from - DbDataAdapter is overridden here, just a few constructors are defined. - - - Default constructor. - - - - - Constructs a data adapter using the specified select command. - - - The select command to associate with the adapter. - - - - - Constructs a data adapter with the supplied select command text and - associated with the specified connection. - - - The select command text to associate with the data adapter. - - - The connection to associate with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - - - Constructs a data adapter with the specified select command text, - and using the specified database connection string. - - - The select command text to use to construct a select command. - - - A connection string suitable for passing to a new SQLiteConnection, - which is associated with the select command. - - - Non-zero to parse the connection string using the built-in (i.e. - framework provided) parser when opening the connection. - - - - - Raised by the underlying DbDataAdapter when a row is being updated - - The event's specifics - - - - Raised by DbDataAdapter after a row is updated - - The event's specifics - - - - Row updating event handler - - - - - Row updated event handler - - - - - Gets/sets the select command for this DataAdapter - - - - - Gets/sets the insert command for this DataAdapter - - - - - Gets/sets the update command for this DataAdapter - - - - - Gets/sets the delete command for this DataAdapter - - - - - SQLite implementation of DbDataReader. - - - - - Underlying command this reader is attached to - - - - - Index of the current statement in the command being processed - - - - - Current statement being Read() - - - - - State of the current statement being processed. - -1 = First Step() executed, so the first Read() will be ignored - 0 = Actively reading - 1 = Finished reading - 2 = Non-row-returning statement, no records - - - - - Number of records affected by the insert/update statements executed on the command - - - - - Count of fields (columns) in the row-returning statement currently being processed - - - - - Maps the field (column) names to their corresponding indexes within the results. - - - - - Datatypes of active fields (columns) in the current statement, used for type-restricting data - - - - - The behavior of the datareader - - - - - If set, then dispose of the command object when the reader is finished - - - - - If set, then raise an exception when the object is accessed after being disposed. - - - - - An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified - - - - - Matches the version of the connection. - - - - - The "stub" (i.e. placeholder) base schema name to use when returning - column schema information. Matches the base schema name used by the - associated connection. - - - - - Internal constructor, initializes the datareader and sets up to begin executing statements - - The SQLiteCommand this data reader is for - The expected behavior of the data reader - - - - Dispose of all resources used by this datareader. - - - - - - Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. - - - - - Throw an error if the datareader is closed - - - - - Throw an error if a row is not loaded - - - - - Enumerator support - - Returns a DbEnumerator object. - - - - SQLite is inherently un-typed. All datatypes in SQLite are natively strings. The definition of the columns of a table - and the affinity of returned types are all we have to go on to type-restrict data in the reader. - - This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In - the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) - to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. - - - This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. - - The index of the column to type-check - The type we want to get out of the column - - - - Retrieves the column as a boolean value - - The index of the column to retrieve - bool - - - - Retrieves the column as a single byte value - - The index of the column to retrieve - byte - - - - Retrieves a column as an array of bytes (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the bytes into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of bytes written into the array - - To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. - - - - - Returns the column as a single character - - The index of the column to retrieve - char - - - - Retrieves a column as an array of chars (blob) - - The index of the column to retrieve - The zero-based index of where to begin reading the data - The buffer to write the characters into - The zero-based index of where to begin writing into the array - The number of bytes to retrieve - The actual number of characters written into the array - - To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. - - - - - Retrieves the name of the back-end datatype of the column - - The index of the column to retrieve - string - - - - Retrieve the column as a date/time value - - The index of the column to retrieve - DateTime - - - - Retrieve the column as a decimal value - - The index of the column to retrieve - decimal - - - - Returns the column as a double - - The index of the column to retrieve - double - - - - Returns the .NET type of a given column - - The index of the column to retrieve - Type - - - - Returns a column as a float value - - The index of the column to retrieve - float - - - - Returns the column as a Guid - - The index of the column to retrieve - Guid - - - - Returns the column as a short - - The index of the column to retrieve - Int16 - - - - Retrieves the column as an int - - The index of the column to retrieve - Int32 - - - - Retrieves the column as a long - - The index of the column to retrieve - Int64 - - - - Retrieves the name of the column - - The index of the column to retrieve - string - - - - Retrieves the i of a column, given its name - - The name of the column to retrieve - The int i of the column - - - - Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done - to gather the necessary information so it can be represented in an ADO.NET manner. - - Returns a DataTable containing the schema information for the active SELECT statement being processed. - - - - Retrieves the column as a string - - The index of the column to retrieve - string - - - - Retrieves the column as an object corresponding to the underlying datatype of the column - - The index of the column to retrieve - object - - - - Retreives the values of multiple columns, up to the size of the supplied array - - The array to fill with values from the columns in the current resultset - The number of columns retrieved - - - - Returns a collection containing all the column names and values for the - current row of data in the current resultset, if any. If there is no - current row or no current resultset, an exception may be thrown. - - - The collection containing the column name and value information for the - current row of data in the current resultset or null if this information - cannot be obtained. - - - - - Returns True if the specified column is null - - The index of the column to retrieve - True or False - - - - Moves to the next resultset in multiple row-returning SQL command. - - True if the command was successful and a new resultset is available, False otherwise. - - - - This method attempts to query the database connection associated with - the data reader in use. If the underlying command or connection is - unavailable, a null value will be returned. - - - The connection object -OR- null if it is unavailable. - - - - - This method attempts to query the flags associated with the database - connection in use. If the database connection is disposed, the default - flags will be returned. - - - The data reader containing the databse connection to query the flags from. - - - The connection flags value. - - - - - Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls. - - The index of the column to retrieve - A SQLiteType structure - - - - Reads the next row from the resultset - - True if a new row was successfully loaded and is ready for processing - - - - Not implemented. Returns 0 - - - - - Returns the number of columns in the current resultset - - - - - Returns the number of visible fields in the current resultset - - - - - Returns True if the resultset has rows that can be fetched - - - - - Returns True if the data reader is closed - - - - - Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! - - - - - Indexer to retrieve data from a column given its name - - The name of the column to retrieve data for - The value contained in the column - - - - Indexer to retrieve data from a column given its i - - The index of the column to retrieve - The value contained in the column - - - - SQLite exception class. - - - - - Private constructor for use with serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Public constructor for generating a SQLite exception given the error - code and message. - - - The SQLite return code to report. - - - Message text to go along with the return code message text. - - - - - Public constructor that uses the base class constructor for the error - message. - - Error message text. - - - - Public constructor that uses the default base class constructor. - - - - - Public constructor that uses the base class constructor for the error - message and inner exception. - - Error message text. - The original (inner) exception. - - - - Adds extra information to the serialized object data specific to this - class type. This is only used for serialization. - - - Holds the serialized object data about the exception being thrown. - - - Contains contextual information about the source or destination. - - - - - Returns the error message for the specified SQLite return code. - - The SQLite return code. - The error message or null if it cannot be found. - - - - Returns the composite error message based on the SQLite return code - and the optional detailed error message. - - The SQLite return code. - Optional detailed error message. - Error message text for the return code. - - - - Gets the associated SQLite result code for this exception as a - . This property returns the same - underlying value as the property. - - - - - Gets the associated SQLite return code for this exception as an - . For desktop versions of the .NET Framework, - this property overrides the property of the same name within the - - class. This property returns the same underlying value as the - property. - - - - - SQLite error codes. Actually, this enumeration represents a return code, - which may also indicate success in one of several ways (e.g. SQLITE_OK, - SQLITE_ROW, and SQLITE_DONE). Therefore, the name of this enumeration is - something of a misnomer. - - - - - The error code is unknown. This error code - is only used by the managed wrapper itself. - - - - - Successful result - - - - - SQL error or missing database - - - - - Internal logic error in SQLite - - - - - Access permission denied - - - - - Callback routine requested an abort - - - - - The database file is locked - - - - - A table in the database is locked - - - - - A malloc() failed - - - - - Attempt to write a readonly database - - - - - Operation terminated by sqlite3_interrupt() - - - - - Some kind of disk I/O error occurred - - - - - The database disk image is malformed - - - - - Unknown opcode in sqlite3_file_control() - - - - - Insertion failed because database is full - - - - - Unable to open the database file - - - - - Database lock protocol error - - - - - Database is empty - - - - - The database schema changed - - - - - String or BLOB exceeds size limit - - - - - Abort due to constraint violation - - - - - Data type mismatch - - - - - Library used incorrectly - - - - - Uses OS features not supported on host - - - - - Authorization denied - - - - - Auxiliary database format error - - - - - 2nd parameter to sqlite3_bind out of range - - - - - File opened that is not a database file - - - - - Notifications from sqlite3_log() - - - - - Warnings from sqlite3_log() - - - - - sqlite3_step() has another row ready - - - - - sqlite3_step() has finished executing - - - - - Used to mask off extended result codes - - - - - SQLite implementation of . - - - SQLite implementation of . - - - - - Constructs a new instance. - - - - - Static instance member which returns an instanced class. - - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Creates and returns a new object. - - The new object. - - - - Will provide a object in .NET 3.5. - - The class or interface type to query for. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. This event is provided for backward compatibility only. - New code should use the class instead. - - - - - This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each - connection to the database. - - - Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access - to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database - calls during processing. - - It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class - services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement - information in member variables of user-defined function classes. - - For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will - be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. - - - - - The base connection this function is attached to - - - - - Internal array used to keep track of aggregate function context data - - - - - The connection flags associated with this object (this should be the - same value as the flags associated with the parent connection object). - - - - - Holds a reference to the callback function for user functions - - - - - Holds a reference to the callbakc function for stepping in an aggregate function - - - - - Holds a reference to the callback function for finalizing an aggregate function - - - - - Holds a reference to the callback function for collation sequences - - - - - Current context of the current callback. Only valid during a callback - - - - - This static list contains all the user-defined functions declared using the proper attributes. - - - - - Internal constructor, initializes the function's internal variables. - - - - - Constructs an instance of this class using the specified data-type - conversion parameters. - - - The DateTime format to be used when converting string values to a - DateTime and binding DateTime parameters. - - - The to be used when creating DateTime - values. - - - The format string to be used when parsing and formatting DateTime - values. - - - Non-zero to create a UTF-16 data-type conversion context; otherwise, - a UTF-8 data-type conversion context will be created. - - - - - Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if - someone closes the connection while a DataReader is open. - - - - - Placeholder for a user-defined disposal routine - - True if the object is being disposed explicitly - - - - Scalar functions override this method to do their magic. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The arguments for the command to process - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - Aggregate functions override this method to do their magic. - - - Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. - - The arguments for the command to process - The 1-based step number. This is incrememted each time the step method is called. - A placeholder for implementers to store contextual data pertaining to the current context. - - - - Aggregate functions override this method to finish their aggregate processing. - - - If you implemented your aggregate function properly, - you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have - all the information you need in there to figure out what to return. - NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will - be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value - if that is the case. - - Your own assigned contextData, provided for you so you can return your final results. - You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or - you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error, - just return it! - - - - - User-defined collation sequences override this method to provide a custom string sorting algorithm. - - The first string to compare - The second strnig to compare - 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 - - - - Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. - - - Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available - to force them into a certain type. Therefore the only types you will ever see as parameters are - DBNull.Value, Int64, Double, String or byte[] array. - - The number of arguments - A pointer to the array of arguments - An object array of the arguments once they've been converted to .NET values - - - - Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context. - - The context the return value applies to - The parameter to return to SQLite - - - - Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. - WARNING: Must not throw exceptions. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. - WARNING: Must not throw exceptions. - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. Returns 0 if an exception is caught. - - - - The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. - WARNING: Must not throw exceptions. - - - This function takes care of doing the lookups and getting the important information put together to call the Step() function. - That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so - binary searches can be done to find the data. - - A raw context pointer - Number of arguments passed in - A pointer to the array of arguments - - - - An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. - WARNING: Must not throw exceptions. - - A raw context pointer - - - - Using reflection, enumerate all assemblies in the current appdomain looking for classes that - have a SQLiteFunctionAttribute attribute, and registering them accordingly. - - - - - Manual method of registering a function. The type must still have the SQLiteFunctionAttributes in order to work - properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. - - The type of the function to register - - - - Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection. - It is done this way so that all user-defined functions will access the database using the same encoding scheme - as the connection (UTF-8 or UTF-16). - - - The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to - all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. - - The base object on which the functions are to bind - The flags associated with the parent connection object - Returns a logical list of functions which the connection should retain until it is closed. - - - - This function binds a user-defined functions to a connection. - - - The object instance associated with the - that the function should be bound to. - - - The object instance containing - the metadata for the function to be bound. - - - The object instance that implements the - function to be bound. - - - The flags associated with the parent connection object. - - - - - Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert - strings and DateTime's into the current connection's encoding schema. - - - - - Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call. - - - User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays. - - - - - Obtains the collating sequence in effect for the given function. - - - - - - The type of user-defined function to declare - - - - - Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. - - - - - Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. - Examples include SUM(), COUNT(), AVG(), etc. - - - - - Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is - sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting - in a user-defined manner. - - - - - An internal callback delegate declaration. - - Raw native context pointer for the user function. - Total number of arguments to the user function. - Raw native pointer to the array of raw native argument pointers. - - - - An internal final callback delegate declaration. - - Raw context pointer for the user function - - - - Internal callback delegate for implementing collation sequences - - Not used - Length of the string pv1 - Pointer to the first string to compare - Length of the string pv2 - Pointer to the second string to compare - Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - than the second. - - - - The type of collating sequence - - - - - The built-in BINARY collating sequence - - - - - The built-in NOCASE collating sequence - - - - - The built-in REVERSE collating sequence - - - - - A custom user-defined collating sequence - - - - - The encoding type the collation sequence uses - - - - - The collation sequence is UTF8 - - - - - The collation sequence is UTF16 little-endian - - - - - The collation sequence is UTF16 big-endian - - - - - A struct describing the collating sequence a function is executing in - - - - - The name of the collating sequence - - - - - The type of collating sequence - - - - - The text encoding of the collation sequence - - - - - Context of the function that requested the collating sequence - - - - - Calls the base collating sequence to compare two strings - - The first string to compare - The second string to compare - -1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2 - - - - Calls the base collating sequence to compare two character arrays - - The first array to compare - The second array to compare - -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 - - - - A simple custom attribute to enable us to easily find user-defined functions in - the loaded assemblies and initialize them in SQLite as connections are made. - - - - - Default constructor, initializes the internal variables for the function. - - - - - Constructs an instance of this class. - - - The name of the function, as seen by the SQLite core library. - - - The number of arguments that the function will accept. - - - The type of function being declared. This will either be Scalar, - Aggregate, or Collation. - - - - - The function's name as it will be used in SQLite command text. - - - - - The number of arguments this function expects. -1 if the number of arguments is variable. - - - - - The type of function this implementation will be. - - - - - The object instance that describes the class - containing the implementation for the associated function. - - - - - This class provides key info for a given SQLite statement. - - Providing key information for a given statement is non-trivial :( - - - - - - This function does all the nasty work at determining what keys need to be returned for - a given statement. - - - - - - - - Make sure all the subqueries are open and ready and sync'd with the current rowid - of the table they're supporting - - - - - Release any readers on any subqueries - - - - - Append all the columns we've added to the original query to the schema - - - - - - How many additional columns of keyinfo we're holding - - - - - Used to support CommandBehavior.KeyInfo - - - - - A single sub-query for a given table/database. - - - - - Event data for logging event handlers. - - - - - The error code. The type of this object value should be - or . - - - - - SQL statement text as the statement first begins executing - - - - - Extra data associated with this event, if any. - - - - - Constructs the object. - - Should be null. - - The error code. The type of this object value should be - or . - - The error message, if any. - The extra data, if any. - - - - Raised when a log event occurs. - - The current connection - Event arguments of the trace - - - - Manages the SQLite custom logging functionality and the associated - callback for the whole process. - - - - - Object used to synchronize access to the static instance data - for this class. - - - - - Member variable to store the AppDomain.DomainUnload event handler. - - - - - The default log event handler. - - - - - The log callback passed to native SQLite engine. This must live - as long as the SQLite library has a pointer to it. - - - - - The base SQLite object to interop with. - - - - - This will be non-zero if logging is currently enabled. - - - - - Initializes the SQLite logging facilities. - - - - - Handles the AppDomain being unloaded. - - Should be null. - The data associated with this event. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The SQLite error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - The integer error code. - The message to be logged. - - - - Log a message to all the registered log event handlers without going - through the SQLite library. - - - The error code. The type of this object value should be - System.Int32 or SQLiteErrorCode. - - The message to be logged. - - - - Creates and initializes the default log event handler. - - - - - Adds the default log event handler to the list of handlers. - - - - - Removes the default log event handler from the list of handlers. - - - - - Internal proxy function that calls any registered application log - event handlers. - - WARNING: This method is used more-or-less directly by native code, - do not modify its type signature. - - - The extra data associated with this message, if any. - - - The error code associated with this message. - - - The message string to be logged. - - - - - Default logger. Currently, uses the Trace class (i.e. sends events - to the current trace listeners, if any). - - Should be null. - The data associated with this event. - - - - Member variable to store the application log handler to call. - - - - - This event is raised whenever SQLite raises a logging event. - Note that this should be set as one of the first things in the - application. - - - - - If this property is true, logging is enabled; otherwise, logging is - disabled. When logging is disabled, no logging events will fire. - - - - - MetaDataCollections specific to SQLite - - - - - Returns a list of databases attached to the connection - - - - - Returns column information for the specified table - - - - - Returns index information for the optionally-specified table - - - - - Returns base columns for the given index - - - - - Returns the tables in the given catalog - - - - - Returns user-defined views in the given catalog - - - - - Returns underlying column information on the given view - - - - - Returns foreign key information for the given catalog - - - - - Returns the triggers on the database - - - - - SQLite implementation of DbParameter. - - - - - The data type of the parameter - - - - - The version information for mapping the parameter - - - - - The value of the data in the parameter - - - - - The source column for the parameter - - - - - The column name - - - - - The data size, unused by SQLite - - - - - Default constructor - - - - - Constructs a named parameter given the specified parameter name - - The parameter name - - - - Constructs a named parameter given the specified parameter name and initial value - - The parameter name - The initial value of the parameter - - - - Constructs a named parameter of the specified type - - The parameter name - The datatype of the parameter - - - - Constructs a named parameter of the specified type and source column reference - - The parameter name - The data type - The source column - - - - Constructs a named parameter of the specified type, source column and row version - - The parameter name - The data type - The source column - The row version information - - - - Constructs an unnamed parameter of the specified data type - - The datatype of the parameter - - - - Constructs an unnamed parameter of the specified data type and sets the initial value - - The datatype of the parameter - The initial value of the parameter - - - - Constructs an unnamed parameter of the specified data type and source column - - The datatype of the parameter - The source column - - - - Constructs an unnamed parameter of the specified data type, source column and row version - - The data type - The source column - The row version information - - - - Constructs a named parameter of the specified type and size - - The parameter name - The data type - The size of the parameter - - - - Constructs a named parameter of the specified type, size and source column - - The name of the parameter - The data type - The size of the parameter - The source column - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - The source column - The row version information - - - - Constructs a named parameter of the specified type, size, source column and row version - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - Ignored - The source column - The row version information - The initial value to assign the parameter - - - - Constructs a named parameter, yet another flavor - - The name of the parameter - The data type - The size of the parameter - Only input parameters are supported in SQLite - Ignored - Ignored - The source column - The row version information - Whether or not this parameter is for comparing NULL's - The intial value to assign the parameter - - - - Constructs an unnamed parameter of the specified type and size - - The data type - The size of the parameter - - - - Constructs an unnamed parameter of the specified type, size, and source column - - The data type - The size of the parameter - The source column - - - - Constructs an unnamed parameter of the specified type, size, source column and row version - - The data type - The size of the parameter - The source column - The row version information - - - - Resets the DbType of the parameter so it can be inferred from the value - - - - - Clones a parameter - - A new, unassociated SQLiteParameter - - - - Whether or not the parameter can contain a null value - - - - - Returns the datatype of the parameter - - - - - Supports only input parameters - - - - - Returns the parameter name - - - - - Returns the size of the parameter - - - - - Gets/sets the source column - - - - - Used by DbCommandBuilder to determine the mapping for nullable fields - - - - - Gets and sets the row version - - - - - Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. - - - - - SQLite implementation of DbParameterCollection. - - - - - The underlying command to which this collection belongs - - - - - The internal array of parameters in this collection - - - - - Determines whether or not all parameters have been bound to their statement(s) - - - - - Initializes the collection - - The command to which the collection belongs - - - - Retrieves an enumerator for the collection - - An enumerator for the underlying array - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - The source column - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - The size of the value - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter name - The data type - A SQLiteParameter object - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a parameter to the collection - - The parameter to add - A zero-based index of where the parameter is located in the array - - - - Adds a named/unnamed parameter and its value to the parameter collection. - - Name of the parameter, or null to indicate an unnamed parameter - The initial value of the parameter - Returns the SQLiteParameter object created during the call. - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Adds an array of parameters to the collection - - The array of parameters to add - - - - Clears the array and resets the collection - - - - - Determines if the named parameter exists in the collection - - The name of the parameter to check - True if the parameter is in the collection - - - - Determines if the parameter exists in the collection - - The SQLiteParameter to check - True if the parameter is in the collection - - - - Not implemented - - - - - - - Retrieve a parameter by name from the collection - - The name of the parameter to fetch - A DbParameter object - - - - Retrieves a parameter by its index in the collection - - The index of the parameter to retrieve - A DbParameter object - - - - Returns the index of a parameter given its name - - The name of the parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Returns the index of a parameter - - The parameter to find - -1 if not found, otherwise a zero-based index of the parameter - - - - Inserts a parameter into the array at the specified location - - The zero-based index to insert the parameter at - The parameter to insert - - - - Removes a parameter from the collection - - The parameter to remove - - - - Removes a parameter from the collection given its name - - The name of the parameter to remove - - - - Removes a parameter from the collection given its index - - The zero-based parameter index to remove - - - - Re-assign the named parameter to a new parameter object - - The name of the parameter to replace - The new parameter - - - - Re-assign a parameter at the specified index - - The zero-based index of the parameter to replace - The new parameter - - - - Un-binds all parameters from their statements - - - - - This function attempts to map all parameters in the collection to all statements in a Command. - Since named parameters may span multiple statements, this function makes sure all statements are bound - to the same named parameter. Unnamed parameters are bound in sequence. - - - - - Returns false - - - - - Returns false - - - - - Returns false - - - - - Returns null - - - - - Returns a count of parameters in the collection - - - - - Overloaded to specialize the return value of the default indexer - - Name of the parameter to get/set - The specified named SQLite parameter - - - - Overloaded to specialize the return value of the default indexer - - The index of the parameter to get/set - The specified SQLite parameter - - - - Represents a single SQL statement in SQLite. - - - - - The underlying SQLite object this statement is bound to - - - - - The command text of this SQL statement - - - - - The actual statement pointer - - - - - An index from which unnamed parameters begin - - - - - Names of the parameters as SQLite understands them to be - - - - - Parameters for this statement - - - - - Command this statement belongs to (if any) - - - - - The flags associated with the parent connection object. - - - - - Initializes the statement and attempts to get all information about parameters in the statement - - The base SQLite object - The flags associated with the parent connection object - The statement - The command text for this statement - The previous command in a multi-statement command - - - - Disposes and finalizes the statement - - - - - If the underlying database connection is open, fetches the number of changed rows - resulting from the most recent query; otherwise, does nothing. - - - The number of changes when true is returned. - Undefined if false is returned. - - Non-zero if the number of changed rows was fetched. - - - - Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to - this statement, and if so, keeps a reference to the parameter so it can be bound later. - - The parameter name to map - The parameter to assign it - - - - Bind all parameters, making sure the caller didn't miss any - - - - - Attempts to convert an arbitrary object to the Boolean data type. - Null object values are converted to false. Throws a SQLiteException - upon failure. - - The object value to convert. - The format provider to use. - The converted boolean value. - - - - Perform the bind operation for an individual parameter - - The index of the parameter to bind - The parameter we're binding - - - - SQLite implementation of DbTransaction. - - - - - The connection to which this transaction is bound - - - - - Constructs the transaction object, binding it to the supplied connection - - The connection to open a transaction on - TRUE to defer the writelock, or FALSE to lock immediately - - - - Disposes the transaction. If it is currently active, any changes are rolled back. - - - - - Commits the current transaction. - - - - - Rolls back the active transaction. - - - - - Returns the underlying connection to which this transaction applies. - - - - - Forwards to the local Connection property - - - - - Gets the isolation level of the transaction. SQLite only supports Serializable transactions. - - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - - Returns the cached ResourceManager instance used by this class. - - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - - Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> - <DocumentElement> - <DataTypes> - <TypeName>smallint</TypeName> - <ProviderDbType>10</ProviderDbType> - <ColumnSize>5</ColumnSize> - <DataType>System.Int16</DataType> - <CreateFormat>smallint</CreateFormat> - <IsAutoIncrementable>false</IsAutoIncrementable> - <IsCaseSensitive>false</IsCaseSensitive> - <IsFixedLength>true</IsFixedLength> - <IsFixedPrecisionScale>true</IsFixedPrecisionScale> - <IsLong>false</IsLong> - <IsNullable>true</ [rest of string was truncated]";. - - - - - Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. - - - - - Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> - <DocumentElement> - <MetaDataCollections> - <CollectionName>MetaDataCollections</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataCollections> - <CollectionName>DataSourceInformation</CollectionName> - <NumberOfRestrictions>0</NumberOfRestrictions> - <NumberOfIdentifierParts>0</NumberOfIdentifierParts> - </MetaDataCollections> - <MetaDataC [rest of string was truncated]";. - - - - - The file extension used for dynamic link libraries. - - - - - The file extension used for the XML configuration file. - - - - - This is the name of the XML configuration file specific to the - System.Data.SQLite assembly. - - - - - This lock is used to protect the static _SQLiteNativeModuleFileName, - _SQLiteNativeModuleHandle, and processorArchitecturePlatforms fields. - - - - - This dictionary stores the mappings between processor architecture - names and platform names. These mappings are now used for two - purposes. First, they are used to determine if the assembly code - base should be used instead of the location, based upon whether one - or more of the named sub-directories exist within the assembly code - base. Second, they are used to assist in loading the appropriate - SQLite interop assembly into the current process. - - - - - For now, this method simply calls the Initialize method. - - - - - Attempts to initialize this class by pre-loading the native SQLite - library for the processor architecture of the current process. - - - - - Queries and returns the XML configuration file name for the assembly - containing the managed System.Data.SQLite components. - - - The XML configuration file name -OR- null if it cannot be determined - or does not exist. - - - - - Queries and returns the value of the specified setting, using the XML - configuration file and/or the environment variables for the current - process and/or the current system, when available. - - - The name of the setting. - - - The value to be returned if the setting has not been set explicitly - or cannot be determined. - - - The value of the setting -OR- the default value specified by - if it has not been set explicitly or - cannot be determined. By default, all references to existing - environment variables will be expanded to their corresponding values - within the value to be returned unless either the "No_Expand" or - "No_Expand_" environment variable is set [to - anything]. - - - - - Queries and returns the directory for the assembly currently being - executed. - - - The directory for the assembly currently being executed -OR- null if - it cannot be determined. - - - - - The name of the environment variable containing the processor - architecture of the current process. - - - - - This is the P/Invoke method that wraps the native Win32 LoadLibrary - function. See the MSDN documentation for full details on what it - does. - - - The name of the executable library. - - - The native module handle upon success -OR- IntPtr.Zero on failure. - - - - - The native module file name for the native SQLite library or null. - - - - - The native module handle for the native SQLite library or the value - IntPtr.Zero. - - - - - Searches for the native SQLite library in the directory containing - the assembly currently being executed as well as the base directory - for the current application domain. - - - Upon success, this parameter will be modified to refer to the base - directory containing the native SQLite library. - - - Upon success, this parameter will be modified to refer to the name - of the immediate directory (i.e. the offset from the base directory) - containing the native SQLite library. - - - Non-zero (success) if the native SQLite library was found; otherwise, - zero (failure). - - - - - Queries and returns the base directory of the current application - domain. - - - The base directory for the current application domain -OR- null if it - cannot be determined. - - - - - Determines if the dynamic link library file name requires a suffix - and adds it if necessary. - - - The original dynamic link library file name to inspect. - - - The dynamic link library file name, possibly modified to include an - extension. - - - - - Queries and returns the processor architecture of the current - process. - - - The processor architecture of the current process -OR- null if it - cannot be determined. - - - - - Given the processor architecture, returns the name of the platform. - - - The processor architecture to be translated to a platform name. - - - The platform name for the specified processor architecture -OR- null - if it cannot be determined. - - - - - Attempts to load the native SQLite library based on the specified - directory and processor architecture. - - - The base directory to use, null for default (the base directory of - the current application domain). This directory should contain the - processor architecture specific sub-directories. - - - The requested processor architecture, null for default (the - processor architecture of the current process). This caller should - almost always specify null for this parameter. - - - The candidate native module file name to load will be stored here, - if necessary. - - - The native module handle as returned by LoadLibrary will be stored - here, if necessary. This value will be IntPtr.Zero if the call to - LoadLibrary fails. - - - Non-zero if the native module was loaded successfully; otherwise, - zero. - - - - - This class represents a context from the SQLite core library that can - be passed to the sqlite3_result_*() and associated functions. - - - - - This interface represents a native handle provided by the SQLite core - library. - - - - - The native handle value. - - - - - The native context handle. - - - - - Constructs an instance of this class using the specified native - context handle. - - - The native context handle to use. - - - - - Sets the context result to NULL. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to the specified - value. - - - The value to use. This value will be - converted to the UTF-8 encoding prior to being used. - - - - - Sets the context result to the specified - value containing an error message. - - - The value containing the error message text. - This value will be converted to the UTF-8 encoding prior to being - used. - - - - - Sets the context result to the specified - value. - - - The value to use. - - - - - Sets the context result to contain the error code SQLITE_TOOBIG. - - - - - Sets the context result to contain the error code SQLITE_NOMEM. - - - - - Sets the context result to the specified array - value. - - - The array value to use. - - - - - Sets the context result to a BLOB of zeros of the specified size. - - - The number of zero bytes to use for the BLOB context result. - - - - - Sets the context result to the specified . - - - The to use. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a value from the SQLite core library that can be - passed to the sqlite3_value_*() and associated functions. - - - - - The native value handle. - - - - - Constructs an instance of this class using the specified native - value handle. - - - The native value handle to use. - - - - - Invalidates the native value handle, thereby preventing further - access to it from this object instance. - - - - - Converts a logical array of native pointers to native sqlite3_value - structures into a managed array of - object instances. - - - The number of elements in the logical array of native sqlite3_value - structures. - - - The native pointer to the logical array of native sqlite3_value - structures to convert. - - - The managed array of object instances or - null upon failure. - - - - - Gets and returns the type affinity associated with this value. - - - The type affinity associated with this value. - - - - - Gets and returns the number of bytes associated with this value, if - it refers to a UTF-8 encoded string. - - - The number of bytes associated with this value. The returned value - may be zero. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with - this value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. - - - - - Gets and returns the associated with this - value. - - - The associated with this value. The value is - converted from the UTF-8 encoding prior to being returned. - - - - - Gets and returns the array associated with this - value. - - - The array associated with this value. - - - - - Uses the native value handle to obtain and store the managed value - for this object instance, thus saving it for later use. The type - of the managed value is determined by the type affinity of the - native value. If the type affinity is not recognized by this - method, no work is done and false is returned. - - - Non-zero if the native value was persisted successfully. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - Returns non-zero if the native SQLite value has been successfully - persisted as a managed value within this object instance (i.e. the - property may then be read successfully). - - - - - If the managed value for this object instance is available (i.e. it - has been previously persisted via the ) method, - that value is returned; otherwise, an exception is thrown. The - returned value may be null. - - - - - These are the allowed values for the operators that are part of a - constraint term in the WHERE clause of a query that uses a virtual - table. - - - - - This value represents the equality operator. - - - - - This value represents the greater than operator. - - - - - This value represents the less than or equal to operator. - - - - - This value represents the less than operator. - - - - - This value represents the greater than or equal to operator. - - - - - This value represents the MATCH operator. - - - - - This class represents the native sqlite3_index_constraint structure - from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint structure. - - - The native sqlite3_index_constraint structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column on left-hand side of constraint. - - - Constraint operator (). - - - True if this constraint is usable. - - - Used internally - - should ignore. - - - - - Column on left-hand side of constraint. - - - - - Constraint operator (). - - - - - True if this constraint is usable. - - - - - Used internally - - should ignore. - - - - - This class represents the native sqlite3_index_orderby structure from - the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_orderby structure. - - - The native sqlite3_index_orderby structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - Column number. - - - True for DESC. False for ASC. - - - - - Column number. - - - - - True for DESC. False for ASC. - - - - - This class represents the native sqlite3_index_constraint_usage - structure from the SQLite core library. - - - - - Constructs an instance of this class using the specified native - sqlite3_index_constraint_usage structure. - - - The native sqlite3_index_constraint_usage structure to use. - - - - - Constructs an instance of this class using the specified field - values. - - - If greater than 0, constraint is part of argv to xFilter. - - - Do not code a test for this constraint. - - - - - If greater than 0, constraint is part of argv to xFilter. - - - - - Do not code a test for this constraint. - - - - - This class represents the various inputs provided by the SQLite core - library to the method. - - - - - Constructs an instance of this class. - - - The number of instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - An array of object instances, - each containing information supplied by the SQLite core library. - - - - - This class represents the various outputs provided to the SQLite core - library by the method. - - - - - Constructs an instance of this class. - - - The number of instances - to pre-allocate space for. - - - - - Determines if the native estimatedRows field can be used, based on - the available version of the SQLite core library. - - - Non-zero if the property is supported - by the SQLite core library. - - - - - An array of object - instances, each containing information to be supplied to the SQLite - core library. - - - - - Number used to help identify the selected index. This value will - later be provided to the - method. - - - - - String used to help identify the selected index. This value will - later be provided to the - method. - - - - - Non-zero if the index string must be freed by the SQLite core - library. - - - - - True if output is already ordered. - - - - - Estimated cost of using this index. Using a null value here - indicates that a default estimated cost value should be used. - - - - - Estimated number of rows returned. Using a null value here - indicates that a default estimated rows value should be used. - - - - - This class represents the various inputs and outputs used with the - method. - - - - - Constructs an instance of this class. - - - The number of (and - ) instances to - pre-allocate space for. - - - The number of instances to - pre-allocate space for. - - - - - Converts a native pointer to a native sqlite3_index_info structure - into a new object instance. - - - The native pointer to the native sqlite3_index_info structure to - convert. - - - Upon success, this parameter will be modified to contain the newly - created object instance. - - - - - Populates the outputs of a pre-allocated native sqlite3_index_info - structure using an existing object - instance. - - - The existing object instance containing - the output data to use. - - - The native pointer to the pre-allocated native sqlite3_index_info - structure. - - - - - The object instance containing - the inputs to the - method. - - - - - The object instance containing - the outputs from the - method. - - - - - This class represents a managed virtual table implementation. It is - not sealed and should be used as the base class for any user-defined - virtual table classes implemented in managed code. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the module implementing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the database containing this virtual table. - - - - - The index within the array of strings provided to the - and - methods containing the - name of the virtual table. - - - - - Constructs an instance of this class. - - - The original array of strings provided to the - and - methods. - - - - - This method should normally be used by the - method in order to - perform index selection based on the constraints provided by the - SQLite core library. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - Non-zero upon success. - - - - - Attempts to record the renaming of the virtual table associated - with this object instance. - - - The new name for the virtual table. - - - Non-zero upon success. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The original array of strings provided to the - and - methods. - - - - - The name of the module implementing this virtual table. - - - - - The name of the database containing this virtual table. - - - - - The name of the virtual table. - - - - - The object instance containing all the - data for the inputs and outputs relating to the most recent index - selection. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This class represents a managed virtual table cursor implementation. - It is not sealed and should be used as the base class for any - user-defined virtual table cursor classes implemented in managed code. - - - - - This value represents an invalid integer row sequence number. - - - - - The field holds the integer row sequence number for the current row - pointed to by this cursor object instance. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - - - Constructs an instance of this class. - - - - - Attempts to persist the specified object - instances in order to make them available after the - method returns. - - - The array of object instances to be - persisted. - - - The number of object instances that were - successfully persisted. - - - - - This method should normally be used by the - method in order to - perform filtering of the result rows and/or to record the filtering - criteria provided by the SQLite core library. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - - - Determines the integer row sequence number for the current row. - - - The integer row sequence number for the current row -OR- zero if - it cannot be determined. - - - - - Adjusts the integer row sequence number so that it refers to the - next row. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being called - from the finalizer. - - - - - Finalizes this object instance. - - - - - The object instance associated - with this object instance. - - - - - Number used to help identify the selected index. This value will - be set via the method. - - - - - String used to help identify the selected index. This value will - be set via the method. - - - - - The values used to filter the rows returned via this cursor object - instance. This value will be set via the - method. - - - - - Returns the underlying SQLite native handle associated with this - object instance. - - - - - This interface represents a virtual table implementation written in - native code. - - - - - - This method is called to create a new instance of a virtual table - in response to a CREATE VIRTUAL TABLE statement. The db parameter - is a pointer to the SQLite database connection that is executing - the CREATE VIRTUAL TABLE statement. The pAux argument is the copy - of the client data pointer that was the fourth argument to the - sqlite3_create_module() or sqlite3_create_module_v2() call that - registered the virtual table module. The argv parameter is an - array of argc pointers to null terminated strings. The first - string, argv[0], is the name of the module being invoked. The - module name is the name provided as the second argument to - sqlite3_create_module() and as the argument to the USING clause of - the CREATE VIRTUAL TABLE statement that is running. The second, - argv[1], is the name of the database in which the new virtual table - is being created. The database name is "main" for the primary - database, or "temp" for TEMP database, or the name given at the - end of the ATTACH statement for attached databases. The third - element of the array, argv[2], is the name of the new virtual - table, as specified following the TABLE keyword in the CREATE - VIRTUAL TABLE statement. If present, the fourth and subsequent - strings in the argv[] array report the arguments to the module name - in the CREATE VIRTUAL TABLE statement. - - - The job of this method is to construct the new virtual table object - (an sqlite3_vtab object) and return a pointer to it in *ppVTab. - - - As part of the task of creating a new sqlite3_vtab structure, this - method must invoke sqlite3_declare_vtab() to tell the SQLite core - about the columns and datatypes in the virtual table. The - sqlite3_declare_vtab() API has the following prototype: - - - - int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) - - - - The first argument to sqlite3_declare_vtab() must be the same - database connection pointer as the first parameter to this method. - The second argument to sqlite3_declare_vtab() must a - zero-terminated UTF-8 string that contains a well-formed CREATE - TABLE statement that defines the columns in the virtual table and - their data types. The name of the table in this CREATE TABLE - statement is ignored, as are all constraints. Only the column names - and datatypes matter. The CREATE TABLE statement string need not to - be held in persistent memory. The string can be deallocated and/or - reused as soon as the sqlite3_declare_vtab() routine returns. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - The xConnect method is very similar to xCreate. It has the same - parameters and constructs a new sqlite3_vtab structure just like - xCreate. And it must also call sqlite3_declare_vtab() like xCreate. - - - The difference is that xConnect is called to establish a new - connection to an existing virtual table whereas xCreate is called - to create a new virtual table from scratch. - - - The xCreate and xConnect methods are only different when the - virtual table has some kind of backing store that must be - initialized the first time the virtual table is created. The - xCreate method creates and initializes the backing store. The - xConnect method just connects to an existing backing store. - - - As an example, consider a virtual table implementation that - provides read-only access to existing comma-separated-value (CSV) - files on disk. There is no backing store that needs to be created - or initialized for such a virtual table (since the CSV files - already exist on disk) so the xCreate and xConnect methods will be - identical for that module. - - - Another example is a virtual table that implements a full-text - index. The xCreate method must create and initialize data - structures to hold the dictionary and posting lists for that index. - The xConnect method, on the other hand, only has to locate and use - an existing dictionary and posting lists that were created by a - prior xCreate call. - - - The xConnect method must return SQLITE_OK if it is successful in - creating the new virtual table, or SQLITE_ERROR if it is not - successful. If not successful, the sqlite3_vtab structure must not - be allocated. An error message may optionally be returned in *pzErr - if unsuccessful. Space to hold the error message string must be - allocated using an SQLite memory allocation function like - sqlite3_malloc() or sqlite3_mprintf() as the SQLite core will - attempt to free the space using sqlite3_free() after the error has - been reported up to the application. - - - The xConnect method is required for every virtual table - implementation, though the xCreate and xConnect pointers of the - sqlite3_module object may point to the same function the virtual - table does not need to initialize backing store. - - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - - SQLite uses the xBestIndex method of a virtual table module to - determine the best way to access the virtual table. The xBestIndex - method has a prototype like this: - - - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - - - The SQLite core communicates with the xBestIndex method by filling - in certain fields of the sqlite3_index_info structure and passing a - pointer to that structure into xBestIndex as the second parameter. - The xBestIndex method fills out other fields of this structure - which forms the reply. The sqlite3_index_info structure looks like - this: - - - struct sqlite3_index_info { - /* Inputs */ - const int nConstraint; /* Number of entries in aConstraint */ - const struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of - * constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should - * ignore */ - } *const aConstraint; /* Table of WHERE clause constraints */ - const int nOrderBy; /* Number of terms in the ORDER BY - * clause */ - const struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *const aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if greater than zero, constraint is - * part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this - * constraint */ - } *const aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from - * sqlite3_malloc() */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if - * true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - }; - - - In addition, there are some defined constants: - - - #define SQLITE_INDEX_CONSTRAINT_EQ 2 - #define SQLITE_INDEX_CONSTRAINT_GT 4 - #define SQLITE_INDEX_CONSTRAINT_LE 8 - #define SQLITE_INDEX_CONSTRAINT_LT 16 - #define SQLITE_INDEX_CONSTRAINT_GE 32 - #define SQLITE_INDEX_CONSTRAINT_MATCH 64 - - - The SQLite core calls the xBestIndex method when it is compiling a - query that involves a virtual table. In other words, SQLite calls - this method when it is running sqlite3_prepare() or the equivalent. - By calling this method, the SQLite core is saying to the virtual - table that it needs to access some subset of the rows in the - virtual table and it wants to know the most efficient way to do - that access. The xBestIndex method replies with information that - the SQLite core can then use to conduct an efficient search of the - virtual table. - - - While compiling a single SQL query, the SQLite core might call - xBestIndex multiple times with different settings in - sqlite3_index_info. The SQLite core will then select the - combination that appears to give the best performance. - - - Before calling this method, the SQLite core initializes an instance - of the sqlite3_index_info structure with information about the - query that it is currently trying to process. This information - derives mainly from the WHERE clause and ORDER BY or GROUP BY - clauses of the query, but also from any ON or USING clauses if the - query is a join. The information that the SQLite core provides to - the xBestIndex method is held in the part of the structure that is - marked as "Inputs". The "Outputs" section is initialized to zero. - - - The information in the sqlite3_index_info structure is ephemeral - and may be overwritten or deallocated as soon as the xBestIndex - method returns. If the xBestIndex method needs to remember any part - of the sqlite3_index_info structure, it should make a copy. Care - must be take to store the copy in a place where it will be - deallocated, such as in the idxStr field with needToFreeIdxStr set - to 1. - - - Note that xBestIndex will always be called before xFilter, since - the idxNum and idxStr outputs from xBestIndex are required inputs - to xFilter. However, there is no guarantee that xFilter will be - called following a successful xBestIndex. - - - The xBestIndex method is required for every virtual table - implementation. - - - 2.3.1 Inputs - - - The main thing that the SQLite core is trying to communicate to the - virtual table is the constraints that are available to limit the - number of rows that need to be searched. The aConstraint[] array - contains one entry for each constraint. There will be exactly - nConstraint entries in that array. - - - Each constraint will correspond to a term in the WHERE clause or in - a USING or ON clause that is of the form - - - column OP EXPR - - - Where "column" is a column in the virtual table, OP is an operator - like "=" or "<", and EXPR is an arbitrary expression. So, for - example, if the WHERE clause contained a term like this: - - - a = 5 - - - Then one of the constraints would be on the "a" column with - operator "=" and an expression of "5". Constraints need not have a - literal representation of the WHERE clause. The query optimizer - might make transformations to the WHERE clause in order to extract - as many constraints as it can. So, for example, if the WHERE clause - contained something like this: - - - x BETWEEN 10 AND 100 AND 999>y - - - The query optimizer might translate this into three separate - constraints: - - - x >= 10 - x <= 100 - y < 999 - - - For each constraint, the aConstraint[].iColumn field indicates - which column appears on the left-hand side of the constraint. The - first column of the virtual table is column 0. The rowid of the - virtual table is column -1. The aConstraint[].op field indicates - which operator is used. The SQLITE_INDEX_CONSTRAINT_* constants map - integer constants into operator values. Columns occur in the order - they were defined by the call to sqlite3_declare_vtab() in the - xCreate or xConnect method. Hidden columns are counted when - determining the column index. - - - The aConstraint[] array contains information about all constraints - that apply to the virtual table. But some of the constraints might - not be usable because of the way tables are ordered in a join. The - xBestIndex method must therefore only consider constraints that - have an aConstraint[].usable flag which is true. - - - In addition to WHERE clause constraints, the SQLite core also tells - the xBestIndex method about the ORDER BY clause. (In an aggregate - query, the SQLite core might put in GROUP BY clause information in - place of the ORDER BY clause information, but this fact should not - make any difference to the xBestIndex method.) If all terms of the - ORDER BY clause are columns in the virtual table, then nOrderBy - will be the number of terms in the ORDER BY clause and the - aOrderBy[] array will identify the column for each term in the - order by clause and whether or not that column is ASC or DESC. - - - 2.3.2 Outputs - - - Given all of the information above, the job of the xBestIndex - method it to figure out the best way to search the virtual table. - - - The xBestIndex method fills the idxNum and idxStr fields with - information that communicates an indexing strategy to the xFilter - method. The information in idxNum and idxStr is arbitrary as far as - the SQLite core is concerned. The SQLite core just copies the - information through to the xFilter method. Any desired meaning can - be assigned to idxNum and idxStr as long as xBestIndex and xFilter - agree on what that meaning is. - - - The idxStr value may be a string obtained from an SQLite memory - allocation function such as sqlite3_mprintf(). If this is the case, - then the needToFreeIdxStr flag must be set to true so that the - SQLite core will know to call sqlite3_free() on that string when it - has finished with it, and thus avoid a memory leak. - - - If the virtual table will output rows in the order specified by the - ORDER BY clause, then the orderByConsumed flag may be set to true. - If the output is not automatically in the correct order then - orderByConsumed must be left in its default false setting. This - will indicate to the SQLite core that it will need to do a separate - sorting pass over the data after it comes out of the virtual table. - - - The estimatedCost field should be set to the estimated number of - disk access operations required to execute this query against the - virtual table. The SQLite core will often call xBestIndex multiple - times with different constraints, obtain multiple cost estimates, - then choose the query plan that gives the lowest estimate. - - - The aConstraintUsage[] array contains one element for each of the - nConstraint constraints in the inputs section of the - sqlite3_index_info structure. The aConstraintUsage[] array is used - by xBestIndex to tell the core how it is using the constraints. - - - The xBestIndex method may set aConstraintUsage[].argvIndex entries - to values greater than one. Exactly one entry should be set to 1, - another to 2, another to 3, and so forth up to as many or as few as - the xBestIndex method wants. The EXPR of the corresponding - constraints will then be passed in as the argv[] parameters to - xFilter. - - - For example, if the aConstraint[3].argvIndex is set to 1, then when - xFilter is called, the argv[0] passed to xFilter will have the EXPR - value of the aConstraint[3] constraint. - - - By default, the SQLite core double checks all constraints on each - row of the virtual table that it receives. If such a check is - redundant, the xBestFilter method can suppress that double-check by - setting aConstraintUsage[].omit. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_index_info structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table. Only the - sqlite3_vtab object is destroyed. The virtual table is not - destroyed and any backing store associated with the virtual table - persists. This method undoes the work of xConnect. - - - This method is a destructor for a connection to the virtual table. - Contrast this method with xDestroy. The xDestroy is a destructor - for the entire virtual table. - - - The xDisconnect method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method releases a connection to a virtual table, just like the - xDisconnect method, and it also destroys the underlying table - implementation. This method undoes the work of xCreate. - - - The xDisconnect method is called whenever a database connection - that uses a virtual table is closed. The xDestroy method is only - called when a DROP TABLE statement is executed against the virtual - table. - - - The xDestroy method is required for every virtual table - implementation, though it is acceptable for the xDisconnect and - xDestroy methods to be the same function if that makes sense for - the particular virtual table. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - The xOpen method creates a new cursor used for accessing (read - and/or writing) a virtual table. A successful invocation of this - method will allocate the memory for the sqlite3_vtab_cursor (or a - subclass), initialize the new object, and make *ppCursor point to - the new object. The successful call then returns SQLITE_OK. - - - For every successful call to this method, the SQLite core will - later invoke the xClose method to destroy the allocated cursor. - - - The xOpen method need not initialize the pVtab field of the - sqlite3_vtab_cursor structure. The SQLite core will take care of - that chore automatically. - - - A virtual table implementation must be able to support an arbitrary - number of simultaneously open cursors. - - - When initially opened, the cursor is in an undefined state. The - SQLite core will invoke the xFilter method on the cursor prior to - any attempt to position or read from the cursor. - - - The xOpen method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xClose method closes a cursor previously opened by xOpen. The - SQLite core will always call xClose once for each cursor opened - using xOpen. - - - This method must release all resources allocated by the - corresponding xOpen call. The routine will not be called again even - if it returns an error. The SQLite core will not use the - sqlite3_vtab_cursor again after it has been closed. - - - The xClose method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - This method begins a search of a virtual table. The first argument - is a cursor opened by xOpen. The next two argument define a - particular search index previously chosen by xBestIndex. The - specific meanings of idxNum and idxStr are unimportant as long as - xFilter and xBestIndex agree on what that meaning is. - - - The xBestIndex function may have requested the values of certain - expressions using the aConstraintUsage[].argvIndex values of the - sqlite3_index_info structure. Those values are passed to xFilter - using the argc and argv parameters. - - - If the virtual table contains one or more rows that match the - search criteria, then the cursor must be left point at the first - row. Subsequent calls to xEof must return false (zero). If there - are no rows match, then the cursor must be left in a state that - will cause the xEof to return true (non-zero). The SQLite engine - will use the xColumn and xRowid methods to access that row content. - The xNext method will be used to advance to the next row. - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xFilter method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Number used to help identify the selected index. - - - The native pointer to the UTF-8 encoded string containing the - string used to help identify the selected index. - - - The number of native pointers to sqlite3_value structures specified - in . - - - An array of native pointers to sqlite3_value structures containing - filtering criteria for the selected index. - - - A standard SQLite return code. - - - - - - The xNext method advances a virtual table cursor to the next row of - a result set initiated by xFilter. If the cursor is already - pointing at the last row when this routine is called, then the - cursor no longer points to valid data and a subsequent call to the - xEof method must return true (non-zero). If the cursor is - successfully advanced to another row of content, then subsequent - calls to xEof must return false (zero). - - - This method must return SQLITE_OK if successful, or an sqlite error - code if an error occurs. - - - The xNext method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - A standard SQLite return code. - - - - - - The xEof method must return false (zero) if the specified cursor - currently points to a valid row of data, or true (non-zero) - otherwise. This method is called by the SQL engine immediately - after each xFilter and xNext invocation. - - - The xEof method is required for every virtual table implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Non-zero if no more rows are available; zero otherwise. - - - - - - The SQLite core invokes this method in order to find the value for - the N-th column of the current row. N is zero-based so the first - column is numbered 0. The xColumn method may return its result back - to SQLite using one of the following interface: - - - sqlite3_result_blob() - sqlite3_result_double() - sqlite3_result_int() - sqlite3_result_int64() - sqlite3_result_null() - sqlite3_result_text() - sqlite3_result_text16() - sqlite3_result_text16le() - sqlite3_result_text16be() - sqlite3_result_zeroblob() - - - If the xColumn method implementation calls none of the functions - above, then the value of the column defaults to an SQL NULL. - - - To raise an error, the xColumn method should use one of the - result_text() methods to set the error message text, then return an - appropriate error code. The xColumn method must return SQLITE_OK on - success. - - - The xColumn method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_context structure to be used - for returning the specified column value to the SQLite core - library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - - A successful invocation of this method will cause *pRowid to be - filled with the rowid of row that the virtual table cursor pCur is - currently pointing at. This method returns SQLITE_OK on success. It - returns an appropriate error code on failure. - - - The xRowid method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - - All changes to a virtual table are made using the xUpdate method. - This one method can be used to insert, delete, or update. - - - The argc parameter specifies the number of entries in the argv - array. The value of argc will be 1 for a pure delete operation or - N+2 for an insert or replace or update where N is the number of - columns in the table. In the previous sentence, N includes any - hidden columns. - - - Every argv entry will have a non-NULL value in C but may contain - the SQL value NULL. In other words, it is always true that - argv[i]!=0 for i between 0 and argc-1. However, it might be the - case that sqlite3_value_type(argv[i])==SQLITE_NULL. - - - The argv[0] parameter is the rowid of a row in the virtual table - to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. - - - The argv[1] parameter is the rowid of a new row to be inserted into - the virtual table. If argv[1] is an SQL NULL, then the - implementation must choose a rowid for the newly inserted row. - Subsequent argv[] entries contain values of the columns of the - virtual table, in the order that the columns were declared. The - number of columns will match the table declaration that the - xConnect or xCreate method made using the sqlite3_declare_vtab() - call. All hidden columns are included. - - - When doing an insert without a rowid (argc>1, argv[1] is an SQL - NULL), the implementation must set *pRowid to the rowid of the - newly inserted row; this will become the value returned by the - sqlite3_last_insert_rowid() function. Setting this value in all the - other cases is a harmless no-op; the SQLite engine ignores the - *pRowid return value if argc==1 or argv[1] is not an SQL NULL. - - - Each call to xUpdate will fall into one of cases shown below. Note - that references to argv[i] mean the SQL value held within the - argv[i] object, not the argv[i] object itself. - - - argc = 1 - - - The single row with rowid equal to argv[0] is deleted. No - insert occurs. - - - argc > 1 - argv[0] = NULL - - - A new row is inserted with a rowid argv[1] and column - values in argv[2] and following. If argv[1] is an SQL NULL, - the a new unique rowid is generated automatically. - - - argc > 1 - argv[0] ? NULL - argv[0] = argv[1] - - - The row with rowid argv[0] is updated with new values in - argv[2] and following parameters. - - - argc > 1 - argv[0] ? NULL - argv[0] ? argv[1] - - - The row with rowid argv[0] is updated with rowid argv[1] - and new values in argv[2] and following parameters. This - will occur when an SQL statement updates a rowid, as in - the statement: - - - UPDATE table SET rowid=rowid+1 WHERE ...; - - - The xUpdate method must return SQLITE_OK if and only if it is - successful. If a failure occurs, the xUpdate must return an - appropriate error code. On a failure, the pVTab->zErrMsg element - may optionally be replaced with error message text stored in memory - allocated from SQLite using functions such as sqlite3_mprintf() or - sqlite3_malloc(). - - - If the xUpdate method violates some constraint of the virtual table - (including, but not limited to, attempting to store a value of the - wrong datatype, attempting to store a value that is too large or - too small, or attempting to change a read-only value) then the - xUpdate must fail with an appropriate error code. - - - There might be one or more sqlite3_vtab_cursor objects open and in - use on the virtual table instance and perhaps even on the row of - the virtual table when the xUpdate method is invoked. The - implementation of xUpdate must be prepared for attempts to delete - or modify rows of the table out from other existing cursors. If the - virtual table cannot accommodate such changes, the xUpdate method - must return an error code. - - - The xUpdate method is optional. If the xUpdate pointer in the - sqlite3_module for a virtual table is a NULL pointer, then the - virtual table is read-only. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of new or modified column values contained in - . - - - The array of native pointers to sqlite3_value structures containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - - This method begins a transaction on a virtual table. This is method - is optional. The xBegin pointer of sqlite3_module may be NULL. - - - This method is always followed by one call to either the xCommit or - xRollback method. Virtual table transactions do not nest, so the - xBegin method will not be invoked more than once on a single - virtual table without an intervening call to either xCommit or - xRollback. Multiple calls to other methods can and likely will - occur in between the xBegin and the corresponding xCommit or - xRollback. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method signals the start of a two-phase commit on a virtual - table. This is method is optional. The xSync pointer of - sqlite3_module may be NULL. - - - This method is only invoked after call to the xBegin method and - prior to an xCommit or xRollback. In order to implement two-phase - commit, the xSync method on all virtual tables is invoked prior to - invoking the xCommit method on any virtual table. If any of the - xSync methods fail, the entire transaction is rolled back. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to commit. This is - method is optional. The xCommit pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin and - xSync. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method causes a virtual table transaction to rollback. This is - method is optional. The xRollback pointer of sqlite3_module may be - NULL. - - - A call to this method always follows a prior call to xBegin. - - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - delegate responsible for implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - - This method provides notification that the virtual table - implementation that the virtual table will be given a new name. If - this method returns SQLITE_OK then SQLite renames the table. If - this method returns an error code then the renaming is prevented. - - - The xRename method is required for every virtual table - implementation. - - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the UTF-8 encoded string containing the new - name for the virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - - These methods provide the virtual table implementation an - opportunity to implement nested transactions. They are always - optional and will only be called in SQLite version 3.7.7 and later. - - - When xSavepoint(X,N) is invoked, that is a signal to the virtual - table X that it should save its current state as savepoint N. A - subsequent call to xRollbackTo(X,R) means that the state of the - virtual table should return to what it was when xSavepoint(X,R) was - last called. The call to xRollbackTo(X,R) will invalidate all - savepoints with N>R; none of the invalided savepoints will be - rolled back or released without first being reinitialized by a call - to xSavepoint(). A call to xRelease(X,M) invalidates all savepoints - where N>=M. - - - None of the xSavepoint(), xRelease(), or xRollbackTo() methods will - ever be called except in between calls to xBegin() and either - xCommit() or xRollback(). - - - - The native pointer to the sqlite3_vtab derived structure. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - This interface represents a virtual table implementation written in - managed code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class contains static methods that are used to allocate, - manipulate, and free native memory provided by the SQLite core library. - - - - - Allocates at least the specified number of bytes of native memory - via the SQLite core library sqlite3_malloc() function and returns - the resulting native pointer. - - - The number of bytes to allocate. - - - The native pointer that points to a block of memory of at least the - specified size -OR- if the memory could - not be allocated. - - - - - Gets and returns the actual size of the specified memory block that - was previously obtained from the method. - - - The native pointer to the memory block previously obtained from the - method. - - - The actual size, in bytes, of the memory block specified via the - native pointer. - - - - - Frees a memory block previously obtained from the - method. - - - The native pointer to the memory block previously obtained from the - method. - - - - - This class contains static methods that are used to deal with native - UTF-8 string pointers to be used with the SQLite core library. - - - - - This is the maximum possible length for the native UTF-8 encoded - strings used with the SQLite core library. - - - - - This is the object instance used to handle - conversions from/to UTF-8. - - - - - Converts the specified managed string into the UTF-8 encoding and - returns the array of bytes containing its representation in that - encoding. - - - The managed string to convert. - - - The array of bytes containing the representation of the managed - string in the UTF-8 encoding or null upon failure. - - - - - Converts the specified array of bytes representing a string in the - UTF-8 encoding and returns a managed string. - - - The array of bytes to convert. - - - The managed string or null upon failure. - - - - - Probes a native pointer to a string in the UTF-8 encoding for its - terminating NUL character, within the specified length limit. - - - The native NUL-terminated string pointer. - - - The maximum length of the native string, in bytes. - - - The length of the native string, in bytes -OR- zero if the length - could not be determined. - - - - - Converts the specified native NUL-terminated UTF-8 string pointer - into a managed string. - - - The native NUL-terminated UTF-8 string pointer. - - - The managed string or null upon failure. - - - - - Converts the specified native UTF-8 string pointer of the specified - length into a managed string. - - - The native UTF-8 string pointer. - - - The length of the native string, in bytes. - - - The managed string or null upon failure. - - - - - Converts the specified managed string into a native NUL-terminated - UTF-8 string pointer using memory obtained from the SQLite core - library. - - - The managed string to convert. - - - The native NUL-terminated UTF-8 string pointer or - upon failure. - - - - - Converts a logical array of native NUL-terminated UTF-8 string - pointers into an array of managed strings. - - - The number of elements in the logical array of native - NUL-terminated UTF-8 string pointers. - - - The native pointer to the logical array of native NUL-terminated - UTF-8 string pointers to convert. - - - The array of managed strings or null upon failure. - - - - - Converts an array of managed strings into an array of native - NUL-terminated UTF-8 string pointers. - - - The array of managed strings to convert. - - - The array of native NUL-terminated UTF-8 string pointers or null - upon failure. - - - - - This class contains static methods that are used to deal with native - pointers to memory blocks that logically contain arrays of bytes to be - used with the SQLite core library. - - - - - Converts a native pointer to a logical array of bytes of the - specified length into a managed byte array. - - - The native pointer to the logical array of bytes to convert. - - - The length, in bytes, of the logical array of bytes to convert. - - - The managed byte array or null upon failure. - - - - - Converts a managed byte array into a native pointer to a logical - array of bytes. - - - The managed byte array to convert. - - - The native pointer to a logical byte array or null upon failure. - - - - - This class contains static methods that are used to perform several - low-level data marshalling tasks between native and managed code. - - - - - Returns a new object instance based on the - specified object instance and an integer - offset. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location that the new - object instance should point to. - - - The new object instance. - - - - - Rounds up an integer size to the next multiple of the alignment. - - - The size, in bytes, to be rounded up. - - - The required alignment for the return value. - - - The size, in bytes, rounded up to the next multiple of the - alignment. This value may end up being the same as the original - size. - - - - - Determines the offset, in bytes, of the next structure member. - - - The offset, in bytes, of the current structure member. - - - The size, in bytes, of the current structure member. - - - The alignment, in bytes, of the next structure member. - - - The offset, in bytes, of the next structure member. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Reads a value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - to be read is located. - - - The value at the specified memory location. - - - - - Reads an value from the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be read is located. - - - The value at the specified memory location. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes an value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Writes a value to the specified memory - location. - - - The object instance representing the base - memory location. - - - The integer offset from the base memory location where the - value to be written is located. - - - The value to write. - - - - - Generates a hash code value for the object. - - - The object instance used to calculate the hash code. - - - Non-zero if different object instances with the same value should - generate different hash codes, where applicable. This parameter - has no effect on the .NET Compact Framework. - - - The hash code value -OR- zero if the object is null. - - - - - This class represents a managed virtual table module implementation. - It is not sealed and must be used as the base class for any - user-defined virtual table module classes implemented in managed code. - - - - - The default version of the native sqlite3_module structure in use. - - - - - This field is used to store the native sqlite3_module structure - associated with this object instance. - - - - - This field is used to store the destructor delegate to be passed to - the SQLite core library via the sqlite3_create_disposable_module() - function. - - - - - This field is used to store a pointer to the native sqlite3_module - structure returned by the sqlite3_create_disposable_module - function. - - - - - This field is used to store the virtual table instances associated - with this module. The native pointer to the sqlite3_vtab derived - structure is used to key into this collection. - - - - - This field is used to store the virtual table cursor instances - associated with this module. The native pointer to the - sqlite3_vtab_cursor derived structure is used to key into this - collection. - - - - - This field is used to store the virtual table function instances - associated with this module. The case-insensitive function name - and the number of arguments (with -1 meaning "any") are used to - construct the string that is used to key into this collection. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Calls the native SQLite core library in order to create a new - disposable module containing the implementation of a virtual table. - - - The native database connection pointer to use. - - - Non-zero upon success. - - - - - This method is called by the SQLite core library when the native - module associated with this object instance is being destroyed due - to its parent connection being closed. It may also be called by - the "vtshim" module if/when the sqlite3_dispose_module() function - is called. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - - - Creates and returns the native sqlite_module structure using the - configured (or default) - interface implementation. - - - The native sqlite_module structure using the configured (or - default) interface - implementation. - - - - - Creates and returns the native sqlite_module structure using the - specified interface - implementation. - - - The interface implementation to - use. - - - The native sqlite_module structure using the specified - interface implementation. - - - - - Creates a copy of the specified - object instance, - using default implementations for the contained delegates when - necessary. - - - The object - instance to copy. - - - The new object - instance. - - - - - Calls one of the virtual table initialization methods. - - - Non-zero to call the - method; otherwise, the - method will be called. - - - The native database connection handle. - - - The original native pointer value that was provided to the - sqlite3_create_module(), sqlite3_create_module_v2() or - sqlite3_create_disposable_module() functions. - - - The number of arguments from the CREATE VIRTUAL TABLE statement. - - - The array of string arguments from the CREATE VIRTUAL TABLE - statement. - - - Upon success, this parameter must be modified to point to the newly - created native sqlite3_vtab derived structure. - - - Upon failure, this parameter must be modified to point to the error - message, with the underlying memory having been obtained from the - sqlite3_malloc() function. - - - A standard SQLite return code. - - - - - Calls one of the virtual table finalization methods. - - - Non-zero to call the - method; otherwise, the - method will be - called. - - - The native pointer to the sqlite3_vtab derived structure. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - used to get the native pointer to the sqlite3_vtab derived - structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance to be used. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - Non-zero if this error message should also be logged using the - class. - - - Non-zero if caught exceptions should be logged using the - class. - - - The error message. - - - Non-zero upon success. - - - - - Gets and returns the interface - implementation to be used when creating the native sqlite3_module - structure. Derived classes may override this method to supply an - alternate implementation for the - interface. - - - The interface implementation to - be used when populating the native sqlite3_module structure. If - the returned value is null, the private methods provided by the - class and relating to the - interface will be used to - create the necessary delegates. - - - - - Creates and returns the - interface implementation corresponding to the current - object instance. - - - The interface implementation - corresponding to the current object - instance. - - - - - Allocates a native sqlite3_vtab derived structure and returns a - native pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Zeros out the fields of a native sqlite3_vtab derived structure. - - - The native pointer to the native sqlite3_vtab derived structure to - zero. - - - - - Frees a native sqlite3_vtab structure using the provided native - pointer to it. - - - A native pointer to a native sqlite3_vtab derived structure. - - - - - Allocates a native sqlite3_vtab_cursor derived structure and - returns a native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Frees a native sqlite3_vtab_cursor structure using the provided - native pointer to it. - - - A native pointer to a native sqlite3_vtab_cursor derived structure. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The object instance to be used. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Reads and returns the native pointer to the sqlite3_vtab derived - structure based on the native pointer to the sqlite3_vtab_cursor - derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure - from which to read the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure -OR- - if it cannot be determined. - - - - - Looks up and returns the object - instance based on the native pointer to the sqlite3_vtab derived - structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The object instance or null if - the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab derived - structure and creates an association between it and the specified - object instance. - - - The object instance to be used - when creating the association. - - - The native pointer to a sqlite3_vtab derived structure or - if the method fails for any reason. - - - - - Looks up and returns the - object instance based on the native pointer to the - sqlite3_vtab_cursor derived structure. - - - The native pointer to the sqlite3_vtab derived structure. - - - The native pointer to the sqlite3_vtab_cursor derived structure. - - - The object instance or null - if the corresponding one cannot be found. - - - - - Allocates and returns a native pointer to a sqlite3_vtab_cursor - derived structure and creates an association between it and the - specified object instance. - - - The object instance to be - used when creating the association. - - - The native pointer to a sqlite3_vtab_cursor derived structure or - if the method fails for any reason. - - - - - Deterimines the key that should be used to identify and store the - object instance for the virtual table - (i.e. to be returned via the - method). - - - The number of arguments to the virtual table function. - - - The name of the virtual table function. - - - The object instance associated with - this virtual table function. - - - The string that should be used to identify and store the virtual - table function instance. This method cannot return null. If null - is returned from this method, the behavior is undefined. - - - - - Attempts to declare the schema for the virtual table using the - specified database connection. - - - The object instance to use when - declaring the schema of the virtual table. This parameter may not - be null. - - - The string containing the CREATE TABLE statement that completely - describes the schema for the virtual table. This parameter may not - be null. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - Calls the native SQLite core library in order to declare a virtual - table function in response to a call into the - - or virtual table - methods. - - - The object instance to use when - declaring the schema of the virtual table. - - - The number of arguments to the function being declared. - - - The name of the function being declared. - - - Upon success, the contents of this parameter are undefined. Upon - failure, it should contain an appropriate error message. - - - A standard SQLite return code. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Arranges for the specified error message to be placed into the - zErrMsg field of a sqlite3_vtab derived structure, freeing the - existing error message, if any. - - - The object instance used to - lookup the native pointer to the sqlite3_vtab derived structure. - - - The error message. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated cost. - - - The object instance to modify. - - - The estimated cost value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated cost. - - - The object instance to modify. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the specified estimated rows. - - - The object instance to modify. - - - The estimated rows value to use. Using a null value means that the - default value provided by the SQLite core library should be used. - - - Non-zero upon success. - - - - - Modifies the specified object instance - to contain the default estimated rows. - - - The object instance to modify. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated with - the virtual table. - - - The native user-data pointer associated with this module, as it was - provided to the SQLite core library when the native module instance - was created. - - - The module name, database name, virtual table name, and all other - arguments passed to the CREATE VIRTUAL TABLE statement. - - - Upon success, this parameter must be modified to contain the - object instance associated with - the virtual table. - - - Upon failure, this parameter must be modified to contain an error - message. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The object instance containing all the - data for the inputs and outputs relating to index selection. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - Upon success, this parameter must be modified to contain the - object instance associated - with the newly opened virtual table cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Number used to help identify the selected index. - - - String used to help identify the selected index. - - - The values corresponding to each column in the selected index. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Non-zero if no more rows are available; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to be used for - returning the specified column value to the SQLite core library. - - - The zero-based index corresponding to the column containing the - value to be returned. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the current row for the specified cursor. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The array of object instances containing - the new or modified column values, if any. - - - Upon success, this parameter must be modified to contain the unique - integer row identifier for the row that was inserted, if any. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The number of arguments to the function being sought. - - - The name of the function being sought. - - - Upon success, this parameter must be modified to contain the - object instance responsible for - implementing the specified function. - - - Upon success, this parameter must be modified to contain the - native user-data pointer associated with - . - - - Non-zero if the specified function was found; zero otherwise. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - The new name for the virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier under which the the current state of - the virtual table should be saved. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer used to indicate that any saved states with an - identifier greater than or equal to this should be deleted by the - virtual table. - - - A standard SQLite return code. - - - - - This method is called in response to the - method. - - - The object instance associated - with this virtual table. - - - This is an integer identifier used to specify a specific saved - state for the virtual table for it to restore itself back to, which - should also have the effect of deleting all saved states with an - integer identifier greater than this one. - - - A standard SQLite return code. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - the method, - the method, - the method, - and the method should be logged using the - class. - - - - - Returns or sets a boolean value indicating whether virtual table - errors should be logged using the class. - - - - - Returns or sets a boolean value indicating whether exceptions - caught in the - method, - method, and the - method should be logged using the - class. - - - - - Returns non-zero if the schema for the virtual table has been - declared. - - - - - Returns the name of the module as it was registered with the SQLite - core library. - - - - - This class implements the - interface by forwarding those method calls to the - object instance it contains. If the - contained object instance is null, all - the methods simply generate an - error. - - - - - This is the value that is always used for the "logErrors" - parameter to the various static error handling methods provided - by the class. - - - - - This is the value that is always used for the "logExceptions" - parameter to the various static error handling methods provided - by the class. - - - - - This is the error message text used when the contained - object instance is not available - for any reason. - - - - - The object instance used to provide - an implementation of the - interface. - - - - - Constructs an instance of this class. - - - The object instance used to provide - an implementation of the - interface. - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab derived structure. - - - The value of . - - - - - Sets the table error message to one that indicates the native - module implementation is not available. - - - The native pointer to the sqlite3_vtab_cursor derived - structure. - - - The value of . - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Disposes of this object instance. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is being - called from the finalizer. - - - - - Finalizes this object instance. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this cursor - was created. - - - - - This value will be non-zero if false has been returned from the - method. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Advances to the next row of the virtual table cursor using the - method of the - object instance. - - - Non-zero if the current row is valid; zero otherwise. If zero is - returned, no further rows are available. - - - - - Resets the virtual table cursor position, also invalidating the - current row, using the method of - the object instance. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if the virtual - table cursor has been closed. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - Returns non-zero if the end of the virtual table cursor has been - seen (i.e. no more rows are available, including the current one). - - - - - Returns non-zero if the virtual table cursor is open. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. The following short - example shows it being used to treat an array of strings as a table - data source: - - public static class Sample - { - public static void Main() - { - using (SQLiteConnection connection = new SQLiteConnection( - "Data Source=:memory:;")) - { - connection.Open(); - - connection.CreateModule(new SQLiteModuleEnumerable( - "sampleModule", new string[] { "one", "two", "three" })); - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = - "CREATE VIRTUAL TABLE t1 USING sampleModule;"; - - command.ExecuteNonQuery(); - } - - using (SQLiteCommand command = connection.CreateCommand()) - { - command.CommandText = "SELECT * FROM t1;"; - - using (SQLiteDataReader dataReader = command.ExecuteReader()) - { - while (dataReader.Read()) - Console.WriteLine(dataReader[0].ToString()); - } - } - - connection.Close(); - } - } - } - - - - - - This class implements a virtual table module that does nothing by - providing "empty" implementations for all of the - interface methods. The result - codes returned by these "empty" method implementations may be - controlled on a per-method basis by using and/or overriding the - , - , - , - , and - methods from within derived classes. - - - - - This field is used to store the - values to return, on a per-method basis, for all methods that are - part of the interface. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - - - Determines the default value to be - returned by methods of the - interface that lack an overridden implementation in all classes - derived from the class. - - - The value that should be returned - by all interface methods unless - a more specific result code has been set for that interface method. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Converts a value into a boolean - return value for use with the - method. - - - The value to convert. - - - The value. - - - - - Determines the value that should be - returned by the specified - interface method if it lack an overridden implementation. If no - specific value is available (or set) - for the specified method, the value - returned by the method will be - returned instead. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - - - Sets the value that should be - returned by the specified - interface method if it lack an overridden implementation. - - - The name of the method. Currently, this method must be part of - the interface. - - - The value that should be returned - by the interface method. - - - Non-zero upon success. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - The CREATE TABLE statement used to declare the schema for the - virtual table. - - - - - The instance containing the backing data - for the virtual table. - - - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This has no - effect on the .NET Compact Framework. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - Non-zero if different object instances with the same value should - generate different row identifiers, where applicable. This - parameter has no effect on the .NET Compact Framework. - - - - - Determines the SQL statement used to declare the virtual table. - This method should be overridden in derived classes if they require - a custom virtual table schema. - - - The SQL statement used to declare the virtual table -OR- null if it - cannot be determined. - - - - - Sets the table error message to one that indicates the virtual - table cursor is of the wrong type. - - - The object instance. - - - The value of . - - - - - Sets the table error message to one that indicates the virtual - table cursor has no current row. - - - The object instance. - - - The value of . - - - - - Determines the string to return as the column value for the object - instance value. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a string representation for. - - - The string representation of the specified object instance or null - upon failure. - - - - - Constructs an unique row identifier from two - values. The first value - must contain the row sequence number for the current row and the - second value must contain the hash code of the enumerator value - for the current row. - - - The integer row sequence number for the current row. - - - The hash code of the enumerator value for the current row. - - - The unique row identifier or zero upon failure. - - - - - Determines the unique row identifier for the current row. - - - The object instance - associated with the previously opened virtual table cursor to be - used. - - - The object instance to return a unique row identifier for. - - - The unique row identifier or zero upon failure. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - This class represents a virtual table cursor to be used with the - class. It is not sealed and may - be used as the base class for any user-defined virtual table cursor - class that wraps an object instance. - - - - - The instance provided when this - cursor was created. - - - - - Constructs an instance of this class. - - - The object instance associated - with this object instance. - - - The instance to expose as a virtual - table cursor. - - - - - Closes the virtual table cursor. This method must not throw any - exceptions. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - - - - Returns the value for the current row of the virtual table cursor - using the property of the - object instance. - - - - - This class implements a virtual table module that exposes an - object instance as a read-only virtual - table. It is not sealed and may be used as the base class for any - user-defined virtual table class that wraps an - object instance. - - - - - The instance containing the backing - data for the virtual table. - - - - - Constructs an instance of this class. - - - The name of the module. This parameter cannot be null. - - - The instance to expose as a virtual - table. This parameter cannot be null. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - See the method. - - - - - Throws an if this object - instance has been disposed. - - - - - Disposes of this object instance. - - - Non-zero if this method is being called from the - method. Zero if this method is - being called from the finalizer. - - -
-
diff --git a/src/packages/dotConnect.Express.for.Oracle.7.1.58/dotConnect.Express.for.Oracle.7.1.58.nuspec b/src/packages/dotConnect.Express.for.Oracle.7.1.58/dotConnect.Express.for.Oracle.7.1.58.nuspec deleted file mode 100644 index 7e0aa0c5c..000000000 --- a/src/packages/dotConnect.Express.for.Oracle.7.1.58/dotConnect.Express.for.Oracle.7.1.58.nuspec +++ /dev/null @@ -1,21 +0,0 @@ - - - - dotConnect.Express.for.Oracle - 7.1.58 - dotConnect Express for Oracle - Devart Software - Devart Software - http://www.devart.com/dotconnect/oracle - http://www.devart.com/content/images/logos/dcoracle-white_fb.png - false - dotConnect Express for Oracle is a free of charge enhanced database connectivity solution built over ADO.NET architecture and a development framework with a number of innovative technologies. dotConnect offers a complete solution for developing database-related applications and web sites. It introduces new approaches for designing applications and boosts productivity of database application development. - dotConnect Express for Oracle is a free of charge enhanced database connectivity solution built over ADO.NET architecture and a development framework with a number of innovative technologies. - Copyright � 1998 - 2012 Devart - Oracle ADO.NET provider Database - - - - - - \ No newline at end of file diff --git a/src/packages/dotConnect.Express.for.Oracle.8.3.115/content/app.config.transform b/src/packages/dotConnect.Express.for.Oracle.8.3.115/content/app.config.transform deleted file mode 100644 index 27b18c536..000000000 --- a/src/packages/dotConnect.Express.for.Oracle.8.3.115/content/app.config.transform +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/packages/dotConnect.Express.for.Oracle.8.3.115/content/web.config.transform b/src/packages/dotConnect.Express.for.Oracle.8.3.115/content/web.config.transform deleted file mode 100644 index e2abce547..000000000 --- a/src/packages/dotConnect.Express.for.Oracle.8.3.115/content/web.config.transform +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/packages/dotConnect.Express.for.Oracle.8.3.115/lib/Devart.Data.Oracle.dll b/src/packages/dotConnect.Express.for.Oracle.8.3.115/lib/Devart.Data.Oracle.dll deleted file mode 100644 index 46a5674eb..000000000 Binary files a/src/packages/dotConnect.Express.for.Oracle.8.3.115/lib/Devart.Data.Oracle.dll and /dev/null differ diff --git a/src/packages/dotConnect.Express.for.Oracle.8.3.115/lib/Devart.Data.dll b/src/packages/dotConnect.Express.for.Oracle.8.3.115/lib/Devart.Data.dll deleted file mode 100644 index 6e4758bbf..000000000 Binary files a/src/packages/dotConnect.Express.for.Oracle.8.3.115/lib/Devart.Data.dll and /dev/null differ diff --git a/src/packages/odp.net.x64.112.3.0/odp.net.x64.112.3.0.nuspec b/src/packages/odp.net.x64.112.3.0/odp.net.x64.112.3.0.nuspec deleted file mode 100644 index 07d23583f..000000000 --- a/src/packages/odp.net.x64.112.3.0/odp.net.x64.112.3.0.nuspec +++ /dev/null @@ -1,17 +0,0 @@ - - - - odp.net.x64 - 112.3.0 - Oracle Data Provier for .NET (ODP.NET) x64 - Oracle - Oracle - http://www.oracle.com/technetwork/licenses/odt-lic-152011.html - http://www.oracle.com/technetwork/topics/dotnet/index-085163.html - true - This NuGet package contains Oracle.DataAccess.dll (x64- both the net20 and net40 versions) needed to compile a project that uses Oracle's ODP.NET Library. Oracle will still need to be installed on the production or development machine in order to connect to Oracle (those libraries are greater than 100MB in size, so it didn't make sense to include them in a NuGet package), but this package will at least allow the project to be successfully built (i.e. if you're using a CI server). - - - - - \ No newline at end of file diff --git a/src/packages/odp.net.x64.112.3.20/lib/net20/Oracle.DataAccess.dll b/src/packages/odp.net.x64.112.3.20/lib/net20/Oracle.DataAccess.dll deleted file mode 100644 index 42e39281e..000000000 Binary files a/src/packages/odp.net.x64.112.3.20/lib/net20/Oracle.DataAccess.dll and /dev/null differ diff --git a/src/packages/odp.net.x64.112.3.20/lib/net40/Oracle.DataAccess.dll b/src/packages/odp.net.x64.112.3.20/lib/net40/Oracle.DataAccess.dll deleted file mode 100644 index 94b664637..000000000 Binary files a/src/packages/odp.net.x64.112.3.20/lib/net40/Oracle.DataAccess.dll and /dev/null differ diff --git a/src/packages/odp.net.x86.112.3.20/lib/net20/Oracle.DataAccess.dll b/src/packages/odp.net.x86.112.3.20/lib/net20/Oracle.DataAccess.dll deleted file mode 100644 index b4f68bb7a..000000000 Binary files a/src/packages/odp.net.x86.112.3.20/lib/net20/Oracle.DataAccess.dll and /dev/null differ diff --git a/src/packages/odp.net.x86.112.3.20/lib/net40/Oracle.DataAccess.dll b/src/packages/odp.net.x86.112.3.20/lib/net40/Oracle.DataAccess.dll deleted file mode 100644 index 32543d0f0..000000000 Binary files a/src/packages/odp.net.x86.112.3.20/lib/net40/Oracle.DataAccess.dll and /dev/null differ diff --git a/src/packages/repositories.config b/src/packages/repositories.config deleted file mode 100644 index a7397870c..000000000 --- a/src/packages/repositories.config +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/servicestack.snk b/src/servicestack.snk new file mode 100644 index 000000000..dade7cea3 Binary files /dev/null and b/src/servicestack.snk differ diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props new file mode 100644 index 000000000..7eb7717ea --- /dev/null +++ b/tests/Directory.Build.props @@ -0,0 +1,29 @@ + + + + 6.0.3 + latest + false + + + + DEBUG + + + + $(DefineConstants);NETFX;NET472 + + + + $(DefineConstants);NETCORE;NETSTANDARD2_0 + + + + $(DefineConstants);NET6_0;NET6_0_OR_GREATER + + + + $(DefineConstants);NETCORE;NETCORE_SUPPORT + + + diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/DateTimeColumnTest.cs b/tests/ServiceStack.OrmLite.FirebirdTests/DateTimeColumnTest.cs index 8a067818b..5df957616 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/DateTimeColumnTest.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/DateTimeColumnTest.cs @@ -9,8 +9,7 @@ namespace ServiceStack.OrmLite.FirebirdTests { [TestFixture] - public class DateTimeColumnTest - : OrmLiteTestBase + public class DateTimeColumnTest : OrmLiteTestBase { [Test] public void Can_create_table_containing_DateTime_column() diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Expressions/AuthorUseCase.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Expressions/AuthorUseCase.cs index 410874746..2b6950905 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Expressions/AuthorUseCase.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/Expressions/AuthorUseCase.cs @@ -52,7 +52,7 @@ public void AuthorUsesCases() ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); List result = db.Select(ev); Assert.AreEqual(expected, result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); + result = db.Select(db.From().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); Assert.AreEqual(expected, result.Count); result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); Assert.AreEqual(expected, result.Count); @@ -154,14 +154,14 @@ public void AuthorUsesCases() expected = 2; var rate = 0; ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); + var rows = db.UpdateOnlyFields(new Author() { Active = false }, ev); Assert.AreEqual(expected, rows); // insert values only in Id, Name, Birthday, Rate and Active fields expected = 4; ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); ev.Where().Where(rn => !rn.Active); result = db.Select(ev); Assert.AreEqual(expected, result.Count); @@ -169,7 +169,7 @@ public void AuthorUsesCases() //update comment for City == null expected = 2; ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); + rows = db.UpdateOnlyFields(new Author() { Comments = "No comments" }, ev); Assert.AreEqual(expected, rows); // delete where City is null @@ -351,17 +351,17 @@ public void AuthorUsesCases() rr.City = "Madrid"; rr.Comments = "Updated"; ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated - rows = db.UpdateOnly(rr, ev); // == dbCmd.Update(rr) but it returns void + rows = db.UpdateOnlyFields(rr, ev); // == dbCmd.Update(rr) but it returns void Assert.AreEqual(expected, rows); expected = 0; ev.Where().Where(r => r.City == "Ciudad Gotica"); - rows = db.UpdateOnly(rr, ev); + rows = db.UpdateOnlyFields(rr, ev); Assert.AreEqual(expected, rows); expected = db.Select(x => x.City == "Madrid").Count; author = new Author() { Active = false }; - rows = db.UpdateOnly(author, x => x.Active, x => x.City == "Madrid"); + rows = db.UpdateOnlyFields(author, x => x.Active, x => x.City == "Madrid"); Assert.AreEqual(expected, rows); expected = db.Select(x => x.Active == false).Count; diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/FB4ConnectionTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/FB4ConnectionTests.cs new file mode 100644 index 000000000..bb1439f2d --- /dev/null +++ b/tests/ServiceStack.OrmLite.FirebirdTests/FB4ConnectionTests.cs @@ -0,0 +1,87 @@ +using System; +using System.IO; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Firebird; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.FirebirdTests +{ + [TestFixture] + public class FB4ConnectionTests + : OrmLiteTestBase + { + protected override string GetFileConnectionString() => FirebirdDb.V4Connection; + protected override IOrmLiteDialectProvider GetDialectProvider() => Firebird4OrmLiteDialectProvider.Instance; + + [Test]//[Ignore("")] + public void Can_create_connection_to_blank_database() + { + var connString = + $"User=SYSDBA;Password=masterkey;Database=/ormlite-tests/ormlite-tests.fdb;DataSource=localhost;Dialect=3;charset=utf8;"; + using (var db = connString.OpenDbConnection()) + { + } + } + + [Test] + public void Can_connect_to_database() + { + using (var db = new OrmLiteConnectionFactory(ConnectionString, Firebird4Dialect.Provider).OpenDbConnection()) + { + } + } + + [Test] + public void Can_create_connection() + { + using (var db = new OrmLiteConnectionFactory(ConnectionString, Firebird4Dialect.Provider).CreateDbConnection()) + { + } + } + + [Test] + public void Can_create_ReadOnly_connection() + { + using (var db = ConnectionString.OpenReadOnlyDbConnection()) + { + } + } + + [Test][Ignore("")] + public void Can_create_table_with_ReadOnly_connection() + { + using (var db = ConnectionString.OpenReadOnlyDbConnection()) + { + try + { + db.CreateTable(true); + db.Insert(new ModelWithIdAndName(0)); + } + catch (Exception ex) + { + Log(ex.Message); + return; + } + Assert.Fail("Should not be able to create a table with a readonly connection"); + } + } + + [Test] + public void Can_open_two_ReadOnlyConnections_to_same_database() + { + var db = ConnectionString.OpenReadOnlyDbConnection(); + db.CreateTable(true); + db.Insert(new ModelWithIdAndName(1)); + + var dbReadOnly = ConnectionString.OpenReadOnlyDbConnection(); + dbReadOnly.Insert(new ModelWithIdAndName(2)); + var rows = dbReadOnly.Select(); + Assert.That(rows, Has.Count.EqualTo(2)); + + dbReadOnly.Dispose(); + db.Dispose(); + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/FB4CreateTableTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/FB4CreateTableTests.cs new file mode 100644 index 000000000..98f18f390 --- /dev/null +++ b/tests/ServiceStack.OrmLite.FirebirdTests/FB4CreateTableTests.cs @@ -0,0 +1,104 @@ +using System; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Firebird; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.FirebirdTests +{ + [TestFixture] + public class FB4CreateTableTests : OrmLiteTestBase + { + protected override string GetFileConnectionString() => FirebirdDb.V4Connection; + protected override IOrmLiteDialectProvider GetDialectProvider() => Firebird4OrmLiteDialectProvider.Instance; + + [Test] + public void Does_table_Exists() + { + using (var db = new OrmLiteConnectionFactory(ConnectionString, Firebird4Dialect.Provider).OpenDbConnection()) + { + db.DropTable(); + + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithAutoIncrement)), + Is.False); + + db.CreateTable(true); + + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithAutoIncrement)), + Is.True); + } + } + + [Test] + public void Can_create_ModelWithAutoIncrement_table() + { + using (var db = new OrmLiteConnectionFactory(ConnectionString, Firebird4Dialect.Provider).OpenDbConnection()) + { + db.CreateTable(true); + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithAutoIncrement)), + Is.True); + + db.DropTable(); + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithAutoIncrement)), + Is.False); + } + } + + [Test] + public void Can_create_ModelWithAutoId_table() + { + using (var db = new OrmLiteConnectionFactory(ConnectionString, Firebird4Dialect.Provider).OpenDbConnection()) + { + db.CreateTable(true); + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithAutoId)), + Is.True); + + db.DropTable(); + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithAutoId)), + Is.False); + } + } + + [Test] + public void Check_AutoIncrement_with_Identity() + { + using (var db = new OrmLiteConnectionFactory(ConnectionString, Firebird4Dialect.Provider).OpenDbConnection()) + { + db.CreateTable(true); + + var id = db.Insert(new ModelWithAutoIncrement { Id = 1000, Name = "Isaac Newton"}); + var model = db.SingleById(1000); + Assert.That(model, !Is.Null); + Assert.That(model.Name, Is.EqualTo("Isaac Newton")); + + id = db.Insert(new ModelWithAutoIncrement { Name = "Alan Kay"}); + model = db.SingleById(1); + Assert.That(model, !Is.Null); + Assert.That(model.Name, Is.EqualTo("Alan Kay")); + + var rows = db.Select(); + Assert.That(rows, Has.Count.EqualTo(2)); + } + } + + [Test] + public void Check_AutoId_generation() + { + using (var db = new OrmLiteConnectionFactory(ConnectionString, Firebird4Dialect.Provider).OpenDbConnection()) + { + db.CreateTable(true); + + db.Insert(new ModelWithAutoId { Name = "Isaac Newton" }); + db.Insert(new ModelWithAutoId { Name = "Alan Kay" }); + var rows = db.Select(); + Assert.That(rows, Has.Count.EqualTo(2)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ForeignKeyAttributeTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/ForeignKeyAttributeTests.cs index 00b30b885..48fb212fc 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/ForeignKeyAttributeTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/ForeignKeyAttributeTests.cs @@ -6,7 +6,7 @@ namespace ServiceStack.OrmLite.FirebirdTests [TestFixture] public class ForeignKeyAttributeTests : OrmLiteTestBase { - [TestFixtureSetUp] + [OneTimeSetUp] public void Setup() { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) @@ -99,7 +99,7 @@ public void CanCreateForeignWithOnDeleteSetNull() } } - [TestFixtureTearDown] + [OneTimeTearDown] public void TearDwon() { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/LocalizationTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/LocalizationTests.cs index 00df1f194..346e651ea 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/LocalizationTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/LocalizationTests.cs @@ -15,14 +15,14 @@ public class LocalizationTests private readonly CultureInfo CurrentCulture = Thread.CurrentThread.CurrentCulture; private readonly CultureInfo CurrentUICulture = Thread.CurrentThread.CurrentUICulture; - [TestFixtureSetUp] + [OneTimeSetUp] public new void TestFixtureSetUp() { Thread.CurrentThread.CurrentCulture = new CultureInfo("vi-VN"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("vi-VN"); } - [TestFixtureTearDown] + [OneTimeTearDown] public void TestFixtureTearDown() { Thread.CurrentThread.CurrentCulture = CurrentCulture; @@ -56,8 +56,9 @@ public void Can_query_using_float_in_alernate_culuture() Assert.That(points[0].Height, Is.EqualTo(1.123f)); Assert.That(points[0].Top, Is.EqualTo(3.456d)); Assert.That(points[0].Left, Is.EqualTo(2.345m)); - - points = db.SelectFmt("Height={0}", 1.123f); // returns no rows! FirebirdSql bug? + + // returns no rows! FirebirdSql bug? + points = db.Select("Height=@height", new { height = 1.123f }); Assert.That(points.Count>0); } diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Category.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Category.cs deleted file mode 100755 index bc6b2410d..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Category.cs +++ /dev/null @@ -1,42 +0,0 @@ -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace Northwind.Common.DataModel -{ - [Alias("Categories")] - public class Category : IHasIntId, IHasId - { - [StringLength(15)] - [Required] - [Index] - public string CategoryName - { - get; - set; - } - - [StringLength(10)] - public string Description - { - get; - set; - } - - [Alias("CategoryID")] - public int Id - { - get; - set; - } - - public byte[] Picture - { - get; - set; - } - - public Category() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Customer.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Customer.cs deleted file mode 100755 index 95e102897..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Customer.cs +++ /dev/null @@ -1,104 +0,0 @@ -using ServiceStack.DataAnnotations; -using ServiceStack.Model; -using System; - -namespace Northwind.Common.DataModel -{ - [Alias("Customers")] - public class Customer : IHasStringId, IHasId - { - [StringLength(60)] - public string Address - { - get; - set; - } - - [Index] - [StringLength(15)] - public string City - { - get; - set; - } - - [Index] - [Required] - [StringLength(40)] - public string CompanyName - { - get; - set; - } - - [StringLength(30)] - public string ContactName - { - get; - set; - } - - [StringLength(30)] - public string ContactTitle - { - get; - set; - } - - [StringLength(15)] - public string Country - { - get; - set; - } - - [StringLength(24)] - public string Fax - { - get; - set; - } - - [Alias("CustomerID")] - [Required] - [StringLength(5)] - public string Id - { - get; - set; - } - - [StringLength(24)] - public string Phone - { - get; - set; - } - - public byte[] Picture - { - get; - set; - } - - [StringLength(10)] - [Index] - public string PostalCode - { - get; - set; - } - - [StringLength(15)] - [Index] - public string Region - { - get; - set; - } - - public Customer() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/CustomerCustomerDemo.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/CustomerCustomerDemo.cs deleted file mode 100755 index 153c3d5bb..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/CustomerCustomerDemo.cs +++ /dev/null @@ -1,31 +0,0 @@ -using ServiceStack.Model; -using ServiceStack.DataAnnotations; - -using System; - -namespace Northwind.Common.DataModel{ - - [Alias("CustomerDemo")] - public class CustomerCustomerDemo : IHasStringId, IHasId{ - - [Alias("CustomerTypeID")] - [StringLength(10)] - public string CustomerTypeId - { - get; - set; - } - - [Alias("CustomerID")] - [StringLength(5)] - public string Id - { - get; - set; - } - - public CustomerCustomerDemo() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/CustomerDemographic.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/CustomerDemographic.cs deleted file mode 100755 index 32db657bf..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/CustomerDemographic.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - - -namespace Northwind.Common.DataModel{ - - [Alias("Demographics")] - public class CustomerDemographic : IHasStringId, IHasId - { - public string CustomerDesc - { - get; - set; - } - - [StringLength(10)] - [Alias("TypeID")] - public string Id - { - get; - set; - } - - public CustomerDemographic() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Employee.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Employee.cs deleted file mode 100755 index e2fa16e4c..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Employee.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - - -namespace Northwind.Common.DataModel{ - - [Alias("Employees")] - public class Employee : IHasIntId, IHasId - { - [StringLength(60)] - public string Address - { - get; - set; - } - - public DateTime? BirthDate - { - get; - set; - } - - [StringLength(15)] - public string City - { - get; - set; - } - - [StringLength(15)] - public string Country - { - get; - set; - } - - [StringLength(4)] - public string Extension - { - get; - set; - } - - [Required] - [StringLength(10)] - public string FirstName - { - get; - set; - } - - public DateTime? HireDate - { - get; - set; - } - - [StringLength(24)] - public string HomePhone - { - get; - set; - } - - [AutoIncrement] - [Alias("EmployeeID")] - public int Id - { - get; - set; - } - - [Required] - [StringLength(20)] - [Index] - public string LastName - { - get; - set; - } - - public string Notes - { - get; - set; - } - - public byte[] Photo - { - get; - set; - } - - [StringLength(255)] - public string PhotoPath - { - get; - set; - } - - [StringLength(10)] - [Index] - public string PostalCode - { - get; - set; - } - - [StringLength(15)] - public string Region - { - get; - set; - } - - [References(typeof(Employee))] - public int? ReportsTo - { - get; - set; - } - - [StringLength(30)] - public string Title - { - get; - set; - } - - [StringLength(25)] - public string TitleOfCourtesy - { - get; - set; - } - - public Employee() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/EmployeeTerritory.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/EmployeeTerritory.cs deleted file mode 100755 index d25ed19d5..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/EmployeeTerritory.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - - -namespace Northwind.Common.DataModel{ - - [Alias("EmployeeTerritories")] - public class EmployeeTerritory : IHasStringId, IHasId - { - [Alias("EmployeeID")] - public int EmployeeId - { - get; - set; - } - - public string Id - { - get - { - return string.Concat(this.EmployeeId, "/", this.TerritoryId); - } - } - - [StringLength(20)] - [Required] - [Alias("TerritoryID")] - public string TerritoryId - { - get; - set; - } - - public EmployeeTerritory() - { - } - } - } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/NorthwindData.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/NorthwindData.cs deleted file mode 100755 index 884f62f90..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/NorthwindData.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using Northwind.Common; - -namespace Northwind.Common.DataModel{ - - public static class NorthwindData - { - - public static List Categories - { - get;set; - } - - public static List CustomerCustomerDemos - { - get;set; - } - - public static List Customers - { - get;set; - } - - public static List Employees - { - get;set; - } - - public static List EmployeeTerritories - { - get;set; - } - - public static List OrderDetails - { - get;set; - } - - public static List Orders - { - get;set; - } - - public static List Products - { - get;set; - } - - public static List Regions - { - get;set; - } - - public static List Shippers - { - get;set; - } - - public static List Suppliers - { - get;set; - } - - public static List Territories - { - get;set; - } - - - public static DateTime ToDateTime(string dateTime) - { - string[] strArrays = dateTime.Split(new char[] { '/' }); - return new DateTime(int.Parse(strArrays[2]), int.Parse(strArrays[0]), int.Parse(strArrays[1])); - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/NorthwindFactory.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/NorthwindFactory.cs deleted file mode 100755 index 723e34f06..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/NorthwindFactory.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Northwind.Common.DataModel{ - - public static class NorthwindFactory - { - - public readonly static List ModelTypes; - - static NorthwindFactory() - { - List types = new List(); - types.Add(typeof(Employee)); - types.Add(typeof(Category)); - types.Add(typeof(Customer)); - types.Add(typeof(Shipper)); - types.Add(typeof(Supplier)); - types.Add(typeof(Order)); - types.Add(typeof(Product)); - types.Add(typeof(OrderDetail)); - types.Add(typeof(CustomerCustomerDemo)); - types.Add(typeof(Category)); - types.Add(typeof(CustomerDemographic)); - types.Add(typeof(Region)); - types.Add(typeof(Territory)); - types.Add(typeof(EmployeeTerritory)); - NorthwindFactory.ModelTypes = types; - } - - public static Category Category(int id, string categoryName, string description, byte[] picture) - { - Category category = new Category(); - category.Id = id; - category.CategoryName = categoryName; - category.Description = description; - category.Picture = picture; - return category; - } - - public static Customer Customer(string customerId, string companyName, string contactName, string contactTitle, string address, string city, string region, string postalCode, string country, string phoneNo, string faxNo, byte[] picture) - { - Customer customer = new Customer(); - customer.Id = customerId; - customer.CompanyName = companyName; - customer.ContactName = contactName; - customer.ContactTitle = contactTitle; - customer.Address = address; - customer.City = city; - customer.Region = region; - customer.PostalCode = postalCode; - customer.Country = country; - customer.Phone = phoneNo; - customer.Fax = faxNo; - customer.Picture = picture; - return customer; - } - - public static CustomerCustomerDemo CustomerCustomerDemo(string customerId, string customerTypeId) - { - CustomerCustomerDemo customerCustomerDemo = new CustomerCustomerDemo(); - customerCustomerDemo.Id = customerId; - customerCustomerDemo.CustomerTypeId = customerTypeId; - return customerCustomerDemo; - } - - public static Employee Employee(int employeeId, string lastName, string firstName, string title, string titleOfCourtesy, DateTime? birthDate, DateTime? hireDate, string address, string city, string region, string postalCode, string country, string homePhone, string extension, byte[] photo, string notes, int? reportsTo, string photoPath) - { - Employee employee = new Employee(); - employee.Id = employeeId; - employee.LastName = lastName; - employee.FirstName = firstName; - employee.Title = title; - employee.TitleOfCourtesy = titleOfCourtesy; - employee.BirthDate = birthDate; - employee.HireDate = hireDate; - employee.Address = address; - employee.City = city; - employee.Region = region; - employee.PostalCode = postalCode; - employee.Country = country; - employee.HomePhone = homePhone; - employee.Extension = extension; - employee.Photo = photo; - employee.Notes = notes; - employee.ReportsTo = reportsTo; - employee.PhotoPath = photoPath; - return employee; - } - - public static EmployeeTerritory EmployeeTerritory(int employeeId, string territoryId) - { - EmployeeTerritory employeeTerritory = new EmployeeTerritory(); - employeeTerritory.EmployeeId = employeeId; - employeeTerritory.TerritoryId = territoryId; - return employeeTerritory; - } - - public static Order Order(int orderId, string customerId, int employeeId, DateTime? orderDate, DateTime? requiredDate, DateTime? shippedDate, int shipVia, decimal freight, string shipName, string address, string city, string region, string postalCode, string country) - { - Order order = new Order(); - order.Id = orderId; - order.CustomerId = customerId; - order.EmployeeId = employeeId; - order.OrderDate = orderDate; - order.RequiredDate = requiredDate; - order.ShippedDate = shippedDate; - order.ShipVia = new int?(shipVia); - order.Freight = freight; - order.ShipName = shipName; - order.ShipAddress = address; - order.ShipCity = city; - order.ShipRegion = region; - order.ShipPostalCode = postalCode; - order.ShipCountry = country; - return order; - } - - public static OrderDetail OrderDetail(int orderId, int productId, decimal unitPrice, short quantity, double discount) - { - OrderDetail orderDetail = new OrderDetail(); - orderDetail.OrderId = orderId; - orderDetail.ProductId = productId; - orderDetail.UnitPrice = unitPrice; - orderDetail.Quantity = quantity; - orderDetail.Discount = discount; - return orderDetail; - } - - public static Product Product(int productId, string productName, int supplierId, int categoryId, string qtyPerUnit, decimal unitPrice, short unitsInStock, short unitsOnOrder, short reorderLevel, bool discontinued) - { - Product product = new Product(); - product.Id = productId; - product.ProductName = productName; - product.SupplierId = supplierId; - product.CategoryId = categoryId; - product.QuantityPerUnit = qtyPerUnit; - product.UnitPrice = unitPrice; - product.UnitsInStock = unitsInStock; - product.UnitsOnOrder = unitsOnOrder; - product.ReorderLevel = reorderLevel; - product.Discontinued = discontinued; - return product; - } - - public static Region Region(int regionId, string regionDescription) - { - Region region = new Region(); - region.Id = regionId; - region.RegionDescription = regionDescription; - return region; - } - - public static Shipper Shipper(int id, string companyName, string phoneNo) - { - Shipper shipper = new Shipper(); - shipper.Id = id; - shipper.CompanyName = companyName; - shipper.Phone = phoneNo; - return shipper; - } - - public static Supplier Supplier(int supplierId, string companyName, string contactName, string contactTitle, string address, string city, string region, string postalCode, string country, string phoneNo, string faxNo, string homePage) - { - Supplier supplier = new Supplier(); - supplier.Id = supplierId; - supplier.CompanyName = companyName; - supplier.ContactName = contactName; - supplier.ContactTitle = contactTitle; - supplier.Address = address; - supplier.City = city; - supplier.Region = region; - supplier.PostalCode = postalCode; - supplier.Country = country; - supplier.Phone = phoneNo; - supplier.Fax = faxNo; - supplier.HomePage = homePage; - return supplier; - } - - public static Territory Territory(string territoryId, string territoryDescription, int regionId) - { - Territory territory = new Territory(); - territory.Id = territoryId; - territory.TerritoryDescription = territoryDescription; - territory.RegionId = regionId; - return territory; - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Order.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Order.cs deleted file mode 100755 index 616daa2c2..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Order.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace Northwind.Common.DataModel -{ - - [Alias("Orders")] - public class Order : IHasIntId, IHasId - { - [Alias("CustomerID")] - [Index] - [StringLength(5)] - [References(typeof(Customer))] - public string CustomerId - { - get; - set; - } - - [References(typeof(Customer))] - [Alias("EmployeeID")] - [Index] - public int EmployeeId - { - get; - set; - } - - public decimal Freight - { - get; - set; - } - - [AutoIncrement] - [Alias("OrderID")] - public int Id - { - get; - set; - } - - [Index] - public DateTime? OrderDate - { - get; - set; - } - - public DateTime? RequiredDate - { - get; - set; - } - - [StringLength(60)] - public string ShipAddress - { - get; - set; - } - - [StringLength(15)] - public string ShipCity - { - get; - set; - } - - [StringLength(15)] - public string ShipCountry - { - get; - set; - } - - [StringLength(40)] - public string ShipName - { - get; - set; - } - - [Index] - public DateTime? ShippedDate - { - get; - set; - } - - [StringLength(10)] - [Index] - public string ShipPostalCode - { - get; - set; - } - - [StringLength(15)] - public string ShipRegion - { - get; - set; - } - - [Index] - [References(typeof(Shipper))] - public int? ShipVia - { - get; - set; - } - - public Order() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderBlob.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderBlob.cs deleted file mode 100755 index 69d179454..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderBlob.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using ServiceStack.Model; -using System.Collections.Generic; -using ServiceStack.DataAnnotations; - -namespace Northwind.Common.DataModel{ - - public class OrderBlob : IHasIntId, IHasId{ - - public Dictionary CharMap - { - get; - set; - } - - public Customer Customer - { - get; - set; - } - - public Employee Employee - { - get; - set; - } - - public decimal Freight - { - get; - set; - } - - [AutoIncrement] - public int Id - { - get; - set; - } - - public List IntIds - { - get; - set; - } - - public DateTime? OrderDate - { - get; - set; - } - - public List OrderDetails - { - get; - set; - } - - public DateTime? RequiredDate - { - get; - set; - } - - public string ShipAddress - { - get; - set; - } - - public string ShipCity - { - get; - set; - } - - public string ShipCountry - { - get; - set; - } - - public string ShipName - { - get; - set; - } - - public DateTime? ShippedDate - { - get; - set; - } - - public string ShipPostalCode - { - get; - set; - } - - public string ShipRegion - { - get; - set; - } - - public int? ShipVia - { - get; - set; - } - - public OrderBlob() - { - this.OrderDetails = new List(); - } - - public static OrderBlob Create(int orderId) - { - - OrderBlob orderBlob = new OrderBlob(); - orderBlob.Id = orderId; - orderBlob.Customer = NorthwindFactory.Customer("ALFKI", "Alfreds Futterkiste", "Maria Anders", "Sales Representative", "Obere Str. 57", "Berlin", null, "12209", "Germany", "030-0074321", "030-0076545", null); - orderBlob.Employee = NorthwindFactory.Employee(1, "Davolio", "Nancy", "Sales Representative", "Ms.", new DateTime?(NorthwindData.ToDateTime("12/08/1948")), new DateTime?(NorthwindData.ToDateTime("05/01/1992")), "507 - 20th Ave. E. Apt. 2A", "Seattle", "WA", "98122", "USA", "(206) 555-9857", "5467", null, "Education includes a BA in psychology from Colorado State University in 1970. She also completed 'The Art of the Cold Call.' Nancy is a member of Toastmasters International.", new int?(2), "http://accweb/emmployees/davolio.bmp"); - orderBlob.OrderDate = new DateTime?(NorthwindData.ToDateTime("7/4/1996")); - orderBlob.RequiredDate = new DateTime?(NorthwindData.ToDateTime("8/1/1996")); - orderBlob.ShippedDate = new DateTime?(NorthwindData.ToDateTime("7/16/1996")); - orderBlob.ShipVia = new int?(5); - orderBlob.Freight = new decimal(3238, 0, 0, false, 2); - orderBlob.ShipName = "Vins et alcools Chevalier"; - orderBlob.ShipAddress = "59 rue de l'Abbaye"; - orderBlob.ShipCity = "Reims"; - orderBlob.ShipRegion = null; - orderBlob.ShipPostalCode = "51100"; - orderBlob.ShipCountry = "France"; - - orderBlob.OrderDetails = new List - { - new OrderDetailBlob - { - ProductId = 11, - UnitPrice = 11m, - Quantity = 14, - Discount = 0.0 - }, - new OrderDetailBlob - { - ProductId = 42, - UnitPrice = 9.8m, - Quantity = 10, - Discount = 0.0 - }, - new OrderDetailBlob - { - ProductId = 72, - UnitPrice = 34.8m, - Quantity = 5, - Discount = 0.0 - } - }; - - orderBlob.IntIds = new List - { - 10, 20, 30 - }; - - orderBlob.CharMap = new Dictionary - { - - { - 1, "A" - }, - { - 2, "B" - }, - { - 3, "C" - } - }; - - return orderBlob; - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderDetail.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderDetail.cs deleted file mode 100755 index 176d9c76a..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderDetail.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - - -namespace Northwind.Common.DataModel{ - - [Alias("OrderDetails")] - public class OrderDetail : IHasStringId, IHasId - { - public double Discount - { - get; - set; - } - - public string Id - { - get - { - return string.Concat(this.OrderId, "/", this.ProductId); - } - } - - [Index] - [References(typeof(Order))] - [Alias("OrderID")] - public int OrderId - { - get; - set; - } - - [References(typeof(Product))] - [Alias("ProductID")] - [Index] - public int ProductId - { - get; - set; - } - - public short Quantity - { - get; - set; - } - - public decimal UnitPrice - { - get; - set; - } - - public OrderDetail() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderDetailBlob.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderDetailBlob.cs deleted file mode 100755 index e4404aa4f..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/OrderDetailBlob.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -namespace Northwind.Common.DataModel{ - - public class OrderDetailBlob - { - public double Discount - { - get; - set; - } - - public int ProductId - { - get; - set; - } - - public short Quantity - { - get; - set; - } - - public decimal UnitPrice - { - get; - set; - } - - public OrderDetailBlob() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Product.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Product.cs deleted file mode 100755 index 5cf3eb6cd..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Product.cs +++ /dev/null @@ -1,85 +0,0 @@ -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace Northwind.Common.DataModel -{ - [Alias("Products")] - public class Product : IHasIntId, IHasId - { - [References(typeof(Category))] - [Alias("CategoryID")] - [Index] - public int CategoryId - { - get; - set; - } - - public bool Discontinued - { - get; - set; - } - - [AutoIncrement] - [Alias("ProductID")] - public int Id - { - get; - set; - } - - [Index] - [Required] - [StringLength(40)] - public string ProductName - { - get; - set; - } - - [StringLength(20)] - public string QuantityPerUnit - { - get; - set; - } - - public short ReorderLevel - { - get; - set; - } - - [Alias("SupplierID")] - [References(typeof(Supplier))] - [Index] - public int SupplierId - { - get; - set; - } - - public decimal UnitPrice - { - get; - set; - } - - public short UnitsInStock - { - get; - set; - } - - public short UnitsOnOrder - { - get; - set; - } - - public Product() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Region.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Region.cs deleted file mode 100755 index 0407e91be..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Region.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using ServiceStack.Model; -using ServiceStack.DataAnnotations; - -namespace Northwind.Common.DataModel -{ - - public class Region : IHasIntId, IHasId - { - [Alias("RegionID")] - public int Id - { - get; - set; - } - - [StringLength(50)] - [Required] - public string RegionDescription - { - get; - set; - } - - public Region() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Shipper.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Shipper.cs deleted file mode 100755 index 8176cc258..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Shipper.cs +++ /dev/null @@ -1,38 +0,0 @@ -using ServiceStack.DataAnnotations; -using ServiceStack.Model; -using System; - -namespace Northwind.Common.DataModel{ - - [Alias("Shippers")] - public class Shipper : IHasIntId, IHasId - { - [Required] - [Index(Unique=true)] - [StringLength(40)] - public string CompanyName - { - get; - set; - } - - [Alias("ShipperID")] - [AutoIncrement] - public int Id - { - get; - set; - } - - [StringLength(24)] - public string Phone - { - get; - set; - } - - public Shipper() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Supplier.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Supplier.cs deleted file mode 100755 index c3a602ecf..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Supplier.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - - -namespace Northwind.Common.DataModel{ - - [Alias("Suppliers")] - public class Supplier : IHasIntId, IHasId - { - [StringLength(60)] - public string Address - { - get; - set; - } - - [StringLength(15)] - public string City - { - get; - set; - } - - [StringLength(40)] - [Required] - [Index] - public string CompanyName - { - get; - set; - } - - [StringLength(30)] - public string ContactName - { - get; - set; - } - - [StringLength(30)] - public string ContactTitle - { - get; - set; - } - - [StringLength(15)] - public string Country - { - get; - set; - } - - [StringLength(24)] - public string Fax - { - get; - set; - } - - public string HomePage - { - get; - set; - } - - [AutoIncrement] - [Alias("SupplierID")] - public int Id - { - get; - set; - } - - [StringLength(24)] - public string Phone - { - get; - set; - } - - [StringLength(10)] - [Index] - public string PostalCode - { - get; - set; - } - - [StringLength(15)] - public string Region - { - get; - set; - } - - public Supplier() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Territory.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Territory.cs deleted file mode 100755 index c2f1afd72..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common.DataModel/Territory.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - - -namespace Northwind.Common.DataModel{ - - [Alias("Territories")] - public class Territory : IHasStringId, IHasId - { - [StringLength(20)] - [Alias("TerritoryID")] - public string Id - { - get; - set; - } - - [References(typeof(Region))] - [Alias("RegionID")] - public int RegionId - { - get; - set; - } - - [StringLength(50)] - [Required] - public string TerritoryDescription - { - get; - set; - } - - public Territory() - { - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common/NorthwindResources.cs b/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common/NorthwindResources.cs deleted file mode 100755 index 65945f796..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/Northwind.Common/Northwind.Common/NorthwindResources.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Collections.Generic; -using System; - -namespace Northwind.Common -{ -public static class NorthwindResources -{ - public static Dictionary Images - { - get - { - return NorthwindResources.k__BackingField; - } - set - { - value; - } - } - - static NorthwindResources() - { - Func func1 = new Func(null.NorthwindResources.GetImageKey); - Func func2 = new Func(null.NorthwindResources.GetImageKey); - Dictionary strs = new Dictionary(); - strs.Add(func1(1), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF00000000000000000010000000001000000001001000000000000001010100010000100100000001010001000000100100000100000010101000100000100010000000000000000000001000000001000000000000001000000000000000000000001001001000000000000000000001001001000012507070100000001000000001000100100000010000001000000000100100100000001001010101010000000000000000000001001000100000101010101000000000000000000000000000000000000101020525363777777777777753530100101000100000000001010001001000100100100000000000100000000000000000100010001001010001000000010010000000000000100000000000000000000000000000001014343577777777777777777777777777770100120001010100102000000000000000000000000100100010010000000000100010000000000000000010010000001001001010100000000000000000000000000000001021617777777775757535353525777777777777770150120000100010101000000000000000001000000000000001001001000000000010010000010010010000101001001000000100000001000000000000000000000001417777737617376377775767771707752777777776340161210300000000010000000000010000000000000000000000000000000000000000100000000000100000000000010000100000000000000000000000000100503677577571705014000000101070717775777777775334101400010101010001010010101000000000000000000000000000001000000000000000000000000000000001010001000001000000000000000000000000010357353000000000000000000000000000171777777777470612101000000001000001000000010000000000000000000000000000000100010703010101210000000000000000000000000000000000000000000000101034350000000010653435777570477474700000107757777171000000101001000101000101010000100000000000000000001041477110131035750020040477301000100000000000000000000000000000000000000000010004014176577707000067777777776560404007371734361701400001241000001000000001000020400000200000101747767777000101073777577777775372100000000100000000000000100100000000010000010000037676476700004000577470416717477421405000434140343000565120510100301014002107171370701437777777775777777112103177777777777705757771010000000100000000000000010000100000101000470440440671007477776777777614060600742524001777777747646776752060250003021716737777777777777774747727574777001016777777777767173317703000101010000000010000000001000000000000420460200077427477767777777775677777746474656606767777665746776757151253507166737777733746777577777777572776771100517777777767776015713141030020001000000001001000000000010100067440044047761477767776706767777674765673470657505767375664746757777271252167717733771737776777677567476577577121103775777777776717027753121010101000010000000000100001010000010767060004776747776776777756776777777777042477676067777467474747676777565256531311771177376477777576757777747710110701777777767777401717340000000000100001000000000001000000101004776540666050777677657777677470774777776747664607777376747476777777677717173735377717737747777777777774774770011271077777767777763171735210121010100000000000000000000010000000300406767757676775077006767477774774777774747770476777656706746777657777777777777777777737667777476574774777771001031777777776767741371771000000000010000000000000000000000101005707442567656176006767004770476707700767770000477747734656446745677676777777777777777777375667777777777777777773100010777777777777771753521010101010000000000100010000000010007777712152503004670077774767427047247776577564700076737747670474277777777777777777367777777765777777777777434777750757775377767676770172773100000000001000000000000001000101007170701614204046007746040676167470774167743656777740077776067407465677677777777777757717777737476775716161243410303077777777577775210000011350001001001000000101000100000100002100171525675070074340670005004076700706570757777767770077744746466567777677777777777777777773776777610000000137775350317777773777737750701000101021001000100000000000010100010010300067777761650604065047604760746404776406705656776770077764750474747677777777777777777773733747777773011735777777777777777757777777777767412041001001000001000001000000010001000577744140000607406706767676776777776477756767777447700774076646764777567777777777777737373737764677747753527777776777777777776365735353513010300120301010000000000000000001000107000210006147767674646040404040066667767677775476777046644644044456776767777777777733737373776777776774244777377717712777165357577534242040010010010000010001000000100010000100300050000146664000000101030734352101100065677767077770047604774377676777767777777777373737333756477657075377100770770177776525271673001012101210301001030000000100100000001000005000060046160004000125343510110101000000000007740000047744733737377757677777777777373737377737656757777777373101676770777717775671773001010300000021021010000000000000100000000100077400000414021414000000000000000000000000000300000777777773737377677677777777777373737333735677677777377710177777717774705271767340300000010101000100000100000100100000001014005660000000737560600000000000000000000000000004730777773733373737777747677777777737337353761666777777737737017771677077353777574735310012101000000010010100000100000000010004300065400000000400141254140404000000000000000000037737776773777373733777677777777777677646746565756747777773773017017710765654352735770017010303031010010000000100001001010030704000660000000000000040000000000000000000000000007777514673373373737777777476777777777474644764666776777777772711031076117307374357477373010341050043030012100100010100100012500000047000000000046742000000000000000000000000077776677777377377373733737767777777777767645676507574777657610057121101731611574777637735105270125213010050210100001070210301650000000640000000006776406776464000040641434177777767667614737337337373777777767677777776564767474664667477761775271112116101002331211101052721016120140161034106010173075617770000570047400047400446000000467770504777767173573756767776767737737773737377776777777777776564746765477576777176700774656474731010011000001250165214716170121012011070777173777400063770040000760467600000000740760600777067777777676767676767337333373737377747677777777776767747424676747677157701677677676131331213131301371317310312161525053073077777777700047577700000006006760000640400006474046740777777777676767676737737777373777777767777777777674746767467477777743670175305325352527135335353170143414371617130131211777177777777001737770006760476677047064466400047640077747777777767676767673773373333737373776746777777765467674704747674765375610731773573752534737417017035303130101010030001427777777737770047777770047460704644064400004640067004767077777777767676767673377377773737777776777777777766565665670767767775077007563153347370731013213617034343434307031417121177773777777740257737700027447000064000000000640064006760777777776767767767773373333373737777476777777777746765674464747767763477027172753717175777757757357171717171717433616163777777735737400737773400460660046000000000004000600676747777777776766766767377377777373737777747677777776756567467746765777117100537153353773777777777777777777777777737757737573777773773772047777350000474044600440000000000040047774007777700667677677633333333333737777766767777777777667476564657476760600007353375373177777777777777777777777777777737777377733753777740007177770000664024640640000000000004646700477777007767667666777777777773737777777777777776777446467565676777535373525317137177177777777777777777777777777777775377773753771737700076737350000000474664665646644400400464000077700067677677773333333333373737776676777777777767777766767765677771713175217037173777777777777777777777777775375377173753777377773700057777004007477667764766767667467600000004770000767667666677777777777337777775677777771777772604000404067761171613131535353717777777777777777777737753777777777753773717735374700000500670446677777776777776777776561004661000006767767777333131101100777777666567777567704040505140777716536353147173135371777777777777777777577577777777777777777353753777371700000001776040404040404606076767776170000470000071101100100000000000110157177776777776470124100002530004777111301313017535371777777777771771737377773777377753773717353252165376164464265700400000000000004040040076774000440000777500750000000000000000017347766777746564100000000400300652513530753303170737777775777777777777737777777773777753757035353134317137313533000046440000004400000000053770000000000077343100000000000000000004135777775676176000700000004044213052153115353371357777377737737775777777573757777777353213503161617163521657257000006700060042400000005273710000000000007577000000000000000000531117777665447405244000000040031501313030721353537737775777577753737717737777777777777035343343131303103171317337130100000567000200000031756000000000000000077771012100101101131117133375466747465707047000071502161011531534353517753773737353777737777777777737537713503353170717173561343105307030525370047014161717433700000000000000000000101011770000006402737373767456467777777773065773510137343531317073737773775777773777577375735737577777343375377373673071316352731717173137000007737352713574000000000000000000000000464000000046733737373446647777777777740007373737110310343537171773565373537577177375737777777777773353737717175357727753717163737357770000071735371677700000000000000000000000000460004004676173737374745777777777777004631713112031213131317337177737777777377777777777777777777775377737777377371717353773571747737377617771677773570000000000000000000000000400400000000406337333464673777777777774007733373311001013135317177737775377377777777777777777777777737777573777377777736771773773716717535343373525773700000000000000000000000000000000000000037337374433373777777777700007740010313133173137337357753777777777777777777777777777777737737775375737373717367171653735727367374753737174000000000000000000004600000000000000000373733643773373777777777404073000000000012137331737377777777777777777777777777777777777577773737773757575735317273353531757535737377576300000000000000000000424400000004000040007373375733337333377777770000700000000000000000070477777777777777777777777777777777777737773757753757373737777775357273673373773535737357000000000000000000004406000000000404004037337333773737737377777700400000000000004006404043777777773757777777777777777777777777773773737773777777717371737357171752573473721777340000000000000000000006446400000000004004337337333373337337337777100004705340100016503777747717717757777777777777777777777777773757757773577173577775777577377773777373757777177700000000000660000640047674000000004000003737337373377337373737774040077760004000000044004737777777777777777777777777777777777773773773577377777377377377377537177535757373537710000000000004040004640604600000000000400073733737337333737373777700000047477420000000000435777777777777777777777777777777777777757777777777777777777777777777777737737377577777000000000004600000460064600000004000000000373373337337373737373777600000000000550043617777777777777777777777777777777777777777773777777773777777777777777777777777777777737737777000000000000000000000406400000004040000003373373737337373737373770040000000002777357777777777777777777777777777777777777775777777777773777573717775777777577377777777777777757340400000000000000040004064000000000000000073373373337333373737377750000000000057777777777777777777777777777777177775737577737777777735777773777773773775377377735735735375737737000000000000000044600406060000000000000046337337337373777373733777007460000000377777777777777777777777777777777737737777377777377777737371775353753753777777777777777777737717750000000000000000000000444404400400000000063733737337333337373377774067400000000777777777777777777777777375773777757777177177377735777777777377777777777777777777777777777777777704000000000000000000006000666066000000004433733337337377333377777700676004004407777777777777777777777777777757357375377777775777737777777777777777777777777777777777777777777772010000000000000000000040004404440000000000373737337337337377777777704600674660077777777777777777777777777737777777777773773773777777777777777377377777737777753777777777777777750040000000000000000000000460460000000000463733733733733737777777770047464067000777777777777777777777777777777777777777777777777777771737177777757377377753777777777737757773737000000000000000000000644640000460000000000073373733733733777777773750660760400017777777777777777777777777777777777777777777777777777777777373773777357173775377735737777377757777240000000000000000000606400000000000000000373373773733777777777737604746400406057777777777777777777777777777777777777777775775771733735377757177175737753737537777757777777777750100000000000000000046540000000000000000007337333333777777777771771066067674767677777777777777777777777777777777377777777377737777775737573737736373717375773777373737377777371200400000000000000000046000000000000000000073737373777777777777737700656476464617777777777777777777777777775757777777575757735773735371737357737575357635733577377577777773777775000040000000000000440646000040000000000000733733377777777777777137106606476400077777777777777775777757357777777757577377375777775737777577735737377371735773757073737175777777370000000000000000046764656546400000000000007733737777537777777777774474407467005077777777777775777757377735737717737377777737777371773737373773577535373437073737757577737353777700500000000000004676474266640000000000000047333777074747777777777776567642766027777757537775777371735777777577777777577777775377777777577577777737777577737757757373737777775777000000400000000067407604040000000000000000077777103716173777777737676665646470577757377775777375777777177377777777777357357777773737777777371735737773735753737377777773577377370004000000000000666424604040000000000000000777777007677477777777767676767474003577777777773777777777777777773773573777377773777777577773777777777771775773777757353753577357777770010000000000040406404000244000000000000000777370141477567777777762476767660067777777773777777737773777753777777777777777777777777773777777777375367377375357367767767737673477140240000000000000446400004660000040000000007737520077772757777770040047667767177777757777777777777577737777757777717753717717777777757753535357777775775777777535753735757177357005004000000000000000040400476440464000000007773401616575777777006440004764256777377375775375735737777777737737737773777777777773777777777777771771777777777777773775777377577773000000040000000000400000000000067400000000077771425777367777700400060006765377777377777377737777777735735777777777777777777777757777777777777777777777777777777777777377377353770070040000000000000400000404000040000000000077770525765777777004004040440065773775717377777777377777777777777777777777777777777777777777777777777773737371775377773775657527777500004000000000000000000442424400064000000000777724077576777700400600007000373757373775775375375737777777777777777777777777777777777777737777377373577575777777573575373733771737300700004000000000000004646440000672440000000777507567657775000444040644047777377777773777777777757777777777777777777777777777777757377771777375773737373737373773377753575377577400004000000000000000000400000040440640000004777407757777700404246044604375777757737777777777777777777773777777777777777777777777377775773575737175717175717571757253372734372773007000040000000000000000000004600464000000007772525677777004704064240124373777377577777777777777773773777777573577777777777757377737373777373777737367363727373735356171737177175000400000400000000000000004600000400000000047710477777700676006564640577777777777777777777737773777777577177777777777777777377735775775377757173717535357174352537737373717717730070040000000000000000000040046000000000000077777711357047600446500072777777777737777777377777777573573777777777777777777777737777377377177377757773777377737777343574356773737710060040400400000000000000000400000000000000771571715356770446002470757775773777777377757735735773777777777777777777777777735777377777777777777737573577177535357773777371747527710160000000040000000000000006000000000000007771353777767600056440042735373775377375773777777777777777777777777777777777777777777777777777757377773777377737777735777537577373717700104004000000000000000000440000000000000077171357777674006064214357577775737757777777777777777777777777777777777777777777377777777777777777777777777777777737777373777737577777300424000400000000000000000000000000000000777174777756765404051425373735737777777777777777777777777777777777777777777777777777777777777377777577777777777777777375777737777353777100100400040400000000000000000000000000007717137577764767404061777777777777737737777777777777777377777777737537777777777777777577777777773773777737775377177577737353753737770737100400400000000000000000000000000000000077717177777467760030065377577777777777777777777777377777777777777777777777777777777373735371777775777177753777777737717757775375753573536100050040404040000000000000000000000000771717177720767000043737737737737757737773773777777777777777777777777777777777777577777777777737773777777777777777777773773737737377357753000004200000004040000000000000000000047773537777504004104375777573757777371777777777773777777777777777777777777777777373777777777777777777777777777777777777777757777777377373777200504040404000000400000000000000000077153577770000016075375373777737177777717717777777777777777777777777777777777777777777777777777777777777777777777777777777375373577177573535300100040104004000040400040040004000177353577770070007277377777537777753757777777777777777777777777777777777777777777777777777777757777777773777577777775377537727576377717252734120050040400404040000040000000400007735353777005006535357777737771773777377777777777777777777777777777777777777777777775737777377777717377777777773777777777753753735752771775173500007000040000004004000400400000477717177775004353777737377773777777777777777777777777777777777777777777777777777773737757377173717777773577737777773777773773777773771773136343700000561040405004000400400040400775317777700367771737577537757777777777777777777777777377777777777777777777777775757717777777777737177577377777775777773777353717773771776535353716000047000404004000500050010001735717777761717777573777777777777777777777777777757375777777777777777777777773737737773753777177577737777537537737777757777777771757372537737271717100005252004004040604004040077531717777177777777777777737777777775777777777777777777777777777777777777777757717753757775377737737773777777777777777777177173777737753770775363774320000416524100000400400004773717777777777737777777777777777377377777777777777777777777777777777777777777737773777773777777777577757377377777777377377777753737753771775375757377577600000106141410143405007757537777777777777377737777773777777777777777777777777777777777777777777777777753777737777777777777737777777777777777777777377777573777777377373775373735373000000000400010000077377717777737777757757571777777777777777777777777777777777777777777777777737773777777777777777777777777777777777777777777777777777777737775777777377775777777777161612161637777777101777777771771773777777777777777777777777777777777777777777177577377577757777777777777777777777777777777777737777777777777737737775773737717717771737737537777777777777777775717177777771777777777377773777777777777777777777777777777777777777777777777777777777777777777377377777377777777777377577177537777777373757737737735377735737737377737775773777377717177777777737777777777777777777377777777777777777777777777777777777777777777777357537537777577773775753573577577537377737753757357757357571753777171735735775357537737571777771717577777777777375777375735377377775377777777777777777777777777777777777777777777737777771773753757377377777737777777777773777377737737737377375377777737573537737753773777777777177777777775775737757737777777757377777777777777777777777777777777777777777357777777777777777777777777777777773777777777777777777777777777777777537717773777777777777577777717711737777173737377777377777777177377777777777777777777777777777777777777777777737377777777777777777777777773777777777737775777777777757777775373737777773777377377537737777777710101417777757757377777771735377777777777777777777777777777777777777777777777777777777377777777377377777777777775775775775737777717717371735377575735373757175365737777773737777777773617377373775737773777777777777777777777777777777777777777777777777777777377757177573737777577773575373573737737777773773737777777777777737373777175337637173573537777577717777753775777775377777777777777777777777777777777777777777777777777777777777777773737773777573573753777737777777777773773777577577737353717353577175217437753577377377771737373773777375377375377777777777777777777777777777777777777777777777777777777777777757153471773737373773771737771737377777777777773777737577777777777377737733717373717177737777777577777375377777777777777777777777777777777777777777777777777777777777777777777773737773771757577573577377717777575717377777777777377773717353717357175717577717753777175773773537777777777777777777777777777777777777777777777777777777777777777777777777777777753473535377373717353717171735373737777777777777777737777777777777737737737353735371737737777377777777777777777777777777777777777777777777777777777777777777777777777777777777777773777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777773535000000000000000000000105000000000000C7AD05FE")); - strs.Add(func1(2), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF00000000000000777777777737125353313731773543110105302502105313321714317343717135371373147317317171717121135301610131217777777770146765074747776567616774776565774040371737031611737710110100007777777777717435357353531713343030301103112161705353317353343717135371370317717737371734125031131352171777777714066544724767776774747657700577764774340735757100371507530210777777777777777731737317353731704311151303112110431731305317314171731717171354731713535373107131703011317177777770664576076567476404776147676777674174074740573312411002173611137777777777777353167171735337173531163125351615307173171737171707373173733537023177373737351611010113521737777775245006047474747407777777767657775747477416560075141200115351103077777777777777377143161735717353463107113131303343353171317373107177317173171477135353717370737312503173577777344760547061604760777777777777764677776007470774033001010035212100777777777777777173563535335371731053130707071351165343171701773417357717177130177173717717134101713353173777747640076047447000777777777777777775667570467760774040301010101053107777777777777773712531335337171735301531313134334135353361371350735331737137707137353731737433731717377777776040000407647604777777777777777777460547743565054776011001031213010077777777777777353561737534717337161352171712717103737335137137061373573171711073531737171710351171735373777704740460464746777777777777777777777040667746776007751300530101301300777777777777777373071713713717135241311030711317605117533517171075353357373734173173537373735373773777777770460464740406757777777777777777771777640577740457777000131035310701007777173777777775353431613717357131630731713735311637317173737171235353353535725377777777777777777773737777567404706425046777777777777777757777775246577777767711350131030311300177777357777777737350771731171337510531071351613735534317131717305737357377373077777777777777777777777777776540060405646777777777777374777377777774767777747771076035031110121000173735777777773535307131717373513243357317073171163353712571735073171733535735777777777777777777777777777704600564064077577777777777737777777777424577756771147741121161037100017357733577777773731603521725153251071335213317077071335373371732177373573737777777777777777737737777777776460464604046473777777777777777777737777567776657167647421121121103001035775737377777571711613531337353371435135351713131471731171735716171773753777777777737777777773777777777774740405674747777777777777777777377737176567757370470067070121121100010733531717577777371734173535353353107127713631735370371737173537107377373777777777773777377377171377777777444006640464677777777777777777777777777756777774747047741137112116100305737161373777737173107313531735352471713171173537017173717353731637535777777777777777737737737337177777770760650406047777777777777777077777373437777770567674776012101611210010131717135357777713253425343525353131031717373537171617171371717750537737777777777773737737733713537777777744404656440467777777777777777777377771577774764044774470717131071301210161335253077777757131035313137377534721717173537371637171733737343537777777777777777737737753713137377777764604646560457777777777777773777373001777574777764477611301121010001017135131314377773131716317353135313001717353353717165317371713573173777777777777777737573533373353717777777465404006400767777777777777377735000137776067664707640341216131300300035253521707577135271653531161773716173371375335373531717173757316773777777777777773773737377171313773777770460000440066757777777777777773700010577756764100674031311310100010103131313521073777731131052773171371310715377135737171773353353337717777777777777777773773737333131353353777776764007640456006777777777737371000013576644566565671341210131300010103521703170073735371730311173171371352735377335373725357353757177177777777777777777773737377173317173773777344564046466404444056477777537301000373405606746764011331352171001201013523152107177735303504373171357017005335217135307107317371337377777777777777777773377373137317133353353777706400004400676000640677471001000171464767444564031301052117100301001703117211617173531713035316127331710737171717731734071737171777737777777777777777777737377735333531737777717746654047046440044700465700016113000564440676653130171311303001010303152311340217173613530435313513531210717313613535312131713771777577777777777777777373735333337113713131377777344660240404740064000007003012446064000065641301430121217100303010117214341305030713521770035312153431340315251703537140713531737773573777777777777737373737171337311317171771777714540440064600464074764547407644764474661061711131171213001100121311331330433171353713107121713013170071631331353113013073173537752777777777777777773737337373131371731317707377776646600000000400464006460040000476461100121212163011710430103104341170510350307131714035353017317034353153417125240735317537717377373777777777737173537713137113133135371377737771404047400000000440040000046564612110016111211111303013012110331333130343135134352334031251210717107353213717131300131733737777577777777777777737173713737133713717131774353737777776646444600006000046442564670513430031611030301700012112131170552530043032531351307171335313137007153513035211071631535737716173777777777777737373733733531313133713707375737737757474604640746406546442411030301104111210110303104012112533130313134315113171371407135031707110712313253121520031173733537777777777777777737737373717373313533531177165373577777737777574746445652413513125110130012121121210110013152113152531725005303616343160335303521310243535161134112143537371777777173777777777777731737737313171731353137350737173717352573717737353737171343070110212100210130101013020210311612313171134121711311353134135311353531061303116113010013535373537370777777777777773777371737373331371335117340537153717352573737517340707317351130211011201712103103011001312531711725371124301253717135035215271212170171703130313030703535373777757377777777777773735733717171311371333173163537353707142570532717161352513307111211211401113502101211041713030371135363105331301212530431731135353107031100110411000713737177377377777777777773773733771733317131335353170143417217317073173535317071353250303071021120120301311303124330171711371133150435053537171703713107031316053160317031301071371717717734777777777777777377377337371331351733137124331335351700717053530700714351131501103112107111131030105001153012125363757312131303113121051707131716110210110101100300317137373737713777777777777777777777777377373331537174101170535321705713725353507331216121312110710003070125103130061213110133151317052521716161370213134310313514310303121310140307171717735653777777777777777777775341307071331313130060130305313003411310303014105310101012101214311130121103130131412130757377735213171213135105350311251212021030110101030035317337735731777777777777777777757171310101373535317100112535321610613161035110031310130103010131003030013112105007031301011317731730717031711612012135035335310503110212130104713535713737167377777777777777777737310010135153313530003011010511001212117121243001030012101103010051013100301130011030130077737771750731731631350717133031035302110211010121303533733753773177777777777777777777510100000017335331711043030312121041153010101001121031010102103010303100311012100121010010731737773731731711531300316153171307116111035031101433537533771774377777777777777753012110111000015617137200103110311121203103031210021110010030101010000103110121013000130131017771777771471352373053525313317037130612102103121312573713753777377773777777777735035355371731510001717701100314311430100101311011021102031211011010130010100312112100030012003037777737377335375317330131351631713150110311301535017353777377377177777777777773513513130111053351101771130070131303131053170161307050311101030102121000121211010010101013101101777777777716537131731570716331531352352311210713013343773777375377577777777777713171310135371315373103520010113161311032072113131110311212121012110110031101121213030003100100307737777773717137171731310315331707353014301311253353573573717377737377377777773177125353131735335357103131202521135271510113412163105211111113110121210003100111011100101301010177777377775637717331737071735213317317431734121314317373777777777757777777777317313113107173777531737150101013173031133043713353110631777377777373111001310312121030012121000210777777773733171316171611073135351731703101013171733525777777652104277777377731713535341717353537357571310100010351353250310351317377577525010505357730301031010112100210100101037377777777757335735331734353717371371707131343121753177050001040014077777737713713011331357777775337175000100010370351314771377775713400100000000000417531013130313051130100010077777777777345331735353125353310375313430521353531377770000400140014057777777351717351071353771775357331001111111353353211377777434001000000000000000003531051014110030100100210777777737735335731735217103341737137353413110313535377104700106756207747773537371710325175375777317735110110001107317351677771611013400100000000000000000703121313003012100010017777777777773433173131710735333113710305303431073737770777406456065570014777753103535113137773711771101110010100171771737777171607000010001000000000000000130110300611101010011077737777773717717353731730537516371737125313173171777575646747676566756704773757110717757777773773130000111001110771377777516101105010000000000000000000000532131101721000012000777777773777717317353431343133317171717035307173773777775747400456556756701773737711010343571513571110010010001001777777777357343034341010000050000000000000150121001121100010107777777777771635371353735343535353371335431713535377777770006047606677674073777777771711113173753000001000010100177777777535305141000000401070000000000000000313500310100100010077777777777373537037331530173537317137523173773737777777747650460447465677777777777777777777777300001100000010110777777573530530374175353107057310000000000001710071030010101010777777777377753713713573716137131733533507171353777777777774640540761465477777777777777777777575000000000000000007777777753577575031035257053007700000000000003100121121000300007777375777737343711713131716137171753533437173773777777576700766704465625777777777777777777777737000000000000000077777777773537077577561763571001000000000000053010121001000110077777737777773531733536173253717373373711717353777777777755046564476767477777777777777777777777111300000110101000777777753577753712707100142070070000000010010300713110100010000375771777373534371353317315171731717171707353777377777774766474677644747777757777777777777777717370100013000000007777777777777350574100005251007100000000000000611210030001000017737371777773716135271711732533537373737307377177777777777752424464765677777777777777777777777777141010011100000077777777777770712170710301701617000000000130010531031010101001071771735717777136131173731716173531717135353737377777777747654476744644777777777777777777777777713001011010100100777777777777570570110414161600071000000004170003071011000100000371737137773733417373171371217137373737737771777777777777777467444604677777777777777777777777771700000001010010017777777577757353052431201001015340000000012100171121200100101011735717773375353735317137131613717171731717377377777777777600742076565677777777777777777777777737100010110100000077777777777305705251525034000702100000000005037103101100010000037133710775737352135237317350713737371773777377777777777765046546046467777777675777777777777773710113110110110001777777777775730701006125010100050000000010030013103000010001010717717373737735357135117717334353537373773577377777777777567746644650477577775777777777777777750131100000100100077777777771775711753010530400001010000000010010703113100010000003710735357353737037333713317137373757377173737377777773776564745204646757774777777777777777773313010010101110007777777777577771650341252051012104200000000007001352100101000101017373171737373531617171371713435317337537357777777377377756470064404657777777776567777777777751111101000110011377777777777577161035214105200040101000000000101031013010001010000735377335773773535373173173353737737737737373737377375377777447476704677777775777777777777771371301001001011017777777777537577134104034001001000000000000000700033101000100001003171357331771737160152173171351733717373717177775371737776767460446044777777467774777777777771311111001101017777777777777577756134311012161401000100000000010101012121010000000077337335737377373137335353737363573735373737735337173177756104700046567777777757477777777777117131000100113777777777777776717351410401450101000000000000000016017110100010000010357371773177735371613533371353537373737717353173713717775654065400004677777774707757777777735311010112113777777777777777535757161252161210000010001000000010010310210001001010007335377377353773530713535337337173537373735377311713737765670000004004777765656577777777777531311010111777777777777777777536352141010014340100000000000000010000311010100000001071775335377373737170733735717537373717373735317373717775725650000474046777577777677777777773711311313777777777777777777777575757161050000100000000000000000001001210000100000000377335737737777737313571733733717373735353737731353733770567000007400077777677777577777777735311177777777777777777777777573537010116310100000000000000000000000131010010000010105335173353777371353053331353171735373737373713177737777770016140740004777757777747777777777531377777777777777777777777757347753777717400000000000000000000000010103001000001000035736317357357377317271737373735337171737353777333737377716140141003473777776757465777777773537777777777777777777777777775771757761601000000000000000000000000003100000001001010173317717377377373711373535353734737371717371377777777777502112007047377777756777777777777777777777777777777777777777777771777771501000100000000000000000000000003103010001021016317431635377377173727173373371313531373737377737737777733714005001737377777777777777777777777777777777777777777777777775777776142140100000000000000000000000000110001000101012017713173537377737353117317137137343777373737737373773737373737137773777777777777777777777777777777777777777777777777777777775011210010000000000000000000000000001200100010301211431617353717737353353613733537335373337777733737373373737373737737373777777474240567777777777777737173302137777777777777753435341410001010000000000000000000000010010003010101003173617313737573753353435373135337773333777733737373373373373733737773777756101000507777777777777776140500001377777777777753525210250000000000000000000000000000210010010210303117351314771737373371321733173737733337377333373333373373373733773773777714000404070747777777777400000000000400257777777757170714141001000000000000000000000000001003001011010100617335733135377717137152357333773337333333373337373737377373777377377777435777707477175777777700000000000000005377577777716171430300100100000000000000000000000000010021201210311314121353737173737313253333733337333373373337333373377337373337737777710777775077574707777700000000000000011007377757753717071050140000000000000000000000000000001000101310310035737171253537177317353057733737333333333333337373373337373777737777777775475725777770477770000000000000000003005777677757717070102101000000000000000000000000000121010100310311121312135353343737733337373373333373333333737333337373737373373777777777773470052574177777700000000000000000010077575777771751016010000100000000000000000000000000100030310130307171353433035353773731717373333333337337333333373733373737377777777777777747125352757657770000000000000000001250577777753571252501410100000000000000000000000000110001011013010112130313117312777733323323332337333333333737373333737373737737777777777777140016050257407700050000000000000041003777777777357103000000000000000000000000000000002030003071301213353413437017717737373333333333333333333333333373733737373737737777777777777375017257400747100000000000000001000075777577575307505101010000000000000000000000000010101211035351010313703113733337337333333323333333733733733373333373737373737777777777777777477405670067777000000000000000000007743477777737530302500000100000000000000000000000130300313121213013431353673377373323333333333323333333333373333737373737377777777777777776747640424000474775200000000000000007575707705753553141410010100000000000010000000000013011035217131301703137331373333233333323333333333333333373373733737373737737777777777777756777004774770576705700000000000002177677057777777347130012000000000000003500000000000013125035217050131353137337333313333323333233333332337333333333733737373737737777777777464644640004047406700677505000107161756505777000575357316153050101000000000017100000000000707125131213130137333273313332333233333333332333733333373737373733733737737777777777656740000074067640000575767700416500416777777775777777717535214010000001000005370000000000424133530351302130137333323233333333333333333333233333333333333333773377373737777777757474000004656504704756524057470770071257777777777777571771341431001010000010117430000000007406753071034111013273331333323332333333233233333333733733733737373377337377777777774246740047000064704706760077077574774774577777777777777775347131020500010000035210100000000675740243103130303033323233331333333333233333333333333333333733337373337373737377776564404004064000474404004104747724740776776777777777777774735317435102100010015035700000000004642440043101010101331333323333323333233333333233332333333733373733373737373777777706400000670400000000070470477777577074757757777777777775675775701520510521001431500010000000700040056103121312103233333332333333213333323333323333333733337333737373737373777744470000004041640560046747477757556777417677707777777776567467171353413001006143043401000000074000004640210101001033323033333231333333233333333333333733373737373737337373773774676740460000640646406756777477776775774675447407776774052467747257253143525012107100000000000464270047040121303121333333323333323333333333332333333333373333333333337337373377640444004000004004000046777770707756767775677777657574256477567057357057177171410507110100000000054640676740101001003033333132333332332333033333323337333337373737373737373777774040000600004640000470047677434475034774434774750676705657740400645717377753430001214730000000000600004404042101301333323233333333333333333312333333333733733333733373373737376420000004006040420006406767767477042457707407047765774067764740064163717575251010000573500014425604450000046500210130333131323313233333333333333333373333733373733737337373777745400044004040000405447747747577774050604077447747465765044747604776445777775200010101350102467406470640000046041030113233733312333323323323323333233337333373333733737373373774664400000004000000460467767676776770675424770747725046565677654004476064065351777777777770005470474004000600470001012031323333333333333333333333333333333737337373373337377777000400000000000040000006767477676777765702576004765406770464004604700440000577777777777777750076000000000007407646001211733330332332313333333333323333333733333733377373737373744040000000000040647400477676765657656564047645076567656440756425674004704047777777777777777710400007647600540044650030123333333331333233233231233333337333373733737333373737777000040000000000040004000445740400676472470041674004740400042447560470424747677777777777777777760004047044064600000640171130337303233333333333333333333333733333733737373737737765400400000000400046004600064000400400540470047040076000470047646404004740004377777777777777777040077047707400740000740121333331373323333333333333233333333373733373337373733777046400040000000640040074006004367400407601647400764045607404650470576474040654777777777777777770404400746440044674046002117303137133133233231233233337373337333337337737373777704640000040004040000004400440674400046764064740040410065247000006746645647704427777777777777777700600047004704670400674013031377032323333333333333333233337333373733733373773737400000000000004040074567202400460000007400564706776656065646406004007247044046577777777777777777040460057706000400005674001137117313330333333333333333333333373333733737373377740400004400004000004464044047004747440046564006004454045640474654004744064760006777777777777777777400400674147700707604060307032313733333233233213233333373373337373373737377737740004000040000040400070004406640460707656475004006020064047441600474007476500077777777777777777740000000047464064074004400117313073333333333333333333373333337333337333737373770600460004604000007006464640045061046404650640560056440540064674070465647400406477777777777777774000420000760000434007060003313753533723331333333333323333337337373737373737777704700040640004000044050065000460460074004604006544640046700470640470744006647040047777777777777000400404007704000467444044013073312713330323323323323333373333333333337373737377466400404400654060006460460447474050060000460046064740004474400564464024045240640004777777656744000640074047777047446056700053531713733333333333333333333337373737373733737377774400000000047676404746540000746447465440047406704504004467404046746540470564004740046567765656424064040060777744040610674003312731353333333333333333333333333333333333737377777400004440000464640004044604464647676766746560404046000476776767677776004646400404656676646464644400400640404777600004400460011713000000000000000000000105000000000000E0AD05FE")); - strs.Add(func1(3), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF00000000000000113330735737777704000000000000006060000252000014131315311716037070021240161075371617637506357172512171357170173537160000025214002070000012436167777777173333737171773737377700001111131330131357737700000000000010000050040006331131313310705073430040000003070761617433514356537571773171771716167170604076776775677064253437177777737357531737373753537337113313111111113131235777000043712006767773677777711131531311777377077043125361707171177773563737373563777177371374735716771707717735637700016777476777737531333733537371373717531111313130131316131112163035371350007753477177311137133171331777777770734772516177777717777352575777357377717537533173777160277767777777043635673717737533337171353735737353773713111271131130317013111111131131670073677776771733113113135137777777771470777616777777777175377375377357177773573757073577775677777677770365635777677533753537337371737353377377313111123130131313103131313131711770477670777353533133531331177777777763777177717777777777735357377757777737777353353553737737777777777761771637535733533333135317373753371317371271131111313521313310112131171337003717377771313117113171131777777777177716777777777777777777735353773777777777775773365777777777777767160677747673173717117337335373777177775311123103121113130371131317113313143047765767171715331313133137777777777677777734377777777777437577777357777777777737357530735777777777776071777737317371733733531737177313733737131113313113303511130153311311317343077777773131331171353153137777777735377777777777777777777537737177777777777777777737777767777777777717061617717331337313173371737737373573773103111313103132130133071311311313000617277173171731331313111137777777777757175377777777777736527577173757775777775257537171777735361777253525616717373535333171371737717173753713313121011313113113153131131371310000604167113131171131713131177777775353737736535777173773753752767757377737737777736757777177777776165206353735331317337133335373753737373773111311131311301312130331303113131701070127013353133131713113113171773737773571753773527657765274371717737737777773773753637177777707177716535273533173731713717133717377317177373121131111121130313131031313313531600076507711317153131313113117777777717163763777767753717373136161634777577177757757777567075717776353613437473353131737313313353373731373735311131103111131111301731115313313131120012507317133317131713113137773577737753753435373777675756537535736173777737773773577377736777777677617437173337331737313353353753771335337131111110131303121731073131071313134107612771313535313531311313573757373535375377777567743527253473434357677537577375777735717771717171771707167317131733537317311331373337137131103331313113111113113312133131313503071650131313131531311313173757377757777737437773717377775367343717773537777375773737777777777777777167736535333373173731313133537311313313311111121353011303310335313111331312161677373135373133131135311777377777373717537717777777777725357343634777777777773757757777777777777777716573733171317171733313713317331331313331331130313311113311133173311531371753777717131171117173131311777777777757737717777777777777776347757737777777777777377377377777777777777773777173133333373531313313313331331311121773313311031341373053105313171773777771313537133713131311137777777777377777777777777777775357777775777777777777777777777777777777777777777773313713535373313313131331110103131137701710113113131317331333131337777177731731311311317171131177777777777777773717777777777377737373737777737777775777777777777777777777357777131331313331373131313113111010111773371600771213011305313171143171137777777131713131731313171131777777777777777777777777773577737777774770737777173737375777777777777777777775737331313313137353113103113331111117701677000071513131331353133131331177737753131313531371313131117777777773777777777353535777377771773773775737177777775377777777777777777777377735313313131313373113110111131113171607777000072111111134337113131133771777735317113371310117113177777777777777775377777773777535377357177377777777537777735777377777777777777777133313333131313131101011131113111677077700000000003373131013353533713777373131313135135313631317777777777777371737573773777373737717337317737537373773777773777753777777777777737331311113133133313111131353353137777343400000000000113113111312111717357713171313133131717531177777777777375377773771771717171713707531753573735371777373777173777773777777777713173133313113013313131113377377177701353700000000003113713121313131317371371311317173171317131377777737357377735371771373737371771333533723171735373777577777777773777777777777733133113111113101313131757173173343410111313410000041371353135313537375335131731713117135377177777377757377577173773777773535333171713531117373537173537373777737171737777777777313313113131111111311173337357131353131301111343035363131317133113317137133313113313313531631177377753777773313717353121013131717171312113331313312113777753737777777573777777771331333111000101111130311771733110111111110311317525753173113153035337713535317317315313171533157773773735375353717353113313131331310110110131311313101313773573737773771773777771133131311111131331131371373713131313013111311313737371173713131317137713131315317313531373513353577757771337317313133313121111313110110131111111111313033173753773777773577377733133133331331331331011171717311111111303111131353537737113312171313713713135333713713171173711313737331371731313313111111113030101210111110010101011111110313371353737753077777313113131333133131131313373775313011031113013131317777713371713131131311353733171371313107171131131135777137113111101011011011111311113100011110101000010111121131377777377307377131311331013113133713131117131111313503113317035303177353131713171131731311171137131353131213171153131137313313010101001011010101110101111000111010101010101101111317377357757077111131101013313713331133110171031131352115213131313131317131353031311353373371137171313131713133131131331310113111131130121111110313101211310011010101010101100011337177737737173131111101011173735333533331313501013111631131735353173533533313135313135317137313313171713111111111111101011010121012111110101011011131101011001101103710112110101117373773777653113101103137173133533353133131313171313113073130331213353135353131303531733711535353131311313131313170101101111113111101010101101101010311010110110351310153501011237175377771377111130111313313353335373311013113101213713103131131317335131352133533171711733313313131311111111211331130110101010110110101000101101101013030010131031131313531011137337135370527131111333331353335333171313177307335112153171725353711131713313513530337331717317171131313113311017521012110101110010101001101000101111211111101013170170103031210135337377737147131331311133317335373731113111711533113313331131310317131311713313171537171371713131311331311011313113111011101011110101100100110101011131301317010113131311111113331713317777323131131003131331333131337307131130310311213533173131131317173171253133353137131313131131110101353531010101110101101010100111010010101112101101313131310101010312111113351731777507111110313133133113373111711103131135371713413107112111313131311353571373537131311103101013531131211110101010110101010110001011010110111101310101130113111311113010311331733537707331111310113113313171131173171533131313133173133713121713535312133171173533531313111111031121111301011101101010101110111010011010131031310111110112101010121013110311331737737707713111113313013013131103113131013131313111353171353171353131113517137317173173773301013113130311111010101301030112110101011010110103101010101010111101211111312111031173131717127731303311210101313173171311131701616017337335331331313317130353373531733317717311113113011131030301010110131111011010111300101011311131110100110100101101010113101133317173777077775775311111130117113170706070700005200101731731535351731171353173171757733717310313011011011111311110111101031013110101300001011010121010110010110110101100101311111313353177577737737713131111371311777777777716705347253531731313313731135353171373317753311351011101011101010010110101311013101011011101011013131110100010100110101001110100230011311377137037777777777777377770707725777777610634305277353535353731737137137137177731310131331310111010111111310113111011101131011700101101010110110101001010010101000011031371011373131717777077737575775777777777773677761071777520735373713171773535353717313713131013011111011001010101101031101011010110101073113110111011010010100101010113010311301107333013313773770777747773773437577725777777777707767036571737753735371353137353731713731101311303013775311011101111101111011010111111710100010101101111010101001011011131121100331311011311171771777375777777537777776776776777707716537371713717135377377171713533111331113011111313377751001101011100101011010101013311111010101101010011001010101010121101100110101011033735377777777777577777777777777777777070773535373773737735317177373733113131101711300101101113733100101101110101001010111011010101010110101011001110311010111101100110012110103117377527777377777357776776777777777770525313371717353713171737335371713311133133110111110131310357710010101010101100110101701110101101001010101110001101010010100111011111010010335317777574777777775377771725707777772531715373737373717377535771737351311111011310100111010310313371011010100100110010103101010100100101010101011131111011010111211001011311111131237777375777757777777704725707436531713737177173753535377637371713331313111101111101301111131011133010101100100110110111010101101110101111101013013011011010011011111011101313011753777737777777771725073520717753431353537317351373777071757373311111111301110101110110310113101013110100110110011011031001010100110110301111301101101101011001010101101110101071371777777777771704720742577634367125313531717377575707737375311131313131101011101011011013010111010111011011011301101101101010010111011110310110110110110101131310100101011113117177717577753577073512753471777707531753773717737737735357777731113113133101010101011011011110011010101001010101110101100010101010101010110111010110011010101113130110101101013031777773437777770742616343061617707672717177777777777767377371713113111113110101101001011101111011010131011010101010101110110111010111010110101010111011011010111110103101101211771777777577777712755257777777770735357677777777777771735735737313111012111010101101111100110101001010111001011101101010010010101111010110110101010011011001031011010100112111177377777777777757616327777777777777567773577777777777777537773535313100111101101100110010111010111100111010111100110010110101010110101111011011103111101010371713101113111011107313537771717577775257507777777777737377777377777777777773777377331310113121130100110011010001010010110101011010111011010110010111010101013013121101610101217130110101010101103131717771777777171727777727777777777477777777777777777777771735375331010101121110110111010111010111010101010101010001010100101010011101101011011101311371311525110110101013101111310317775257377777507776577777777777777777777777777777777737737137131310171110010011011110101010001010101110101011301010110101011101101011011101131311111703130310110101010110101031753777775777777727353777777777773777777777777777777777353753713571013121011101101101010101001110110110001011110111010000101110110110101010313010112121353411011011011111211113153775375377535776574347777777777757777777777777777777773713331313353535131000110101313110101100010101011101100110101003110110110110110101111011352111531113701101101001011130113317775777777777353774377777777777737737377777777777777757717131777317331031110101101101110101111010111010101110113111577777370110110101100101013131613536111305301011101011010317017737777777774347034167361757772757777777777777777777737313133111371531113111101110110110101011310101011101010301077377377710110110101110113111531353113635130171010173101131713777577777777774373436756572773757737777777777777777773737131011311713101035010101011011013107101011101100101311117737775773130001011101013101213317134311113717217073110113131317777717777777034141617373777677737777777777777777777777777131310303103131131773730101011101313111010110110101010137737727170131101000101101311311037135031701315313152111013112757777775777773436216167567535777777777777777777777777717373531311153110110737777537131031311777713110110110111110737521717310101371310101110311017101131431315311713313011013113737777777777741615250716352773777777777777777777777777777313130107301031013513353173511111035331717017010101001011713537371011135377510101011101713110353171301301110111011101357775777777777216102527777777777777777777777777777777773735773513111111101101315335317301035130101311311110101117727773777710112112537371301010330110317131135311113071121013137775777777777775250753477777777777777777777777777777777775733133717730101121101031535121331134111301711212511121713513773531312113111305377771735110101213170101303011121171101013777735777777702527673477777777777777777377777777777777737717113317531121101311131121711521131215131251113031112513411777701111010311310135371121031117152131310111011103171331357735777777777753473743777773777737777777777777777777777371737353533101110101012107111031110111133111312111103013103121331310101011010533531121113101213111110110101101353131111377777773535777673757777777777777777777777777777777777777773131313305311011101311311213101211031251031011101351710101111010011011101311351317111301531113012111011010101311301257777775777773773747763477777777777777377777777777777777737777131315301011301311131211101311131111131011101370130351310101111071103110130310313161713121013110101011010131301111377777777577777757737573777737777777377777777777777777777177353101311313010110121051303101121012130111010777173111210731101011031101130111310113131211113101112101011031101121071777777777717577763572757777777737777777737777777777777777777777131317101111031111315310101111111011011377353117121177101100101170101111030131211111121301101011117017521113113137777777777777737577257277777777777777777777777777777777773773731121735310101013030130531130301211301777717171303110310110111131371100101111101113030110110301010731713112111735777777777777777572775357777377377777737377377777777777777737753531171717010111011110113130111311101137777131171110357713010101011130111101010111011110113011111310173717110131737777777777777777257276353777777737737777777777777777377377177373713537313510011010131010131010301101777371731121110373053510111010113121101110101010110111012101311173137313031777777777777757775355717777777377777777737777777777777777773777713137717131311011011003111011311110177735331071152117771313210101011010110101010101010310101011101437113717353137777777777777777276373777377377737377737777377777377777777735777313171312535301101101111301301101037771731153121211735311435112111301013131101101011111011131121313310301371311777777777777777775717777777777737777377777777777777737373737737777130317113031710110110101101100101771731521311111317731213112112101111101030110111010101010101105015315301377137777777777777777773777777777737737377377773777777777777777777337777531313111131312110010101101110117771731131303110173111010717117112101101111030103110111011101131211313171313777777777777777777777777777737773777377773777377373777373737371777773131350307105351011101101101010773121121010110017211011313130311251310101001111312113013101301011121371313777777777777777777777777777777777373735737777377777777377777777737777777112131113130107110110110101137112110111011013771101014352535211130713111131271011101110110121130113137357777777777737777777777777777773737771737737777717373777717373737717777773113573773531310351011011101713111011001101073570131313113131213113152121051111101111010111110135711153777777777777777737777777777777777737373437737737777777377637773737377777777313173573535310311211010173010111011100111773171035253143151707352111113121031101211130101735737373377777777773777777777777777777777737717353577777777735737737737377737177777311177777317353535311121110111010011001131077735303513101313131311113030101113103135121413131733757357777777777777737777777777777777773573737377777777777777777771737373773177777173733531735371307030111031001011101110503171521711213531703703130311111313105314103531316113715331737777777737777777777777777777777773772737370777777777717777733717377777177777311773771531735317110101101101010103013113773111211713121311110110121210101121131713535317313331737777737737777377777377377777777777770753573534357777377771717752737377777777777731531731735735317312101101101031111013410717031701107111303110111111311121125371773535371711777777777777735377773777777777777777777377373727373734377577777771737377777777777777773173531737173535351330100111103013101311211101130313030110110103010101113537137177377171377777773777377777777777777777777777777777707773534365737716375357163717377777777777777777313771737753535373513171010101110131071112113011101111011010111113103071717753717717335377777777777737373777777773777777777777773707167335327777714177371727377777777777777777777711335353737137153717177711110311011130113011303101011073711012103113131313353773771737777377777377777773777737777777777773777773737376335353517730115073537377777777777777777777731537353537537371737137370710131030130113101101101033717735317177571615353353573777173777737377737377777377777737777777777737773435317237277735341617317377777777777777777777777773535373537177171717537731313017113513050310110117575773535353713731331357373371317777777777777777737777777737777773777777777773363735353773777535371637777777777777777777777777713137717177713735373573534307121703035371031037773737173735373777171171331317527777773777773737737777777377777777777777377777777170736357353032525637377777777777777777777777777777513737737771773533573531717171753537173537537173537753577717137173131171637177737777373777777777773777777777777777377777377777372537236353533531377777777777777777777777777777737353537531771737537773571777731373537173537537153717373335377173537170675242477773777777377377377777777377377777777777377777773712717737252163777777777777777777777777777777777577737737773173513717353777371435753717173713173735375357533133317373001024107343777373777777777737773777777777377777377777777777371210101217377777777777777777777777777777777773677753537317131371735371777713773335373571717717171737733113100137100000100074347735777377377377773777777377777777777777773777777773737377777777777777777777777777777777777773471757373717707175371735373711757357537173737713737335353531216174213000000000160137737177377777377777777377777777377777777777777777777777737777777777777777777777777777777775773472777573717707025371735353733717337173537531717175737373171706353471000042107162473637376373777373737377773777777737777377777737773777777077777777777777777777777777777777737753577777777770735317171737371753735717353713773737333531370070714253600000010616150377177177377377777777737377377777773777737737777777777307777777777777777777777777777777777777767177777777775040603121317177377173311317777131311010343107347435341041061061777276536363717737173737371677377737777777777777777737773777017377777777777777377777777777777777777167777777777727371707576713177377311060131313371763434340347737767761207161007077573713173771776375675271735377777377777377377737773777707677737777777777777777777777777777777777177777777777525677020753673135311677166072147777140774340377677777741676167077773767776172723377373737377377777777737777777737573777370761737777777777777777777777777777777777777777777777777773577527777172531770167107757375676372537734777777777275347712777677777037017757137373735235237377537773777372777353537777173577737773777737777777777777777377377777777777777771776172577777777607077070777677777314775610477777777720536710657777777770503303323743707073773577733637777377773436777670007677377777777777777777777777777777177777777737777777774176142770776777307077070773776777430637270777777777512416370376775777727765301703353737371212537771703774371773535213170001077377737777777777777737777777777777777777577777777736012147777753574007052525777717763410505003437707176012140505717727035001000600343303030035353637163775377763477637767007000375273773773777377377777737377777777777777777777777610400030707276301000000072504761700020000077410776701600210063600534720000201006304343037020071707707127525353703170716100007737777777777777777777777777777777777777777777777101073001675250534060030104352430170507016125703676010000050002714177043401401400751437070500143163740707703727343767070700001437735373777777777777377377377171777777777777777777777777705207772521014060707617767070305204036571717771610012415636707371423000210727052572002007707307007707163701010070760002053677777737773737777777717777777077777777777777777777777775307077560210110717617167761615314172776707761670717271610707671507014252572572570500740700434300707161677677770107001671737373773777773773771677777717171771777777757775357777777525252105060601671616170105204216357071770101034725777777771060701610777777777252070307077700071616177777777770707707373777777777777777777373777777777777177777777777777070777777777770707171777777777777773573577777777777777773577777777777717770777777777775257770434000000000000000000000105000000000000E1AD05FE")); - strs.Add(func1(4), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF00000000000000777777777777775773775737773773777777577777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777173434716174361735707353436571717377235700007777777737777737777737653777757377177737537537777777777777777777777777777777777777777777747657252103060206042434777777777777777777777777735777375374361705253432163617075727777777737777777737777777777777757775777773573777777777777777777777777777777777777777772524141210000040604004000000000004061677777777777777177763534736175370773527577757777737577777777773777773757717717717717373737771777777777777777777777777777777777777777777127052430200400604200000000000000000000000000077777777777771776773717237077052707271735735677377737357775773577737777777777777757753777777777777777777777777777777777777775251076502410040600600000000000000000000000000000000000007777777777171756757577307371717076734737177777777777773577777777377777777777777777777777777777777777777777777777777777777676107412042000000000004000000000000000000000000000000000077777777773773637075352525617357737576177357777357777737577777775371735737777777777777777777777777777777777777561600000016700604004004004000000000000000000000000000000000000000000777777777177777377677773765725772737777777777737777777357357377777777777777777777777777777777777777777776536177777777650060000000000000404000000000000000000000000000000000000000077777777757377671717075377777577573777377777777777777777777777777777777777777777777777777777777777777172577777777717777040040000200000202004004000000000000000000000000000000000000777777375775777777727171777373577777777777777777777777777777777777777777777777777777777777777777567537775767775600247142006040404040404000000000000000000000000000000000000000000077777777737370707567677774772777777777777777777777777777777777777777777777777777777777777757572536577727757700000164250400000000000000000000000000000000000000000000000000000000007777373775673773717353773577777777777777777777777777777777777777777777777777777777777756376357616767577777700000025020000000000000000000000000000000000000000000000000000000000007777777777174347777775352717777777777777777777777777777777777777777777777777777777777374357635737576167061652007560400000000000000000004020000000000000000000000000000000000000000777757377737716177767757777777777777777777777777777777777777777777777777777777777765374357434777077752161257003434246040000400400000000404004000400000000000000000000000000000000477377347563777071737377777777777777777777777777777777777777777777777777777777775161434243652527777756140007403400004204000000000000000000200200024040000000000000000000000000000377757737356177777756777777777777777777777777777777777777777777777777777777761636342707165256775777777777777000000000425200000040000000040040400402004000000000000000000000000000077373525617271617735377777777777777777777777777777777777777777777777777771775414340564167014707777777343576100000000004752440004000400000000000004204240000000000000000000000000077567773615777725777777777777777777777777777777777777777777777777777777770736340703167047025200777757202172507060000000652060004000400404004004000000040004000000000000000000000077352353634371737177777777777777777777777777777777777777777777777777777670504250746014304004043434275710050725100000000047004000000000000000000404000200000000000000000000000000077775743537477476777777777777777777777777777777777777777777777777777071072435274212420424200240041427060030052473400000000420000000000000000000000404040000400000000000000000000077172353653717353777777777777777777777777777777777777777777777777177477043425010410400004040043607404140061253043612000000040640000000000000000000000040400240400000000000000000176775253777777777777777777777777777777777777777777777777777777776537043471724202420424003043405607024240040243043416100000000060000000000000000000000000240000000000000000000000735077253434353577777777777777777777777777777777777777777777777773467743424014040040000604306521604000000000000100216034000000042500000000000000000000040004000000000000000000000527014343537072777777777777777777777777777777777777777777777770743535360500606034034070434702040000000040040042410501434020000000656504000004000000000004020400000000000000000003714363527707357777777777777777777777777777777777777777777777775347765160610014024072452400504042000400000000000200203030506000000000616160000000000000000400000000000000000000001634107107717777777777377737777777777777777777777777777777577767347724100424204070452521602002004000000000000040004000030314700000000042470040000000000000604000000000000000000061527077316703777777777777777777777777777777777777777777773752577716524612500563472524040040404000000000000000004000404004212520000000000047002400000000000421400004000000000000172016125613757777777777777777777777777777777777777777777765677741607521040256056152434306120102040000000000000000000000000040357340000000000650040000000000060000000000000000000705253573757277777777777777777777777777777777777777777775371777760524747025617256250004404464040000000000000000000000000000000000716707000000065242040000004074000040000000000000725363757257777777777777777777777777777777777777777777765671671702503244707657050656125212120350000000000000000000000000000000000001616520001060546006000002070400000000000000070707577277777777777777777777777777777777777777777777777371677564652645217771616070216525674774301000000000000000000000000000000000700712107700112034610000040470000000000000000170707257753777777777777777777777777777777777777777777776565352535214120747774343417470753537531000010000000000000000000000000000000070041650030677400046000253640000000000000007070737773777777777777777777777777777777777777777777777717374240607420547356534343743773676573000000000100000000000000000000000000000057252121013577777000040643740000000000000007071757777777777777777777777777777777777777777777777777656534343416520347736747343743571777741010000000001000000000000000000000000000217010000203177777742041677740000000000000725242737537777777777777777777777777777777777777777777753737470042430476770571734775376777177300000100000000000000000000000000000000034161001210102777777750000567704000000000003525375776777777777777777777777777777777777777777777777765743004341043177177365777167571677770000000010010000100100000000000000000000003002100010617777777600600000425600000000056102527377177777777777777777777777777777777777777777775363742524242147576525365777772773576710100100000001000000010000000000000000000000100210211037777777007000000000424000001200614357176177777777777777777777777777777777777777777775752542505252167537565372573577577357300000000000000000000000000000000000000000000010010201077777770077000000000000000025300020216177777777777777777777777777777777777777777777727772142525042536743534757777772777774100000001000001010000000100000000000000000000001210121777777700000000000700000000704034175777737777777777777777777777773777777777777777777577054252420356771776777273477777477710010010000000000001000000001000000000000000000000012107777777400000000000000000434303403434341577777777777777777777777777753777777777777777077025241504252563575257577775777177300000000000010000000010000000001000000000000000000001217777770000000000000000000000701612537363777777737773777777777777777777777777777777777167061626143473576377727573777777747100000010010000000000000000000000100000000000000000000357777770000000000000000000000761612535777777777777777777377777777777777777777777777776714161416007076175673572747377777730001000000000000100000000100001000001010000000000000000277777000000000000000000000000170777763777737357353757357777777777777777777777777777753422507241707716437757757775757777500000100000000000010000000000000000000001012400000000000021776000000000000000000000006707343575777777777777377777777777777777777777777777777767450615242506717653672771777377737010000000000010000000100000000000001000000001000000000000404070000000024000004000000016107777377357777777777777777777777777777777777777777777173070625042516705657757767167575770000000100010000000000000000000000000010000001010000000000000040100000176000377000770352525347777777777777777777777777777777777777777777777777656071425252435635270777777772777710010000000000000100000000011000000000000100000000000000000040252400007610004740007077602537737777777777777777777777777777777777777777307757775307406160043463527577757753577707000000000000000000000000000010000000000000010000001000000000025240000007000037000007761757777757777777777777777777777777777777777777774716773776502534165241756752707677767757770000000000000010000000000000010000000000000000010001001200061420000000000000000000003161207052777777777777777777777777777777777777377717617747777702436125260743657753777777257730102100001000000000000000000000000000000000000000001001000061400000000000000002506061657127052777777777777777777777777777777777775770777065707776561405601416165252765777577777100010000000000000000000000000000000000000000000010000102567060000000001773774352100001206107357777777777777777777777777777777177777073701752756177347360560605257653563477777070000100000000000000000000000001100000000000000001001010216100000000000606043437777777777535771677777777777777777777777777777777777775777720253617056704076161425241652577736577710100010000000000100000000000000000000000000000000000001636160000000000000000000424343437763071777777777777777777777777777177777777721747570257077717725036163425243652525777777700010001001000100000000000000000000000000000000000000101404000000000000000000000000000001757277777777577577577777777777777777735773577737051207430653524507041425241616525074743101000000000000000000000000000000000000000000000000010202020600000000000000000000000007477375777777773773737377777777777777775773576777752025070161347770240724340160652567371773300101001000000000000000000000000000000000000000010001040040000700000000000000000000077767777777577777777777377777777777737777777717161743507076146161657070524176050065256563673730000000010000100000000000000000000000000000000001002040075017700003740000020000077772507777773777773573757777777777735777737777007007342100170352573657070524016070024343571733733210100001000000000000000000000000000000000000001000077760077200007600000750000743756173777777773777357373777777735777777765307701635250610616070052725242525607043410706074773773610010000000000000000000000000000000000000100000777777700774000177000017600077774216775777777777737735357777777773777707534160060070521061001725250577752520140707060407434373333321000001001000000000000000000000000000000010137777770007700006770000777005777425621777773737777717373737777777743777777034177171030060125614165252552752576034043470702434277773732301000000000001000000000000000000000000000377777770017200017700003770027777001567377775773537351717537777777705053770436143434070104030612101612416070757434343434707056173773737321210000000000000000000000000000000101007777777430000000035700007761657777023057737736153434370703777777753027777072534341603436737410707061613611616252524340610707256173773737361000100100000000000000000001000000000177777777000000000000000075425367700456375773717273537073171777777361417777050616030141410041271527170040065255352534161460525024377377373337312000000000100000000000000010000103777776740000000002020340702576770612734736157777577577174341777770521257772171616577273430034020142534352101207614216167376167534217337377737631210001000000000000000000000100377777777700000000000140000252753470434717717235377363777373771777770525277576507177775001412535160342100052405205214704175070177777777773337333733733000001000000010010000100007777777576700720000002102141652752430525637777777535757375775277770702525777773777717120302050767050104777253721610610212527416777777773777737773772733312100100010000001000003777777777770057400000056000200256341402527535377353773735777377774030050177677177777772514101200103777777775705050161241470412707777573777373773337337373733250010000010000010177777777767700272000000374000175770002016752777557671775777375775377470276717177777773712037400142057740217737727060041020003040775773777357373377737737372373333431010001010037777777765776105750000007770006027740012452777353353771737177777377737775357777777777657571763002100212710612410535161061434343000737777577777777337333737377373733332303003037777777777777576002700000007740305057730003052557677771777477717377775777777777777777757373070104104000417651251243420107072534000437775737717377377737773737333373736373373377777777775777727770371000000777000026777400006357353777176717353775777777537777771737777377740170000630000377025724103416000057052573775737777777535733773337373776373733337377777777777777477577000000000003770002517772000534727771777717777777777773777777777775717777571270030010750304161407100617070012006100777737753535737773777377737373337333773737777777777777777777777000000000000300142437740002437577177777717357353717777777777777777777773751734000007614300037707010074010401000703717773777737435353717373737377337733777777777777777777777767765200000000300030303474340107437777777777775735777777777717777777777753567721737000000037430070707352037421000125075761777177717737271737373737337731437777577777777777777777757700000000000000404043076120001747777777777777777777777777777777777777777730507430001000753401000006004143100340003773777537712771717535277373717531343777777777777777777777777774100000000100003034307410002567377777777777777777777777777777777777777771752013410025037700000100104002016070000001771737753757172713617116352733077317777777777777777577774777772016000006000007000743600012074777777777777777777777777777777777777771612052412410735700772000000030100010170100070775717371736173753737353711653107057777777777777777775777777750275000016000007000347000074377777777777777777777777777777777777375377775210241277727777050000000000000000700000375363743563537152317071253731357317377777777777777777777777777061760000770000770024370000035677777777777777777777777777777777177777771421434120500143417007006005000000001600017527357377353716375613535352534331707777777777777737777777777776174300007700034740535770003473777777777777777777777777777777777773534163503430752142100025001010206000000000003073717717535341735133573617353531743177777577777776577777775777700374000077700077702476710043657777777777777777777777777777777777577672507701617742104371020060000100100000000000707352712737371736532535343172521343777777777777777777777777777740770000777000777012577600143777777777777777777777777777777771737761743700161614100630407050107050610020102500017716353753525361713533533172531717117777377777777777577777777774300000000700007770607775004256777777777777777777777777777737777770017171700000030601750300216100210061412517211473471735377173534352570347153170707677775767777777777777777657730000000000000017270537760021617777777777777777777777777777777771710024361614000001700250757576014070121612745763771372573433053713753177132352171311774377777577777777777577777430000000000000005027060000525677777377777777777777777777775771671600015300031200000010003002016030052410417320177774173437577070712352117153070352707777777177777577777777777777420000000000000205007030000435777777777777777777777777777737777161001020502404116100700700351701403001243524177777537073713137171751357216357171351377777757767577775277777777770105000000000000125614000161637377777777777777777777777775777712716000012100300600610601617206060340704100617777777253535256517343136131735121214325777357677776776777757757757616720000000500002070200000027477777777777777777777777777377717050705000400100101010071610404101100120120701777773771617037313725307717251123717335167777777775737771777737677777007700000027000014070000025017777777777777777777777777777737773010300001242520002000000030300607740165100777777777771617147707135301717367510714325377777737737757777677777777777475600000077000030770000024247777777777777777777777777757777340200030301010143414003416500010161034020773777777777771707331352717375215313671635101777717577777775777577577777703677000001770000047740000107377777777777777777777777777737534100100000020030201021343212177060002503177775777777535770731475251617031736161101016367777777657777277777777771777077340000077700000375200016074777777777777777777777777777777730000010001010001021000153534317173412147717777777777737771073031631617070517036373614177777777774775761777776775770054300000377600007777000250077777777777777777777777777775735701000001000001001003012153535637173577357777373777377777777071611613435272035014010337777717717777777777734777777770200000000777001007770001607077777777777777777777777777377773000100000010000000100017013531353572717737177775777771777717161631611201017037737775777777677777777537775773577777061000000000000020077700007007777777777777777777777777775773500000010010000010010001213343175727353773577757777377177777776173052163577777777777777777775347753777657777777776776100000000001070000024000700777777777777777777777777777773777000100000000010010001001715317031717757177173737375777777777712141253577373775737777277777777737675777776375777717716000000010020000030521430601477777777777777777777777777775373100000000010000000000121303535371713737177357575773735777777752173773777777737777775777777777577777577177776717777616000000200001210002402417423777777777777777777777777753777700000000100000000010000116152135073752577356737373775737777777777353777357377777573777777777776357276377777777777777017000010000024000052503402547777777777777777777777777777770100100100000000010001010311313437305317125373567175733477777777777771717735777777757777777777357777775777707757677706774000670001434005200342704377777577777777777777777777771734000000000000100000000035230533111735737737173537737577777777777777777737777777777777777777757707757777657777737577707770001775020777205274305216777737735377777777777777735777130000000000100000010000111531417251235017153537525737137777777777777777717777777777717777777777777771617777777577777052770027767403775600774704257577777777777777777777777773777000100001000000000000103030121301375137352370713737537577777777777777777777777777777777777777765727777777775367777770775216177703477761657770705237737777777777777777777777775301000010000000000000000013517171717013615357173757717343777777777777777777777777777777777773777537577777771777777777616563407777442577524377707027777771777777777777777777717373500000000000000100001001312303112317351361307153313717177777777777777777777777777777777777757777777777775777777717777012142147772106776106776524147777777777777777777777777774352101200000000000000000000111116116112351353533747717335377777777777777777777757777777717777777777777757777767777777756042142052142507706107770707071777777777777777777777777317016161100100000000000000016125213513515361353453313635707777777777777777777777777777777777777777777777777777777577777734304343252052052050617070607777777777777777777777777101521613016134301000000000001713531701212121116171335757171357777777777777777777777777777177777773577777777777775777777777400434344047025205261602434167777717637717777777777777702503507107010521210300000035371161735753534312134530317353777777777777777777777777777777675777777777777777777777777777770703434034307504361420410706177777777577771637777777777753503016107030505250103000071673535331361735717133517107103777777777777777777777777777777373757777777777777777777777777770600616034202704161430612506717677773777777577777777777777775210703503031216101717171163525677171723527507343712577777777777777777777777777773577777777757777777777777777777777401771616005614306025070416017777777777777777777777777777777777771410307041610777777777717171103525357353735371717777777777777777777737777753777757777777777777774777777777777776167760414777070615706003601677777777777777377777717777777777777777774101301777777777777777777771717015253437161777777777777777777775777777777577375773773777777777777777774777702570772430776061427741605261777735371777757777777777777777777777777777761777777777777777777777777777771717107127777777777777777771777777777777377737777777777777777777777777777742400412477775243477341615067777777537173777777777777777777777777777777777777777777777777777777777777777777717577777777777777777777717577777735677777577777777777777777777777777053761610077705243777600260135377703677777737777777777777777777777777777777777777777777777777777777777777777777753757777777777777777773777777773537777752577777777777777777777740276160607770425257740165016777577753177777577777777777777777777777777777777777777777777777777777777777777777777777777777777777777676777777777777757772777777777777777777777777705070501607721605277342032407703777777377773537777777777777777777777777777777777777777777777777777777777777777777777777777777777753535677277775773771753617777777777777777777777200020601400401240160104052777757777771437777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777773535757377777777075777777777777777777777774343430703430705216070612410777777777773777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777377777777707377777777777777777777777700040040240060420400000007067777000000000000000000000105000000000000D6AD05FE")); - strs.Add(func1(5), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF00000000000000777777740043734074373737370737777043707777777777777743777777777000534040673577777500740000400050040042500000777770004217073737373773777730040407073377307373725000043374053000003737373777377604074377777347737377047637777777777777547777777777400750250573177777505350700050000000040004000577770404033773737373773370400040407071214377373736100372000073777777777777377704404427437307377777734341777757777757477077577777771040075000777577777040614340000000040000000003777700007773737737737377040040000007061637373773536173040004003737737373737520404040453774777737373777777767777777777705777777777770004770477737777770051004100000000000000000047777700737373773773737200004004040407173737377373737340004000777777777777736440406404247073737777777737777577777777745761777777777750017770777537777750065000000014000000001040005777733737373773373771604004004000063773773737373730000004040737373737737700406040604007777773737737777777757777777770742777757757777777757777577777601734000000213000000040004167777763737373773773021400004004005373737373737373400404000007777777773753652444040404737373777777777767567777777753475757777377774077777077713777771561410504351750000000000000017771000437373772007003040000400737373737373377240040000040473737373776345340042440573777777377377777577777777777767527077357777717737775775777777770140040037077100000000000040477770703373772253733704304000071637737373737603104000404000777777773617370744044043777373777777777777775777777777577757477737777717777777737177777740000005753176001000000000000077710007373351273773334304037361603737773773506000400000407373373653773773734040772365777373777777777777777757777756770577577777705776177777577777005000127357710040000000000400077705011340361433071214015730001061733770003717000040000377777765343763770704077344032737777777777777777777777777775752777377771377704777737777773001057517375000000000000000007777001340004373737370033723710360273773173733733434004037373640436777377070773734537477777777777777777777777765777525257777777175754007775717777740070030777700000000000000050477775377310000073773207373376004005336036007256352000033507765060470737737707377772407073777777777777777777775775767775417577777737600017737117777101400573777000000005000000000007734170771371052371337373337010033404017373337253434372040430440475617707777737352507775277777777777777757777775775637777777777771404077777357777003537157700000000000000004340007734351005021050077373777373773700004007177373003737370060440440427603737373777777773465657777777777777777777777565547777777757770000077717777775007167375000000000000000000100577515335701507130036373333373340040400436334307773735300440040060471777777777377373746175767777777777777777777777716377357774277040417773777777710731717700000000000500000040000750072571173053711001067777324000000400435430773373723440444044040463737377377377743475677777777777777777777775375657757777714074000617753537777715731775000000000000000000140006734150163413041405031100337004040400400423077377737373040040044041777777377777737443475657757777777775777777567477777777777737434005747777777777777777701000000000000000000000017737350141741030017521110100000000400400437337373737374044444040773737377737377761674367767777777777777775656757777777777777400405521077371777777777771000000000500400000041043775775214170171413710052177111040400440053737737373737340040004376377777737777752574577575757777777777777777771777777777777753540436040777577777777777100502500000000000000104167527101507006121477105010713040000040007377373737373716444074407354241737737372777772567767777777777775777757565775777777777770714054050777357177777777010050050000001000004707573517040350514140717010711771310040040737337373737376300004016777365347737777573737777565777777777777777777767777777777777777777707016177377373535777770500160004014040000015707777071357300717152503537700103610000337024253737373014074407737374074327771636777777777777777777777777775777577777777777777775353757757657777753777777710143505000000000000420077505357314141361050341510153533000707700500273737043233016773777734004776167717777777777777777777777777777577757777777777777777777777735704777735777777052050000056100000000504573417215614170516135170077352700373373042125377352373577737773737737773534407777777777777777777777777777777777757777777777777777717777407707777737777701050000400014000000050030753751701016153050434037135310137377352104037304250732373777777737737772404406572777777777777777777777775777777777777577777777777777777045177777537777701000500050400073040070577053653507317053171714177534316373373734317304000303737773773737773772444061652775777777777777777777777777777777777777677777777777777775067577377777771070050014000077141017500773141250714705257371304712411017377733637724000404343717777777777377040407440657777777777777777777777777777757777777775777777777771777770572777777777771052500400007104040470077714105073531505346525035353104313523773370004040000340273733737377174042443470747777777777777777777777777777777757777777777777777777777770571771777777770014300007314000010140534107014143560734110505107173117703161137004000004040301777777777776377440641474377777777777777777777777777777777777775707777777777777777777765777777777710014005054000000404007717053430501141416350167125776143535377100000404000040773737737371616525341464077777777777777777777777777777777777777776577773777777777777704077735777777771401420000000000000771752140410716100715371711507010000705734340040000400033377777777563773736442537777777777777777777777777777777777775757717477777577777777777507105777777777700040500004004005271456105313410415351040507170100571050143410024000400017377737371736173777753544777577777777777777777777777777777577677657743477773777777777777057604353553777040170500000000005473116535441710430701313507173100071016110037100400403736337777760416773737763777777257777777777777777777777777777775777756543577777777777777777075070402741470004070400007504071457717731061770415061701161775014014017340336030000370034271730406635377761777377347777777777777777777777777777777777757777756777777777777777777743040057121741405000005500007700370571414141051734140534135301731421410037713005377003001760440440576527377777777777777777777777777777777777777777757777561635777775777777777704354100177717353400050520070577144007061735305301531073417770141040143000000347733330040020406044042437757777777777777777777777777777777777777777777777777775777777737777777777507377770377757771004377750525305335711507535377042561717101710350140053053100003777610040340444004040407377777777777777777777777777777777777777775777777575775657777777777777771777777777577737774005770061775254177721703405171010141712500404250143750414000100037361353044044424404777737777777777757777777777777777777777777777777777777777377777777777777777757171737353577700376107577771034351570514176053416077141301001104141000001004000737373204004400440563777773777777777777777777777777777777777777777777775657757777777177777777740257777577677377357414773777777514043052412511241710535035101070004100711250031003737204044420444243777377777777777777777777777777777777777777777777757777767757777777577777777055614016141014014707617571777777717107113414341530417101430417171300001071351410173714000400472405773767777777777777777777777777777777777777777777777777757577777777773577777770061616140164400071417773531743777777577414341041410716101410000471711400050031007373210400444041773743527377777777777777777777777777777777777777777777777777747577777777777777147141450706100165065675353435357077777701617134301570510700005710040043115004140002405200072407773774256577777777777777777777577777777777777777777777777577775777677777777777770434343070414147707173537753777717177777775353410467313050100053050010000401000015013303504041773777375616177777777777777777777777777777777777777777777777775777757777777777777750541404050404165047171653717777777753537777771711107507170521414070140100007100030077372007773777377737777774257777777777777777775737777777777777777777777777757757777777777777070043434252177165377531353717777777777571777777777173516530570101050101710417104103307353073777377737777776174767777777777577775777577777777777777777777777777777775753771771777057041405057416717171775353357777777777777174765777170253501071404340561013710000073733200777377737777372416477777777777773771777777777777777777777777777777777757777777775067774707143077257771777077137714777777777777777735173477535140407400101000104050000005343250177377737777377454657575777777777577773777177577777777777777777777777777775777475707575735707354145735371717357717371777777771734777777753507777311403140540505010000010002143027377737773777773652477676577777737777575777777777577777777777777777777777777577725707725675747777377775377717353715377737775775735775777777717174001571003100005610007710402007737737773777356165257747577777777757357773535777777777777777777777777777777777757577757575377571311177777761757357731177577173777771777777777777717161035040530001710510000053733737773777376737777756777777777757777777357777777177777777777777777777777777777777777777737753361037717171177335371107777737775357777777173777777717537571001041140040004000377373773777377717773777775777777777777577375371777777777773777777777777777777777777777777775771375113117717177175735737717777577777717777777571756571607573431405040000110000172137373777377436727777777777777777777737357775357357771777757777777777777777777777777777573737771133513137777177375734117371737717371717777777777717505170541401210171043500036373637377377700453577777777777777777777757777334357777777571771777757377775377777577377777357535177152103577777717537537701777571775777735777777777707352052070535050404173037100003737377430464367737777777777777777775737715153717717773777777777775777777577377777573571713117310311313735371773753771177777377537353077777777777775757715000143100130103724000073737700440404407777777777777777777737717734357777753571771753535371717777777537753777370171301711311017771717171717537357177537757775352577777771776717771571077300510733100700303720464040604745777777777777777777757771735353573753171773777735377777537177753751775373015311210313117777377777713517777177537371735352567777777717750773700571412513772300007340040404404524277777777777777777775377573537777357375357177771717535773757777353777531117131731533010717775717117752713777777757577137153177077777777104144353000751273373533700000040640460475777777777777777777777537357717535771521737573535353773775353577771753371713073503151137771731753771371477735375373717712714717577577777310000411410303737373360000004404140474377777777777777777777177757717537773173171717171716171757731073775377357130371753710370177775777375377173175777371757713717717052537177777771110061041737373360404000040466340477767777777777777777777717777737153577177175777713531071717771171775317357171171717711310777737175375317171371757573717717537777050547535777777710171103737375300004000140475253777577777777777777777771777753537777357717735371713171173753537771335757317173303711310117777777377175737177777737757770531773777770107677777525752570373737020000000406340527777777777777777777777777175777371753535371353537573017017315373753177573731713511535370311377777535717733531257353577773137373047377377771505043504005017737200105004000075257777777777777777777777777777173575716357771775353753153717171731353737173757171713033531110301777777777735753571377777753757535350004377377777777140105300373610373320000400527737737777777777477777777777757177773515353571371713773717113035775357173577353537171531437111177777777177737713175353537757337535314000377341273777361005343243043343734000037777777777777777577765777777777735717773617777375373757753535301537135317537317131717131353173031777777777717753716377777753735753530704044204377777377777735004004337333000373737737777777777476757577677777771773757771573717317571737373130121717531713753531053530107317513107777717771775353535377757373571373531000003537373737737773400000437432700137343777777777777777756767775777777775757377573577757137377575173511535313531253713413103113115313711377777771717737717375777375753775173530404043737373773773640040400003352177373377777737777777777757576777777777777357773537777357175173735013301317130313535713177117103710353217777777777717535717377777773775377171700017373737373373730040000404040012337373377777777777777777767757777777777775735353507517317777171373515311717115153530353533503111035211177777777773777731717777577777537534371007327373737377342504004040000037373736373737777777777777777757777777777775773577371731371775317177111321703130312135351313571313503531317777777777757377177777777371713717371521720500737373730301600400004003737373737377777777277777777777777777777777773577357535171701735777177771511353510116171310112131103111353135777777777377177717777777777757735173173700300373732161733400004007773737373373777773747477777777777777777777777773717353735301717317777177373771313135317171731717171313071301735377777777577377777777757777371735341373004003725240372733704002120063737373730777244345657777777777777777777777575775757134353715777777777177171617101137371121130131015353137777757777777775777777777777177535121737214001730000127337340003737003003737730003747434727777777777777777777777777737537371711135773777777717537171711312577133513713171331330757357377777777777777777777777753103571733733732040040613730034373500404373732013344346454750747777777777777777777777537575353716135356177753773535313035111352513711711350171117377377377377777777777777717153737171333773737040000000343430733736300003372000272434707256776777777777777777775777777537377717317125310177771535371715137305313153713712135330707537175775737373777777777737357577357773373700000000040000737773737030370040000336454745614757777777777777777767777777757535735711535317717073537011313411137171211351353531175353757737377757777777777777775737317333377370000404000000733733373733770004004037307257165677777777777777777777574777775373537571373130171711353751371371373571315353125313713537777373757737775753753777777773775773777307000400000400537377377377370004000000000745677725777775777777777777777777777777573537377177517170535353131071511053534331353535710172571357753717577373773777577577675033373337030710000000021237337337337000000404004007165747777777777777777777777777757777777777535777173135133531353571123713353135530353137313573767353777773777753577537437737070073777003733250040021373737737377316000000004000377727377777777777777777777777777777777775353537757171733513175271317151351357133535317111777171717775353777577777737773535753007340030733437300003724000323737300401600000000037747777777777777777757577777777777777777177777717737175351343531152531337135373171313535373707771771737777773717371717177737377733000030373730073771000007373702533121000040613737377777777777777777676777777777777777777737717517757125371353171353515113435353535353313571771770775653537577775777377171657173573400437233070373270000037342503363707000031343077777777777777776757575777777777777777775757737717777135357353171312312513133537173171703471771771637777777753737175377173377173773500005030373373303407340002527373000121720000777777777777777675676767577777777777777777777571717717107135352171715353710513113177161771347167171753537537375757377137757176170773700030737373737373300000043713250727372004007777777777777777567757576777777777777777771753773771731713535317073537131131251347537177175737717777377757777572735717771737717735357340373737373737304000040000605233737215000277777777777777777756776577777777777777777777777771717471753537531153513516113161337567177637571707175717736173757563707173535217537717170737373737376000400004000303773737321211777707777777777777756577777777777777777777537175775313531317777773533752137153175773574175737371717377777577577353575352527535737537763737373737373300000004000007733773737373607777777767777777777777777777777777777777777777777777531775777535313571317113317177577377537575670716177777352537777165753517172516153535717337377034014000400005733773373737300007777734347777777777777777777777777777777777577171753175713773771757173531735777777375734347371171617617575777757016133134361615217277173752737303703000400002733377337733734000777775674756777777777777777777777777777777777777773775303753757171377177171777717175775775174777071717763777534357715756717535125017137343737021633737300404310242337733470000007734241434757777777777777777777775777777777777777753777153757317775353353777777777777735734371771617717577773577357020115213434171257417353535001733730700037700004337733032420075676564743647777777777777777777477777777777777757775717717125777735353777757775752535767577576171771773717777147707152527571007055213735373730061673700373730000033610403713100241450470745357777777777777565747777777777777777775373771753537177173777753777773777776117717717707077175775707370535211357000505321756171617050033030377373600005340002372372006564773464767777777777777777767775675777777777777777753573717537177777575775777777534157434717757717167737737757173531525353410125570716135317304043437737373735320000405373310150473775341777777777777777775747675477777777777777777773573737577777577025677777577777353534357375777175775771616516503134353434121534357434315300073733737333734000400020342063773477434777777677777777777777757477777777777777777567777757777777777707571775777757525257357075776177737177141753713040535251000572515235315235173737773737770000000040004017333775773777777477777777777777770743777777777777777777756577775777577777753675777577737753525707777717753757734004005340017253505035251637512521163033733373733120004000004033337777437477773773717775777777777777777775777777777777777777657777577777757775777777357753747734100775701657370400005341153415343005071071410710507115063777373560000000040000377733773737777777777777670747777777777777727777777777777777757777777777777775771435777757775357534175377751774340000007342161617141000570161710712527031003373712134000000001373323737477773777777777741674777777777777777757777747777777777777777777577777777777777577377177735716107577377775100000014105141707107000000101071351117140377250073733000000360307373737777777777777761765453437577777777777777765777777777777777777777757777775777777775756717563475777657717534000004770506170716500100014303125306736037000007372730000173000003373773777777377777560563647467777377777777777536577777777777777777777777757777575777777735763753535717347777400100001536514175010140505211141507510517340040437373730033270000037207777737777773636561441641773777777777736464756577777777777777777777777777777777777775771757777770755353537500404167536170177710100005250003103712500040000043700037731300003000077777773777747573464344377777777777736753574356747777777777777777575677777777777775377077777577775277747743452525353516156150741410001000304341250040004040000737732736331200000737743777737737377504437563477777774757746065670777777777777775657677757775254777777717717357757535705371757341757765251617275100040000100517165000004000004373773373733120000007773743737707777703737776173437777777737357561477777777777777777775757675777734757777737757776376777775777357350717175071757524050100100052050100404000004006377377373372000000043770377604737377747737374467777370737777725477777777777777777775677675777757770757174757753575357717725257657756756177161613531214015000050040003304004003717337373377000000000743777704061677343737777737173706577777774773773775377777777777777565777777775777277731343777774735771757705770735717056140561405001700041000005373030403720727737377300200000000377700404043714377777373777744656277373737777774767777777777777777777777777777575757574315777173577775075773577571653535257170500534001100400337340003171000013773720031000000077707440442404277737377777340614045077747737777773577775777777777777777777777777777777535777777577765777373477537775256525507414341710406500016737370737234040273370177273040000700406160040405377777377377704607064343777777773777774725677777777777777777777777577536525735771077561775753567525775375707143705376501010400030400373737300007340060335370014137440604454040737737377737434740544144777377773777736161475757777777777777777773777777753416567167707176576757357577777525716141735710040400040403777373737737704004075737203633606160100600437673777773563434042424637377737777777456576706777777777777777777475777777777771714141414753571775737252777571657177525705040004000737337373773340000000020201737373604437340443700047373772537737404417477777773773617252414750777777777777767477767677777777777777777770777774165475757773477377470521400004000433737737737374004040404070737373730100737003737070027742563737717707737070737777477777756740777777777777777757475757077777777777777777574757777737773774161037373073773160000537527737373770034000040000073737373737347700737734043770406177734707373742563773743737371614377072777777777375253434257777777777777770707070737737773777352407740407073237000343600000377361073434004040717373737373737077737373737370000404361773777777356177044377777777777777757777777777777747475777777777777777474565654657777777737373700000007373703173373000037302527373300400030233737373737700000000000000000000000105000000000000E5AD05FE")); - strs.Add(func1(6), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF00000000000000733431247777777777777777777777777777777777777777777777777777777777777777777777772577777777777777777777777775677750043507777777717677777776343737737172736373635337373373727300002407477737777377377777777777777777777777777777777777777777777777777777777777777777777777777777777776767777677777775247757777776775761707373737237372737173717377373777363737733477777777777777777777777773777777777777777777777777777777777777777777777777377777777774777777377777777776777767677760104357777775673372737373737737373737373737337373337173732407777377777777777777777777777777777777777777777777777777777777777777777773777524000000000000004165777777777777777527750435677777773734737371737373173737373727372736334737337377777777777777737777773777777777777777777777777777777777777777777777777736140000000000000000000000000040507777777777777770041757777777733737273637376373736373737373713733737637777377777777777777777777777777777777777777777777777777777777777777777734000000000001404160746740040000000040657777777777775241677777377737373737373373727377373737353773737237377777777777777777777777777777777777777777777777777777777777777777735210000000044767773777577353777777652040000043777777777774161577777737725373735367373737317371737233373737737377777777777773777777777777377777377777777777777777777777777774371600000006177737534247043414747416171777737000004077777777770043777777773737373737337371737736372737776373733737777777777777777777377773777777777777777777777777777777777756370700000004577616506461407404740043406060407437760000005777777775241777777373737363737737373633737373733335273573737777777777777777777777777777737777777777777777777777777312777700000407773052507005040400000040040414052525041775340000537777775340777777773727373731737373773737373757337373637777777777777777737777777777777777777777777777777777753434777000000077757047040404004000400040004000404040406524177704000477777774177077777377353772773637373373737373237737373733777777777777777777757777777777777777777777777777437243772500000477725242404000400000000040000000000000400050412407772000057777777407477777737373337337363736537343737773373737377777737773777777777377777777777777777777777775373607346750000047750404140004000004000400000400004000000004040443400577700007777777001477777737277737737353733637373733377363734377777777777777777777777777777777777777777176372577747770000077725257040404004004000600606070745424040040000000400561617700004777777403777737737337337173737737373727771325373737737777777777377777777777777777777777763617253476347370000067745040400000000406574757577577577777577777704000000040040407770001777777754777777737537727372733737373733367373657477777777777777757777777777777777777535375361767356776000047710343400040042456535377777773752713637777757774000000004043430770004777777037777773773633737373773737337177735657727377777777777777777577777777777773537270365763565252710040775644040040042457373765725730577757757577577777777640004000040450776000777777414777777373773737373172527536725727373577777777777777773777777777777373436071675364743363770000077205340040006577707161775735476177343777373776773777740000004000434170400777777434777777373373737363733736717737776563477777777777777777777777770325253437767164733256577400047705404000004753520712577073527717707775252572537575775774000000040042573001777777057777777777373525737747773770771737373777777777777777777777352137563767743706733565777700007714742000407573672171657617161753770773537357357757777777776000004004050774000777777077777373716373737743737167077273434777777777777777777737716376562570752743712567776776000477600144000256171353435753707167370753073435257743727737777577400000004250376007777777007777773737477773776577737717773737777777777777777750730707077576772703725777747776700007705640000057177071253437617343572534771717077717353531653737777700000040040577005777777757777777773716577373727537772377733777777777377301273472777616312171774777567677770000770561040004347712165617561340177353473563435752717073431307171777400000004340370007777777077777777777673635365373673757773777777737163434767747374161631676765677667747776000077524004000534712161731347317037725347172153772710725343574716167177500000404004770007777777517777777773777777737737377337377377777727073777706347436373477777767675767776570007700534000004716774352164357075053534363717257713770125352131616107037600000000700770057777777657777777777577737377737377737375337164177474617716303434767675675675767577437000077564040400034353316171356371237773057170717717703073527074777777777757700000050601740077777777727775757477777737377377737737377727077607273630716777777577567767676747237760007702014000004770774317070757071407307277353653631717143577777777577777774000004041403700577777737575777777737577777377163763576374177670734307076657677676777676775370737461000570655600000061177130707165217121770775317075377143434377757317177775777770000000040477100777777777777777773753777737737771777735777601271616777777767477476767757363437073770007341600400004576174353160177707525371737613777316317177777357736134361677770000004161077007777777777777737170300777735673773737777670761677776776567777677776567347163477477000477041400000037716334343170537103525356535616357316167770537305070537171777770000000040077007777777777773507140500777773777777472731271777567475656776767727037352736752707630043707560400004547357435252077416343036373721775325217577072534373172534361757740000004340770047777777773052500100005777775617617357761677676777767777656350343761674775274731400074040000004056371753121735701735171715717177733535773713535215257053437173773700000404107700777777775705210434770007777773773777777777577476767777257316377341765770725321633041734304000000775772765343521763532070737677375343436570761253725217343107252577400000042407100777775210705070057750007777777777777777676767777652707306716407665361635325333700077054704000007525351734303525172553035253534737353577731743071717053167153173777500000141077005777775615250575257770007777777777777777477773435270724735673725326121633736173000734214000004756572737571613472573257125777273171257713430353521613707316361616176000040060530027777771614377725437741017777777777777767774347361437573467342530713373361337300067425400000401653715257303425357705302537717577617776161735252535241736534171737750000004106700577777777435477752577704777777777777777773337325277462567134312733727353373733400171443404000741745635217753524735737171637773713777717161435353431360512712073577700000004217300777777771603577743077700777777777777774346164775637572126127373633733273370733006721040000000747375735250717134731707031527565703757725363434361655372510717073077400004054075007777777775743477747077750777777777777337357736473402163713731733573537316333700017547040000051617436525377616571743717563577377775737170153537171325052070707147375000000001720077777777777051777705777005777777777776164625653343337373373273273233633737373004770605000004060471753752171770367125752317777537167771617637053436503735371737335700004007427100777777777777476577500777007777777777757735733252373731327337335337373523731734007701424000007147430743717071755707737357707777777771721613537073513752525252525777000000401437007777777777777053577614774047777777777625620707373361727336137337335333731723300037525004000007057717147677072705353434375735775775375717617073527703717173533521774000000400730077777777777777456777403770077777777775733737337353733731737327336336373723737300772434000000447675637717177153652757737073577777777737731743577170750707052503577000000402407500777777777777777251777147770177777777720703333613273363363733732533735233371730005705405000005357177170743416365351271577356377777771653565317217371273735271777704000000050532007777777777777775467776017740777777777737336173377317317331271373373333537323700067007244000004776574173577355734777172357375357775773763737635634375353435370777000000404002710477777777777777777147775077700777777773333337373337237337373363373072732717733700177141000004034717372532516375734352541257377773777777177535735735271617070777740000000025057000777777777777777776147774077704777777736177336374337336327337373273373373323173000716064040000473617577053617527757773375375307177777177737773734377173753777175000000000404330077777777777777777777077770577437777777337333713333631731733633137337317373737270043705500000004775776175301712557765357432525777777777737657257537707161677577770000004040033400777777777777777777774177770777077777777336363377373723733371372735732733631733320047406040000005723573077770353253177273573737177717777753735363753777771777303400000000050471007777777777777777777774077770777577777733713372336173732730373373323733613732737300017014204000025707170014774353043417753575777776777777777777577777777777774353000000040403700477777777777777777777775077743777777777363373173733371373737327373731733733733517000770605400000477716527021775707353771763736573535357777777777777757317777530740000040020070007777777777777777777777770577747777777373372336333536336132733533163363373363172270004350500004000571205710170120775735077170717253777771775777773707374775743070000000004507100477777777777777777777777770777773752536773177337363733737371633727337337343136175370005704244000000775207770052501030437177777777777567777777777757756177777352500000040400071007777777777777777777777777777777763777757336337137333713337333733737137123347436327570007705340040004375301772102161430525071717775363717777777777777777777352017400000002401700077777777777777777777777777734373577777777337723635363727127373731323612547323575716300053404044000004770707170014121043035377773537577777777577777777777775251700000000450070007777777777777777777777777370777577767727337133373337333733737300272561252361756363637400077007000000005771616570612525352527753777777777777177777777777771725364000004040007100677777777777777777777777534777776777353756723673353633773733030735073076777776777735773700437405604000004771610771701020353717677577777777577775777777777773537100004000404370007777777777777777777753736777777737257777773373372333730312163434261677353535737775777773400437005040040000771630777775753757617537475777757145735777777777777774000000400017000777777777777777777773775777777161757777767773353373733437256143737163534372737573777777777000570524140000045775771614361674217343563777777534735777777777777714000004040407710077777777777777716353653677753437776777767777372334330343704307234256352737353773757377377777000770416004000007777577777577535747773757377516043577757777577753400004000005370007777777777777777777777777772777777777777777773373336161720736714737357737537373777277777777777000572407404040007777775777777773731777374777753557577777777757741040000650427100077777777777777777777777473757777767776777767734334072525734716300077371737737353773735777777777400353416050000407777777775777777473475377753502537577777577777361040400407710047777777771657777777777777777777777777777775337336137252721630616737717673633437361773773777777777040770407060400057777777777757777753777575752757757777537717775004161400771004777735256161352535777777777767776777777353637474072725256163073733752773317173737737177377777777777000777054142400077777777777775717777777777175535777536575757534704142573100776150505001050041430375777777777777777257677777737253525236177173477771353737317131737377777777777777400177206414240047777777777777777757405147537777716553577777405256053700007150000000040041001414125377777777737177777777777725207337177372373773777353014307471657075373777777777424057516414340000577777777777777000065217575777616757177707074017770006500000000000010000100210525275777777777777572534333525737373337337377371301201637737373737725477577777777500077701654045042525743452540500400534577777775751777750474057770005010000000000100001050215050105177777777777763773737707333707377273773737525034373731737777771513707757777777740007774006524004000000000000000007507357577771777754707017370000100000000010000010100001000030712107577777777537377373737373736335370343533125373501434143113170755757657777777774004377500416504040434000000000043565737777742570525405775000040000000000000100000010140121411053503177777373773237373707373737336172777043731003471077756740010217717777777777777004137770416165240404040400400043575757775756164007773000141000000000000100010110010100501421052507177777773775737373737371725616252127530047741647077657777435005775757777777777400407773404054165210207040404247177777534004537771000460000000000000000000000001000010121143017107137737777373727373730636163735717753057777064704775357477706135777777777777777740000577771600404444540525041404757752407573752000447140000000010000000000101010011410416105710713577773737373737371671437170763653007004374014707764652574404431577777777777777777400001777773500000004040600000001757777740000477740000000100010012011000001001000121103530171053117777773737330631637436370343743704074774060565735656571606470757777777777777777774000041777777776716350747777777725000004477777400000000101010510010350101041034143501537171070737737773737671477073616177770340416007706560077440617764040435377777777777777777777440000004161753757775352507000000407777777700000010110121013013525201705103501210712507071171773773772731637212525777777075000610477040056775775776504746475777777777777777777777777404000000000000000000000404777777777770400101001201010701210111171013041035070351717127147777377173777077777777777770524041470775076005761474756765777677777777777777777777777777777765616442406146567477777777777777410010101010101010105112530172053171417155071717503177377737373212577777777777735004200420764054065767470757776577771777777777777777777777777777777777777577773577777777777777734010000101010000000000010035153101731713071352513543777737737377777777777777774360404041457704204074543474765677656577777777777777777777777777777777777473043547777777777777777410001010000000000000000001403016171071653161717752177737773637377777777777777735040004160077004702524246056565765656777777777777777777777777777777565173516170034173777777777771000100000000000000000000000105010001711317170735017737773737373777777777777777470040400070774000404004147677775777775777777777777777777777777777777777052710734537575777777777771014100000000000010001010000001061520343435353537017773777373777777777777777777354002404040770400474256157577777757347577777777777777777777777777777777150705010527771775777777775210100000010100001000001010001000140151435357153073773773723777777777777777777004040016016040040005057677757675775734717777777777777777777777775374347070034273417347777777777777530000000000010100010100201601014134303534307705374373173577777777777777777752400040640404004140524775775775777535553575777777777777777777777707535712016531750774737377577777777740001000101020014010011101125030411753411711077737567777777777777777777777712404040160404424240534175376175357563743525777777777757777777777000473417013400301717574577777777777775000300001010010014004004101413061071701077377777777777777777777777777777752400040525024141700434165757075347577577577777777777774777777770071403016701250077073737707575777777777700170500410010010101030521615171307777177757737773737777777777777777777300040000406502524141435716175717537573743757777777777777577777025420350011077006516174771777777777777777750010011041043016161052141034377777777767727777377777777777777777777777174246740440750050343570717521617757575757777775757577777777777503505000000734717217717577717777777777777777161000100105010105214377777577773777773777777563777777777777777777777014777777700050304101034161755705277777757777777777716377777777740300000401413714770737057735777777777777777777770716125252525777777777775777773777717373777777777777777777777777125777777570340102407537161617775417577777777777777757077777777104034000720407217714717365771757777777777777777777777737777777777717637737737757357777777777777777777777777763536535074752050014251716757173565777743757577777777777777535777756010010037053505771771657717677377777777777777737377377777777772536777777777757377777770777777777777777673717176777034347205007061125071307545773777775737777777777777777773777703400007041272125367165341773575777777777777737777777777773773777777377777377377777370777777777777775253747776776777735075703414104025347753731757357776577777775777777777757777410000171005714734177177743577767737777777777777777777777777777777377537367777677347777777777777673677657776773717074777714710034375373312301610307707577575777377777777777773773474040061730037716170773776177177577777777777777777777777737773775737777777673577777777777777777577577777253475677777767771067377337107351171310110713577777775777777777777757752100000173407750777077357717777737757777777777777777777777773777377777771735777777777777353673676772763617767767776776573425736530712730303601013031165375777777777777777777777605200716152570177716534777775177577777777777777777777377377577177777773777777777777777737777577777773757657777777776777571773533377731713101173011103125375777777777735777777777005721712073706136173525347767707737777777777777777777777773777777772577777777777375737777776777437477777677767677777776077373563167723010767753031101134377777777777777777777777701703417161177417761777177177077577577777777777737773773777777253777777777777775377775677777777777777677767777767717617725363353713111771110101410310135357777777757777777775770340147350167701673577707737777757737757777777737777775777677377777777777777277377777477177437776777767777777371716761771737135361774765213031713371431016777777757777777777777774034217236530777143761772577177377577777777777777777777735377777777777772737167767167337677777777767777767757677777343737037635330135771011101215073537353777777777777777777377377041605753053770757177752577757707777777777777777777737777777777777377375777777577737477776777777777707777677767675775277717325136127773012115301102114353777777777777777777777777353731257770177307771777073777777777777777777777377777777777777376377777677673725777777777777437777777777753717327537177735373517157741311210125311613077771777377777777537777735671477730077716571277717757777537777777777777777777777777773717357747777171765777677777777777776777770737363737577373637103016330371770121313530567101777567575777777773777377777167301677716377347571773437777757777777777777777777777377257677777773737777777777767777477777777773373437372733735253127353710534371353101017713533125777777677777777777777777777716771771617771737077577707777777777777777777777777774377777777677365777677777657377777777777353743733737173727773353530343773135161253531277030103527777777777777771777777777777717670777741677525723757771777777777777777777757353777777777717347776777777437371777777737257273737773737373577716303771717170121311727031731135312577777777777771777777777777777771771717377177773577377577777777777777777773727777775763527777777777777373707677777773477737373737336373737377331734770307353177163513177503031253777777777777177777777777777777777072777716177177057777777777777777777757377777777277177777777777732537347777727737777373737737637773727373343523131371307773477353703437313431477777777777125777777777777777777777570707777167777376177777777777777737377577777477377777777677637773657777735773477377777737373737373737367373561343071703477375301713101713167777777770125777777777777777777777777773752537171777177777777777775737777576777773757776777777735737577777347637777377737373567353737371737337373316131371173773537730353330350717776101577777777777777777777777773737775377776772577777777777753777747776777352777677777773437737677737776371777377773777773737373537373537735335731352536313572163531234117077771717777777777677777777777777777777777777716173757777777777773777777777737737777777767777377752777377761735777777733753737373736372736372733363730525373535273173173435137253677777777777753777777777777777767357777777767777577777777777753777767777767735677777777735377172757757725377777777773773773737373737373737373763731731125737331343152173727101057357777777753777737777777774377377737777737177777777777775637777777777737177777777777737736167777777361777777777773753773773727373737373737373373727352112521637336377353116167777777773637777777777377773777757777767527777777777777773737777777775370777767777671771707777777572343777777777775373777373253735373537353713735373736377250575350531710705617377377376177577777377776573577773777767737777777777777772777777776777377777777777777376377777773772357777777777777737773777377373727363727327363736373737337333016177161071737777776356177773737377775373776777776777717777777777777373771777777775377767776777775277717677773752177777777777777253637373377377373737373737737373737373737317373737074377777737252177377737777756717377777777774734377777777777777275271777747743767777777777776375347773770743777777777777716357375777377737377373737373733737373737073034725616527377434361617377733737773737373777777777373737777777777777773707377767767373777777777777712717277736577373777777777777713737737737377373777373737373737373737373737377773773773737773737373737773777737377777777777777777777777777777777773777777777777737777777777777373777777777773737777777777777373777777777777737000000000000000000000105000000000000A2AD05FE")); - strs.Add(func1(7), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF0000000000000033273373337373373373172177765677143477212657777776567776777777747077777777777777777777757777754757777777777777777777377777777777777777777777377777777777777777102136770007770000373373373233373373372173613777767773617717725777776777777677777777771777777777777757777777707746757777777777777777777777777777777777777777777777737777777777777752412576706033277337317373737237337373303763470777675672730737677777677767777777777777777777777777775777740447575677777777777777777777777377777777777777777777777777777777777777771252637616373333733733373333733737337373137377565777574777271756777767776777777777777777777777757777706070047565477777777777777777777777777777777777777777777777777777777777777777701043777337733732737317373373233737337375236377276777617677374347777777676777777777777777577777777405771065772577777777777777777777777737777777777777777777777777777777777777777777300333733732733737237373173733737363373535275752777775367377774777777777777777777777577777777404177774065746577777777777777777777777777777737777737777777777777777777777377777777770733773773373373733273373773733373373733123375656767574737377767777777777777777777775777406546746750074756577777777777777777777777777777777777777777777777777777777777777777777773732333337337333737337333233377377373737734373777776777477737357777777777777577577777560654257757750475656577777777777777777777777777777777777777777777777777377777777777777777773777373732733773337333773737337333372733737343707777777616577737777777777777777777760475604047770640465756567777777777777777777777777777777377777777777777777777737777777777777333337333733733373737633373737337376373773737373770776777777777777777777777777777770045253404047475240434756152767777777777777777777777777777777377777777777777777777777737777777373337273373372373333737337237327337373373737377377717777777777777777577757757774040404645256561764571656747671374767777777777777777777777777777777777777777777377777777777777737333737337137337237373733733737373733737373737737737777777777777777777757777771404250041435614044406774475475277635177777777777777777777777777777777777777777777777737777777377337273337337237337337337273773737337373737373733737737737777777777777777777777642404040040404044000447770477465635267252477777777777777777777777777777777777737777777777777777773737373737337337317337337333733737373736373737773737737777777777777777577777741450404241000000007440777770475747475257353701777777777777777777777777777777777777777777777777777773333373337337337336337337733773373373737373733377373773777777777777577777704067000014104000000740067775740474747765624721676577777777777777777777777777777777777737777777377777373737363733733633737373733373337367373737377377737777377737777775777777770474757645650000000444005776563704657452777752567312047777777777777777777777777777777777773777777777773373337373273733373337333727372737337373737737737737377777777777777777774052474775347050100557000477757447750076544347772524677300677777777777777777777777777777377777777777777737367737373333737377337373737373737373737733737737777377377777777777777006440424675747446577604077774607446774476564342477717077731257777777777777777777777777777777777777777777337333337373733733337237337373373737373733773773737377777777577577777404704250450476400247400407777405440045704056547707047677404673025677777777777777777777777777777777777377777737377737373273363737373733737373737337377377377777737377777777777400474040405246750045404040757040640045426504674763736342567773447312107677777777777777777777777777777777777733333333737373373373337337373373373736737737377373737777777777777740045404040464144244343440577644044040060456714074454775256347477256256313077777777777777777777777777777777777377725213737377377373737273727372737337733737377377773777575777770004061604040564044047440777740040000444040444654565275677365267347356346243066377777777777777777777777777777773333737721235337333373733333737373737733773737737737377377777774004240474104340404004750775674074004140000040407706565477767537124765674716527135677777777777777777777777777777725217470773733733777333777773737373733377377373773777777577774004414043414004770040047777465047504070400004074757744656565777652532126167653652463150767777777777777777777777777737773773470723730337773333373737373777737377773777377777773400004647751000004740000467774164074000500000007404777714742567677777656116347747677167273705777777777777777777777777470163573777561735323577773737373773373777373773777737777740434004041601000016400005777704157700414000000040477777604756565677777776617307247167734203630357777777777777777777773777743675273776727173333737373773777373737777377377777740000470004351140004440007760746576770400000000004077777775504654747676767477765325727756565743070727777777777777777777163572777437577717777637753637737373737777777377777777770004047416405040000400005774054056507440040000044424777657652447565257674767646777430347656376347632531677777777777777777743353437777252773537656371737777777773737377773777777000000507471401100000400776140424075600770040004000577575750657006565647765777776777777737274074771643673134777777777777772777737125277777476777377777737377373777777773777777777000404404743400004000477547465140005405640044000477764774250756506565677767776747677777701277160677743466330147777777777353473777737132537777177777777777737777377773777777777777000000040040004400057706704100000561404040000457760536047740640456474767764765677676767761216770043777114636334176777777737777373777777771777777777777777777777773777777777777771000040004050400047777444410400004044000000057671457654565340477047474356777767647677474777610036764647673652437213677773773337773777773777777777777777777752544644647777777777771000044004770004774340007410000400404250747775440675000044000477447437271667777765777676777773531212716471673707243177777377777773777777377777777776756040400000000000657677777776000004000400177454740001000001400404777777737400770000040404770567473475375677767777656777767470712616674747657343063337733773737377777737777775250000000000100500400040147777771000040000577407604044140000070000077777414440475010000000077774047747276167347767675675646767677251213434717274767377777777377777737777777765000040500725656572571414004004537770000044716565604500401000000404005777750640057105000000447775704776775616735636567767676777747677767343732667477356733776177777777777777775000400070775777777577677777525000405770000004774041406470700000070004064777740040247105000040777770400775677671663570747777676777747477774761617136346657777377373777777777775000002577775774757776575656757777741600570000004704040414040500000440005074477140044041100000077774400043737765675743632342771656766767665676767616137353676177777777777777771400007777656565777773577765475647577774140470000004042407404400000040004774405676564004100000007754000007377771777767765656353077674777767567777677776530343377377777777777777040007774747775777757056175357640757675777701040000004040447340050004004474040065750400471000004750400007777777777070756565361607603436747776677574767777677337777777777777777740000747774145770775311110535375744654567775765000000005040047740400404034074161440675040044040757440000577777777777776372765677761743613716777676776576767464777777777777777770000777744776452577525343010105071741650575777777450000040400440404000004465406560045640040000777400000067665677677777756753774360767253652716056776776756777776777777777777777000177543474453457757115115014100165665676565657777000000040040040000474047500040045000474004757400000054745064040604656777674377574707675247273734677777677777677777777777777100457756744045657775315773701211400157575757575777777500000044000007577404710400005240043777574340000747664646476474464042407777406373465436734342437147677656665677777777777774003776054656161657775771775351521014377777777777565777740000004405047473404400000044160447616504000044747475675656476566546404467770437327657474773432737167657767777777777777000577056404047577757735775571353510015777777777777775777710000000777407446100000000074400775404000056767656674664676474566474424064776035307276676567476163437277777777777777740017747475675774757777773430014116171077777777777777776757740000044750605014100000007040475040400047747474656477475656666747467464046475727307135256353617253617477777777777771004770747477577177777775351117113105105777775357757377575777700000004740560400000004754707504000005674767677777767767677574746746546400066435332523725665765670723030777777777700077775777177177177777775071010141107127777777717777777777757740000007704071000000414604740400004677777777776767777777767676774746656464047663733703071725661671747677777777774007774775777176175357777711075531305105577757175717577777777777700000045704461405040405714400000777776776776777776776777777776767656656474040561733373030721765467253677777777700177577777177535377777771035312150110127775737370753517775657577740000074400040060407740400000777777777777777777777777677676777777765665646044642737373372163127345765777777770047757771717717777577777701515715310300577777754153534775777777777000000470004004047754040000777777767777777777757777777777777767676776566564600470733337333312525272567777777500077675777735717573577771103031710514100775771731356571717775775777000000040040405777400000077777777777767676466656747477677777777777676566564640463737337173733321252777777777007775777535707773577177761511430713012102777775534317775635734775775400000470400777540000077777777777656404405416414707407460656777677776566565604460737033363737373303777577700077577753771717577356177530161151715351057535773515777711577475777770150000405777400000077777777776400441753777111373511701454206467776776506746400452337373333233337337777775004777777775075777375711573117111214311110777777150377717077775777577704770000044540000077777777764004167377777710535751305157335501044677776640656540663733337335373533777707770077757571735717575777771056111715315707017717157357753471757477167777700770000000000007777777764000535357737773131173315121717533757100406777746066400473372536333233633775077500777777775701772535777777157141215217500007777357777413575357477577577505770000000007777777774014171717375777771121753121525733513317711404776756164640407333337337333737770770007775777531771517573577777731315131530011075777777773777307777757757776007770000005777777760407773131617737737131113351151173153051713771004277674674404633737333733733377507700577777717057053756357777777141717077501000177577771715715757575677777750577770000777777764053577115171353777753010377101217351313131353177300467764067404373733163352337770077000775775771317161715777757757170717537011100177777775735777777777575777700777773477777777412537177312135357377331111311315353311511050117357710007777446044333277373337337700770047775777575017571777715353757175753501070100577775775725771777577777577705777747777777440513537371117131335377112117311130357131311317153737737004767065044373333373337377007700077477757353573577775121514377173750351010017777777777577475777777757775077777777777740713712575730311435137313111035301115331011011503717113535006776442407373737273733770077004777777775357757777531510135757775357507103777777777777353527577577777704777767777764171371535337111131303531713013131134337113135303171701711777000767640433372333332377700770007717575777777777773010034131777777773101157777777777757504153777775777705777577777517371113537737312531713433111015131111517111111153531131537377500774640673371737173377007710077777777777777777751711010415377757575177765743577777773534747777777775167777777744357371703111171711311111053131037121303131313012173111103577373700677440173373333373770077400777577775737777777131001011205777777777770171715347777741417175777757760577777774173735121153737331310121101316113753111151111011717310301773317577104767046373373637337710771004777777177575377750100100501577777777777417501534157775350747777777777157777777413535737113131101171113112111111353735103134353131311111173115353777106764413336333732777407770007757575377777777171010013101057777777701777701010015735250153757757774077777734171733713141053171035317313134135371773110113713535312103171301353777107762437337173733771077740017777775075357777171001075317137777577577775340311025775340757777777754777775431311753711313111131131357717131031737777131713773771111173111301353777006740437333333737770777300077577177177777711101005315014577777753777530111400537534110777775777417777743535371371731111210113101373311111173573731713743157131107111311535253777007643337373633377747775000777775715257777170101173503173777777377710153701300753515257775777711777770311317137373110301131315377315313035317353121071317337101311301113131757775076073732373373777377771000771537771177777170053510150157777775747105341141101773705357765777647777541735213530353311110110131117331111013737313513135311577717311312134173777770065233737373377775777770000777575756177777710153100050357357761710717101370065757165777777775177776171313533171353313131311073717121313103533512153535313777771211115135777777775265233333373377777777700004756377375757771753010010315375775110531717161517737357737775777507777705353531353131311317711171113731311111353713111213130777777771130537733535373700703507173373777777777700005304735171777147710105001435047137351741410117777575737575177752577770537313131211312135771103105371153112131331301137173535313131131013531151317577146742333216337777777777700004004577017743105310111011161077505301101014357777777577767777741777543717135171131311037771111301173313111101711112113173313110131117773171314317177106374247313277777777777500004000537417101005710001071540473525357100017761775777577577775177777013737133133111311717373011131153113131317313117373111111311010177113110715377537014377342061777777777777000004000753504110771011353561317751050012177757175777577657777507777701713533113110311173737111131013110771101777101735313130110131137713510351351737770673434356167777777777777000040004775311657170777410110477777535757775777107777755777764177777071713435311131013353537301011311053713377353537531110113013113571713135135277577700343473616377777777577777000005000617571777577751757751177777777777777057753576777775517777741313531316133171353133531311010101373735317337773111313153117077731105137135173777506363061617777777737277777400061000425655377777701777765777777777777757053577557775700777777525713153131531131352513531311010153735737317135371301113353317777735317175735777777417163563607777777777536773000057000441657577771777777104777777775774777770747777560577777770533171317133113113113170171031311253533135313135771135271315351753531737331737777770277352341677737757777771775000007500044753771417775750407777575777577553575777716153777777437117125313110312101353113017125135373717131351177313131101121131377373511153575777717737735373777733777777777737000000771004465753507770142407777371753573747177777450777777777477313111313531111171303111311130117371335311301257011131131111101577711312110313777003733333377757773437377777777140000577300042571153750054465775771770541177777040177777777750771713131713131301131153011311110335371313711311317131131011213533771301111311141777433777727333773373716777767777300000057535014304351005243543477474071777777404177777777777707113153101313101133413111301031017173134311311131313512131371353571311110130170113501373733737773477373737177775777740000007777535011000464444644450517577775040435777777777770771353317130113135311311301131101737317331130103535353335317135373331112533511113577127327373333373337273737253736777735000000477777735315141615353777777770404001777737777777770171315213135311135311211310101317317311113131317737335317135131775112113513737713174007134377377377737373737370735735773700000004057777737777777777777744040005777777777777777561335313517131313131311311131101775717371311111777717135313131577737113533511535777771216337257337233737373737333723527377770000000004056575757474440400000017377777777777777777057113153335353501773531031113177573313131310177731131131716173777713513101313073777007634605327737377373737373773773372537177700000000000000000000000000567777777777777777777770731705315113131357773113105311577371311210137773113103111177777531311311131115357770773561362533737337373737373373377373736371773521000000000000041074777777777737537777777777704711131336317111373535351331130375775311131737353713113121157777131131131112101777506167374356377337373733737373373373737373727777777770707134373777777777777777777773772577777707731141111113017777331011170117131177375777531313713113113017737171161135111101776072525276377337737373773732737373373737373733077777777737671777767777777777777777777777737775077713135313111357735171371131433531357777713105111135311301057713131113533530177717352527525237373373737337373637377737373737377307777777777776537373777777777777777777777773770477713111310131373713011013113353101771337711131213733131111377353537377751111771477777352161737337372733737333736333373373737337737077756777777777775375777777776777777777777730777353301531171171311317311317313111035110353111110177531301577737353531377777770777777777373373737373773737733737772773737377733737343773477377675777737777767777777777777777714757353131171121171711111301735353313131311353131131037371107777373313110177777477777777777737373737373372733733733373373737333773737370347374777776777773477777777677777777777433735317133131113131031311173573311111131111317131101353131377735311300115777750777777777777737373733737737373773377377337373773337737377333433073777777777737377777777776777677057131713511101017131110173373331731307113010731711311173537777131130111217775277777777777773737337373733733732337337337737373377733737337373737352352777777777777777767777777777037531310313110217131313177171731111137311111531311121177757733131537311777765777777777777773737337333773773773737377337337373337737377337373737377373437777777737777777777777775013535311110111371711177373371373107173531037171311110171317531031777711777077777777777777337336337773333373373737337736337376333737337373373373337373734356777777753777777677760713131131010351131373717171331113533713101177317131131311113113177531777707777777777777777337313723337777337373637733737737333773737727337337377737373773735775777777343777767710771717113135303513535313173533313177131137577717173531521301315737777771777777777777777736336363163712337737373733773733737373273733733637736333737373373737273677777773737777740773717353731713103131353113535371317713512577717173531111101337777777747777777777777777313777176163737337337373773373733737373737733773337337737373773737737353736777777771767760753507353531113107171117103531371317773713577313537135311105777777770777777777777777776363737777752527316737373373373763337373733773377337733737373373733373737171777767767173100753535373531711131313311113171131135353151253111107131131137777776577777777777777777777177476377377756733173737377373336737337377337333733377373727737277737373736161757777777400711535313121107135351130107313121777315305351030117353113577777717777777777777777777737737134347777373567133737337373733733737337737273377337373733737333737273737373637777677700773535353131317131253131117371111375311311371110017317101777774777777777777777777777476777773725277777376753437137373733772737733737373372737373737377737273737377373752735637740771311353111317131311101017331307737715341351310017131137777077777777777777777777737137373737737167737735273327237373733373733773737363373737373735333737337373337373373433477300777131313053535351353111735310117771701315331101617135777547777777777777777777777777770737373777373477777756537430373737373773377373737373737373733773373737377737377337373307500477711111301313131311333531311777173171537110101777777540357367777777777777777777373737677577777377347727737473774343537373377337373737373637373373357373737333737337733373733730077773535353711171310573711113777353112157110077777734376347377777777777777777770733437033237377373737527773767377727032353337737373737373737367373373737337733737333777373737370006773131111353011131713713011777353513773110177770457436343436177777777777777737677777747537377777773716161777773777757273733733737337373737337363373637323733737733317373737371214375313531311317565351311177177311357775377700063767757777716252773777777773437716577372761716373777737373436747737725252173373737737373737737373733373737363732373637327332737000435713111131537773121013777753535777777550475353617676777271634343434777777777737074771772737373737377773713707477777777072373533737373733737373737337733733377373337337373733730000757777577577575113577777777777776740247677761707375675674777616732617716577777370777777747743477373777773737343773777756172733737373773737373737333733773337373737337333737373700050577777777777577777777777777010747777677767765271671676347774770727737777777773434743737373725361737337773777074736377252521637373373737373737373733373733733733737373373373371240441675777777777777735614045676777676767776777763434354776076576577777777777777737377777777777373777773777737737777777777773733737373737373737373737373373373373337337337337337333161434565747475656561616377777677777767777677777677637257777677777700000000000000000000010500000000000092AD05FE")); - strs.Add(func1(8), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E5069637475726500010500000200000007000000504272757368000000000000000000A0290000424D98290000000000005600000028000000AC00000078000000010004000000000000000000880B0000880B00000800000008000000FFFFFF0000FFFF00FF00FF000000FF00FFFF000000FF0000FF0000000000000021312121001212103012101120511213001003031000000000001001201000031434130127125003036131617112161707121633525212434101612140103000000001000010000001000000000000010000000000000000100102120005212143012525002070011030101770000000000001001200070431030521125306171134303436170643125351431717043523421052136001002010020100200001020100010000000000000100000021310316114104031050307010303401035203003073000000000001002101000031071430161771407072535353717341752534363761634352153525252411700000002100000100000100000000000000010010003000100114211021201343030103430100312121010301710000000001020010001007007021316161302717353434371734367377371717173525257616137171360000100104002100007000000000000000010000200000100316211203104250103016101125061614121201437600000000000103003004101313534313177500717373535773534717535377777174071301216516165170070600030100000000100000000000000000001000000014211251007100212107012306121001303410301371000000000000001001006124252134343137437775373737777707737775375377370477777532735327124010100000001000002001001000000000000000001000211230303112041352101214130106121071211037500000000100010020102043513353437177703753737753537773477777377737537563010103471634716412520210121020001001000000000000100000000000001251014304204120016125013016001413001243772000000000012001012054303614353717371747377777377777347777777777777756357777777177171610252141060000000000000000000000000000000010210130303030311006171212130305210121341301317710000000000000120010025351734353777770777777777777777577777777750602004000000016124371675252161010410002010000000000000000001000000000014316100253000125050030301204120300341377000000000300100121034070361373753777377777777777777767672525004241447420704046004100400435353070212000400000300100000100000000002100003030310351204352121217050341420150350337770000000100010210103007171375357377777477777777777752705464464604766640446464644606460704024347125001000010030000000000000001000010003016100021021001214130103030120013021037577000000012010010121610657375737377777777777777774040644466567600406400040006000000476746424400212534120430000000000000000000000000003000310313521705241212016310161003503143533770000014010030216101341735737777777777777774740404647460406040042040004620040000000440240467504040025000000000001000000000000000030000000021001001200214316110701030402143031777700000212010010107161347737737777777777727000606676764000000047047640000444644640002040000466464040020041200012000000000000000000001010013523121311041310112530303042112035373770000001010201034312170773777777777777600444664404040070416000000750000000000000000046400560000046744004200001001000000000000100000002000001000525060120430612011610015217135377700000520001121011071737777777777774040476767400000206400640425675200000000000000064000046440000046767400101000000000000000000001201010043121312121124131031215201216025125371770000024012120161637353477777777770464676440000700004740400777777700000000000000000007747600674640000446740002000000000000000000001002000000520012121006030011211201007021317377700003070010121311717353777777524476777600067046404006730331777716101031000000000000047777704040000000044664014121000000001001000000100421312113041706011413705205312101350717373000104030120534371717347777444676460420000464006421171531537133131313133130100000000077700000006740000067400002000000000000000000030041000012241130001321300121130404034333717100000603016113137173775775647767400047400470000703417133113313713131135313133100000000160000000000000650467460010000400000000000010000020013041302112430520712161033007135353637000131430314343537371737674766765000420476000065713337113301311317337333737313110010000100000000000000640046540000002000100000020010001010241101306110431110353125013002537351710000161410331353535377747664004067607400404777521111113101353313337737373337333301011300110100000000000000006620100000000001000100200020001302305112003161212102533404353353737000137061371535373777764677000702444660000077760103131212133337311773737377717310313130130213011000000000000476400060100000000010010040010001300121216142125350713001025335371700003703173173737777767777640046740000470527777012112101317352710033773331773001331371011011101301113000000006774000000010000000201200121020305116125000351210330107124137173527000713547357377777777746464000006460000677777730113111203131311300013777373172101073131030121301313011200000004674004000000000001000000000100121301031250215214136103106117173531001733717377777777676400000075000000057777776101313311133737337310003777377317271373130113101310312111100000004460000002001000003004210000016121031304071211213012507017373617000371753777777777767670006746460000773737377300131373733773001717000003377733721037310131213131213013031300000006740000010000001200010003030301007061002121025341703300737171700017537277777777777767400074006777377170737735013137773373100000330000017177773103373013101303031311301110000060474000300000000301000200100001031131121417017110303114343537373016333771777777777664000066470171331333331737720013177773770000000730000002003773737330003121131313331303310000006764000000001000000041002010007060021520013012730707210073777771017533777777777675000000002533131737173737337100113377773773310100110000010001043735300101133133735371101210040047764000100000030001200100210131135132106107251013101777777777073713777177777747760066000173307371313331337373000311377773777770017200000001000331031000031313737731000131012774066400012000001000020120030000021012010612310123716173716577717171777717777777776006500077317133333373733737710013133777777777310031000000000131303130001313373750000000101304600474000000000000007010101001035131215300114313501210370712530777373737777777666440764617337333017371313730333700013113370737777301170100000013131373010001337377300000000310000000460100001001200000020021020012021210706030612353017710712531377777777777777400064001737131373213337331371733000013013510437377773332101007770131343000001777371710170000030040476520012000200041210010000101215141210013011215213710131253075777373717777760000000073733737371217133521333770000100313000347777307310207777100600010000131777373737310013104607764000000001000100061201200021213030300705321521435207701347777777777777766704760007333533733335313313337173300010010312000103773731031177310211111700000127773777777001210070067600010010000420210101000100141203150430120512121370070077131677377777774776007461033733733717333335317133337000000013113000053717731003375311303373700003113777377737101004670447400200000000101020000300303030142130433130717037001701700771177737777766000006043173733733737371303033525373000000013113131313331031177731311153777710003031000077733714000400642000000000012041012100000003152112103050031211770070070077007377777776400474404333733731733331331313132133331000000013131130311213037773131333377777771311021001373773000000076410100000005001020000210100142111250241307125377103107701700377737777740000060031753353373735337130303013353530000000011313311131131377313537377777101107003112121777300600027640000010000020303012100020002112341304170314313770077073037007737777766700067427533373377333337137131313352333531000000131311333123537373313137377777373713103011100070067600474600200000010100400000010100011250301202170307317300701700700137777777777400040442153773337371333131303052317121212100000001311131133137773313777373737737717133313100040047000674101000000202121030120020000341330701407035317770073070077007737377776400200000053333373737337173130313313312131030231201301213523173377111217377773737737733111210000645644046600200001004110102040010100400301010300313521737205701701701773777777460047400601317177373313713313371361371213002113173130331303353337733333137373337373723734331001000066427641001001200210602010121000020330703431140703171771031063077003757777767400246407643737337353733371711131331335213112030217313071301337777310103123777737337370330101001000400465603000000001201050020000200410010303072121717373702560500700173737777767004006046013537333313531333330731731213030317131212353303737337717313131113230717735350733100101000000764000300000001021210101210401213431103100431217177053017037007173777774676470000700533737373733373171731333131303530303031313210313333713731210130311010313133333130100310000064003010000000702500002000000034003070710613353737301300700700173777777767406464046653353735331317137333132712521313211313035311337373731217371000000000000000000103010005600054404300205210210010012000100243413103111210417353535007012071037373737777640006700004217313333737333537317313131303011730301231230133133131213773000100000000000000000420064046676030535301001021212010142041012200710217302412173730300710300435377777765600056400744737371713137313317335313031713231313331331337137131311337777003500000000000000007406400076434777777777773500016030100006015011211210143371217007013007053173737777767000600064072531333373713737337333733121311030310331217133313131337710001003000000000000560040670004677777737337373777353001002000413421217307034215071710700700700317353777774764000052006653535353373373333733531353312133135337131333313131353770000130101000000000466460000600247773733373737337336165102500601200121210117104333173001030042143717377777767000006650040033333371337373533733733313713103033112173131313121333000177773301100000016400077404444777373373333333333337326100010301430007032121214127171070030140313035377377764000000600005735373371737373733731717331373131123312133131313133771137777777721300024600004660067673737373373737373373333107202410421070117110710433512103035000007161737377777400000046460463533135333733733533733331731333733131313073121131373377777777733131110400004640004767777373373333333337337312301401203007012121071243341253070100702317173537777747600250000000771353733373373373373737173121731353533131310076037177777773421713131201240007000067777773737337373737333312330020160500707010713031041371343134310505303173537737766704640400066121273735337373317137333313131373333353031771771002777773770001313101000000046146777777373337333333333327206676160120121021071217070250361343130700305352173717777576000006700041111353337333735337317373735303353131331377777770017777070110313131311101000476777777737377337373733367764747476764106161403031013004335170307071021734317353773776640047606000131271237337373131733737313131313337121035777737701677700016131313131000300006777777773737333733333376767656476747416010030317073701631433031713125052131635373777774000064000003011313533737333731373137337333537313131777733777740100000013131313000310000677777777773737373737276767767767676765601243400013010301433143431617006316171735377357776604000067053073133353337353737373737313533313313137777771777700000000001313111310160647777777777777737333337770746776777777760341212103701711600523131613037105317034377177377756700000006000161053371733333337331337313133353130013733137770600000000000012301316777777777777777777777777575652105274777677740250400010301271073516161343500612527173537357477764600076400007117373333717373537377337335353130017373707310040000000000000311130676777777777777777777775252000040705010677764705203000711635004301235317171253171717353717737373560000640404771331371713335333335333533533313121231131313000470000000060004003447777777777777777777772524040406170707061057776124100041271037125371521612534247373717377737477777744000007600135371333737331737333733313113131001137171057200674056000400067746777777777777777777777440442400004070707165207474030000035005030425231713713716171753777777777777777747640040007131311713537333317331717333717121021121200064004604600000005666777777777777777777775652560404004124143507175707074000430037133516135353071253714373777777777777777777746700000717135331313137171735373331513331101000040006500670067404204467777777777777777777777765646046527424470743707070706021402005030150243534373535734637777777777777777777777746000024373313513173537333333135133371012121000675004646560042777466777777777777777777777764564654746440407065254525257750000010133512335061350353731735777777777777777777777777774404400071313313113313171717133171707000464064460067006000047667777777777777777777777774776565646142400041525273535253774020000150215307073371717777777777777777777777777777777776767600000113537353353313131171060000007604700000040047444677777777777777777777777777777777777746440604061615067617057734161202335721607171737373777777777767677776767676677767774465600007117353371313313132006504640000006000000007766767777777777777777777777777777777777777774740402525637141747257700014115303171617177177777777777647777767677774747766776777464047776025335313171317750076467000000000666040666477777777777777777777777777777777777777777777404041653450772535777701202721617125373737377777777677777777777767676767777677677777464674001731313137004600000046004000007777647777777777773777777777777777777777766676567777777774065257274357707770205013171735205371777777777777777767465445465446506447677676777774646476775210476400004762000676744664677777777777737373733737377777777777720456446474676777777075257174717157750020017121735373737377777477777746476766767466746652704667677677777747647465467674206476740447464767777777777777777737373773737777777777720456444747665474777746165705253676777701012735273707777777777777777476777775777676774765644470047767767777774776766746465447464764765777717777777777777373773737337377777777774046646676765646464777707560725771517770207001735353567373777777777476777777664765656465644767474000767767777774777777777767672574567773777777777777777777373373737737377777777004654656767665646444677563570573472777750106173703733537777777777767777747654765647656065644646476444247677777777777777777177576727137777737777777777777773773773730707777777740076647676767664746404477562537473557777030300353571743773777777767777774764264424244406424740656446765647767777777777777167707717536537773777777777777737377274340577777777774006656767676764746442460656156743143777752505213733373353777777777777746466404402465427650424074240474765007767777777777016750770773753567777777777777777777414121437777777777000765676776767674644644040771635356777772010321471747374777777777777764670404720744067406470004656560464767407767777777756777360777753763577777777777777777616034103077777777740056767776676746465464464640775774357777417070521373317377377777777767464400004446700467400656706606474240767647777777777007757177777761742577777777777777765010121410777777777024667766777676776666464440460734357777770203030527374737177777777774760000464420044474646744642474577065064777427677777770757767774752577173737777777777776121216030301777777747567776776766766674400000000047577777774010141430117373777777777777464404600002466067067476464747466646566540677647777777652775775737377617756777377777773010104101050167777771676776767676677675000000000000077777772000252020343737173717777777746400474606444044040046440046046147416740670477527777770077737737057017727737777777777750306030252120177777647656777777777767664000000000000777777410010000140143777173737777776564020640407600000000006056424066706465724470677477777752477747573077077177017773777776100101011010520777771657677777742460000000000000000007775610000010100212073717735777777746406440060440474241200046460404744470724477465676477777007077773777107716776777777777710342125203021013777567767775402050004014000000000000061430020100202001000173733777777776400044246404604665424000004656476467656452742564777777774747777771710637777517737377773020105010141101257760776776020605224707421604200000000042014100214010000057735753777777747400240040604707466456000004656647647677656740770774777737777777737731777136743777737341052120302124210777756777040414524570617461670700040000010020310010010000233773771777776046074740044424464467601000004656465640477600700646777777477777777777703776537771717776121010150510110703770777740016724724256425641474700007001250100612030030041753773777777754604464600606406470440464000000647467042763476525756777770777777773373377733743173733753403430212030201057547760017605434165070520742434760400000030701014007000303771373777377660472000614040646464706072000000046746174147616476677777777777777777777777775737353175200300101001410102736370056760562506506076474257425700470010000125210300070473775375777775474444044644004044046440640000000037777776747477077477777777777777777773777372517377737500010217030216105756561614163416470616052435607424760670030107100210061031373737377777764600064000607400060076745676100000337777777777477477777777777737777337777777773617137737214210001010012121770047607407430434075250461643560704740042007000430061605375371777377740046706064464006746406046004200004777777765406747767777777777777777773721377353737753744001070120010000167043650743470463434424427074346165647301010301012040301337377177777777460044446446060474404006774761000710677777767677767757777777777777777775014777737527377700000012503021014352525270343434341643430745616434706574000250002010071434371737357377774470604650654042464240046464047100671077777747567476777777777777777777733133573573577773700000000104102034607470564742434060743465261653461656771210303010061021037177173657377376465624644644644004600424065246301277077777676565777777777777777777777737773173773771777560000002112150135616526160743434343461605652470743477701000000010071034037353717377777746564406760674240647407000464777040577777777476167777777777777777777777377777657375377737140000000000212461616507074340656146165770470475256775242101012061025031173673477737377706400676404604404060244052677765330777777776774776777777777777777777737777771335737736770606100000301005356461647006165216705256043063424077721014200004016112143717173437777777446004440604006000444424645667777731777777774076577777777777777777777733777776521617716165752561614161764253461605745275641674252565147077777521210121007212052373477357735377737164002404656444646460464644567777731377777774676777777777777777777777777777737537703353063773777777777756470343420204025250614052066340477743050240103001413050173435253537737777470404740640065646444040606476777713737777677477777777777777777777777377773712501705252573771617617435607444652547525000605256056140077777161211303040703043037357525277773777777646466440006646000600464650477777347776774747777777777777777777777777777773070372525247075271771342570442700056200605670524203616047777706134124050030301303435253347137171737375744000024454040040400044666077777777746776777777777777777777777777717777773070503121437735370377070374240642005470725052535654007777770135216113200414160521525257077173777757367764560406600740766400004506460677777676747777777777777777777777777377777771032506161435370357071470314040404200404024242400025747776120417136141212030130523347307077353737375737576600040464644442464076406574477777654777737777777777777777777777777777325052317063536177217302171634000404002104000500776567774116153212512300417012012157071707134735735727573744406400042000047402440656647777777727777771734777777777777777777777737012341420707253521771657061010400004040612570674657656161601205071614043121705214307030613531731733563773777747604740000046440604644746777777457371777735777777777777777777777015250123505371361171210303112521000000040442467477525252121125303003300352501211211707616563434735734143353775347564600240400604004246746777776377771735737777777777777777777777210270503607071725275346160703071300100000640507472420105025001617141000212161205230611003113531612527375371737736165644740664074644756357737616717373530777777777777777777771705251030340713521735324215130141024070210420170703010052021103161212300615214305301616534707343071371617136173617056577734765416567173635371771653734717371747777777777777771021030343435025252170530501632070212140305021017021050041201104216113434071120121030431003001310317070140617535353737037353435373777073717135275347377137343527077777777777777761525350343025435316172573061053071250210121003021103030210142131030603100016170143413034703424250313136341230370317124437253734353771473716735337047357135307134217537777774777302120352171302525312533070163010010304250121001421701000710300070113143043012170303430001300711214242510061535035617102517352535271243170711635720735234363537004730737737137750714170353070434316173525306107071241000121412121121030400030171034207104216121034130143424070125031311206112303703124253734353073525216171277170142537537153616173071777343046321033034307170713735252534010303000134252102001016107002103143003031530201012507103052000714036130070525053614341716105252531617343704352125217356072530703617100717173773352010507143530703024343431712125630503030000212110307212100012502125341403014303611212143043070124112532132120003310321213407171613071717061353535343314173531713037060703273070316030302100713571435353431617001430341071050500610010510300410341301231343000501201252103004036434350152516142505251525070243061707034370070343070347025252160707502431705347171404341716170343242703421743524343070303024212121210712030012030305251425316070341705214340724110121030301210003121212103005317130713537007135307135310437135313531241352130312120030121213071735071353170312100301010101001210101030301000001010121303130000121030121030030434300000000000000000000010500000000000094AD05FE")); - strs.Add(func2(1), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D20540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FF0CB0C9000B090900000A009009000000000909A09A900B09000A90A00000000FFFEFFFFFFFFFFFFFFFFFCB9CFCFEFAFFFFFFFFEDFFFEDEFFDEFEFCFFFFDADA00D900009009009000000000090A00090BC0000900900000000A00ACA0E0E0E0F0E9CA9000A9CB0C00009090E0000009090B0000D009009000000900009A000FFFFFFFFFFFFEFFFFFFFFFCADEBDBDFDFDFFFFFFFFFEFEDFFFEFFFFFFFEFCAF0C9A0A0D00009A0000000000000009090A000B009A9000090000900C0900900900FA90ADA00090B00B000000009000090000009009A9B009009A00000000C000BFFFFFFFFEFFFFFFFFFFFFCF9FBCBEFBFFEBFFFFFFFEFDFFFEFDFFCFFEFFF9BC0B00909000900009000000000000900000909009A0C0B00000B00009A00E0E0E0EFCADA0C90000CB009000009A9A09A000B0090090900D00A9090009090A0000FFFFFFFEFFFEFFFFFFFFFFF0F0FFDFEDADFDFFFFFFFFFEFEFDEFEFFCFDEFEC0F0C9AC00A00A09000000090000000090A900A00009090000A00000CA00C09009090F900DA009A9000DA00D0000009C090000090B000A9A9B090000000AC00000BFFEFFFFFFFFFFFFFFFFFEDA9DF0FF9FFFFFFF0FFFFFFFFFDFEFFDEFFEFDFF9A9A0090909009000900000000000090A9000909A9000A90D090000A9000B0E0CACA0FAE9A9CA000A99A90B00000090B000909000090090D00009A900009000009FFFFFFFFFFFFFEFFFFFFEDADEBCFDEFFDADADFFFFFFFFFFEFEFCBEFDEDBEFCAD0D0E00A000000900000000000009009009000000009000A000090000000009A900DF090CA9009090E90900B00090A9009000090B009A09A90909000090B0009FFFFFFFFFFFEFFFFFFFFFD09E9CFBFBF0FFFFFEFFDEFFFFFFFFDFFDFEBFEFDA90B0A90900A9009000000000000000000000090900090A909000A0000ACB00B0C0E0AF0F0BC09000009ADA9090000090F0000900909009909A9A0900000000000FFFEFFFFEFFFEFFEFFFFEA9E9FBFDEDFFFDFFFDFFFFFCFFFFFEFEFEDFCFDEFC000D0000900000000000000000000009009000A0090090000B00900009000C00A09C0FF0F0BCA0B0A00090F0A9A900090B0900900090000B0D090A900009A000BFFFFFFFFFFFFFFFFFFFFD0F9E9F0FBEF0FAFCBFEFFDFFFFFFFFFDFFAFFAF9EFBC0A9C0A00909000900000000009000000000900000000B0000000A000000B0C90A00F0B0F009C0009000B009C000B00AD000B0099A909A90B00990000009C00FFFFFFFEFFFEFFEFFFFFCA90F0FCFFDFDFFDFFFDFDBEFFFDFFFFFEFCFCFDFEFC00900A9000000A090000000000000000B000900900000900909AC90000A9000A0C09CF00F00DA0090000909F0B909C0099A09009A00000090909A0090009A09FFFFFFFFFFFFFFFDFFFEE99CF0FDBE9EFAFCBE9EFBEFFFDEBFDBFFFFFFF0FEDF0A90AD0009009090000000000000000090090000000000009A00900090000DA0900A0AFADADB009AC900000009000A9009AD00090090909BCB09C9900090009AFFFFFFFFFEFFFEFEFEFFDACB0FDADFFBDF9FFDFDFDFDFFFFFFEFFFFFEFCF0FBED0E9009C0000000000000000000000000000000900000000009A00000090B0C00E9C00FDA90E9AC9A0A90A90A9A909AD009B900AD0A90009090B0A90000090BDFFFFFFFFFFFFFFFFFFFC09AD0B0F0BEDAFE9EFAFBEBFDAFDFFFDBFFFFFFFFCFFE9009A0B00000090A90000000000000090090000000000090009B000000000B0000AD0FADEB9E9000D00090090D0B099A9A0F09009009090B09099000000009EFFFFFFFFFFEFFFFCFFC0F0DAFCF9FD9FDF9FF9FDFDFEFFFFEFDFEDFFFFEFCFFEDE9E09000090000090000000000000000000090090000000099C00900000F000090000FDBADCADA900A9000000B009CA9C099A00B0090A9E900B00A0009009FBFFFFFFFEFFFFEFEFFC0B09AD09ADEBEFE9EF0FCBEF9FBDFFFFFFFFFFFFFFFFEFF000900090000900000000000000000900900000009009009A0A9000000900000ACA0AFAEDABF9ADA900DA9C909E9A99A9C9A9990900900909909900000000BCFFFFFFFFFEFFFDFFCBC0F0DA9EDBFDF9FF9DFBFF9FEDFFEBDFFEDBFFFFFEFFFFEC09ACB00000000909000000000000000000900900000090009000009000A0000000D0FDBEDACFBCBCBA09A0A00909AC9BA99E0A9A90090B00BCA9000000009BFFFFFFFFFFFFFEFF00909E9CB9EDAFCF0FEBCF0FE9FBCFDFFBFFFFCFFFFFFFFFFFE09009000000A0000000000000000000000000000000009A0909000090900000000BFFE9FDBC9E9BC900909900B09B0D9A0999C00090909A0909000090090FFFFFFEFFFFEFFFFC90A900B0DADBDFBFFDBDB9FDBFCFFBFFEDFDBFFBFFFFFFFFFE900B0C009090900900000000000000009000000900000AD090A0009A000000909A09F9FFEBEBEBDADBAD0BCA09C0BCB0BC9B00A9090B0F0990B000000000B9FFFFFFFFFFFDEFCA0C9CAD0DADBEBEDADBEDAFCBFCBDBCFDFFEFFCFDFFFFFFFFED00009A9000000090000000000000000000000000000090000090900000F0900000DAFEADBFDBDF0FAD0A9090B0B0090B0BD0B990000090000900000090090FFFFFFFFEFFEFFFD09A0090B0F0FDF9FFEDBFDFBCBFFFFFAFFBFFFBFBFFFFFFFFFFE09000000000900000000000000000000000000000000900900000909000000A9A9AF9DADAFCBFBCBF9F0B0F090B9A9C90B90E909090B909B0900000000090BFFEFFFFFFFFEFE00909AD0BCBDAFE9FDBCBE9FFDADAFDF9FDFDFFCF9FFFFFFFFFC000090909000B009000000000000009000000900009A009A90000000B09E0900C90FEADADFBF0DBDAF0BC090F90000B0B0DB90B00090000090B0000000009FFFFFFFFFFEFFF090C0AC9ADBDAFDBFEBEFFDFF0FFFFDBFFEFFBFFFFEFFFFFFFFEB000000A0000000000000000000000000000000000B090000009009A9000000090A9F0DFAF0FE9EBEBDBE9B0B0BC090BD09A9A9009A90090B000000009009BFFFFFFEFFFFDFC000A9090F9EFBDBEDBFDF9FE9FFBDBEFFFDBFCFF9F9FFFFFFFFD000000090009090000000000000000000000000009C0000A909A0000009009A00A9CFEA0D0FDBFBC9CADBF090D0B00990B09B9E90090B009090900000000000FEFFFFFFFEFEF00090DAF0F9EDEDBFCFBFE9FFADFEFDFCBFFFFFFFEF9FFFFFFFE90000900000000090000000000000000000000090B000009000000B0F0A0000F0D0BFDFFAFAFEDBFBF9E9EF0BA9ADA0A9C9AD09A0900090000000000000009BDFFFFFFEFFFFE0900A909F0FBFBFDBFDEFFFFDFFBDFBFFFE9FDBDF9FEFFFFFFFFC090000090000000000000000000000000000000F00000909A9090090909AD000000FBEFDFFDBFE9E9A9B9BD09DB90D09B090B909009000B090900000090900FFFEFFFFFFFED000D0CBCBDADEDEFFFFF9FDAFF9FFEDF9FDFEFEFFFF9F9FFFFF9B00000000090090000000000000000000000000B090009000900009F0AC00000A0BCFCF0BEDAFF9F9ADF0FFA9AB00B09E9A9A9E90090900900000000000000FBEFFFFFFFEDF009009B0F0FDFBFBFCBDFFEFFDEFEDFBFFEFBF9FBDF0FFEFFFFFE00000000000000000000000000000000000009F000000009BCA900B00909A0AD0D09FA9EC9AF9EF0ADBAD0BDF9C9F0B09090999A900A09000009000000000909FFFFFFEFFEFC00B0E0F9FFAFDFDFFFFAFDBFFBDFBDFCF9FCFFDFBFFBDBFFFFFD9A0000B0000000900000000000000000000BCB0B000009A0090009E9E0000900A0A0FFCBFEDAF9BFDADBBF0B0BB099DA9F0BCB0D0009009090000000000090B0DFFFEFFFFFF000099F0F0FDFAFEBDFFDFFFCFFFFFEBFFFFBDEBCF9FCBDADFFFAD0000000000000000000000000000000000090D000090090B009F09090B00C090D09FEBFCBADBEF0BDADA9FDBC9FA0B90090099A909000A00000090000000009AFEDFFFFEFC09090E9F9FBEBDFFFFBFFFFFFBDE9FFDF0F0FFBDFBEFBFFDBFFFF0900000000000000000000000000000000B9A9A00090090900FA0BCA0000B0B0E0A0F0F0BEDFEF9BCADADFA9A9A9099E99B0B9A900009009000000000000009ADFFFFDEFFDA000F0BDAFCFDFFF9FFCFFE9FFFFFFF9EBFDFFADEBFDBCBCBE9EF09A00009C000000000000000000000000090C0900900A900B0F909000900D000C090DFACFEDAF9F9EBDB9A9BDBDBDB0B9A90990D0B09009000900000000000909ADEFEFFFEF009009F0F9FBFCBFEFFFF9FFF9FCF9EFFDAF0FDBFD0FDBDBD9F9FF009000A00000000000000000000000000B090E9009090B9C9A00E090C00A000B0CB0FDB0F0F0FBE9CBCF9EDA9A9ADBCB9ADA0B0909A9000900000900000000009BFDFFFFFFC009ACBDAFDEBFFDFBDBFFFDEFFBFF9FAFDFF0F9EBFBEFEFADADBE9000090000000000000000000000000009A090000090B0ABD090900B0A900F0CB0E9F0EDAF9E9E9BBCB9EBBDBDBDB09AD0999090090009000000000000000009A0FFFEFEF00000DBCBDFBFDF0FBDEFFFFBFFDEDFEFDFADADFE9FCBDBD9FBD0BD0B0000CB0000000000000000000000009C90A900A90BC9D00A000B0009C0B09AC090F0B9ADADBF0BCBBCB9DADA9A90BDA9B0A9A09A00900090000090000000909DBEFFFFDE090DB0FBFBEDEBFFFFFFDADFDFBFBFBDFADBFFADBCBDADBEF90BD009000900000000000000000000000009A000900999A90B0A090B9C90F00BC0AC0B0EFB0C09ADA9FDBFCB9EBB9BDBDB90B9099C900990090000000009000000000ADFEDFEF0000A9F0FCFDBDFDFDFBFFFFFBEFDFCFADFBC9ADADBCBF0F90FBCBE9AC000AC0000000000000000000000009A090E90A09E900900BCA9A00B0090090009FDBB0F09F0B0B9BCB9C9E9B0BCB9CBDA9B0900B00090000000000000000090A9FADFEF0090E9F9FAFFBEBEBFDFFFFFFDFEBFDFBCFFEDBDADBCBDAFD0F90909000090000000000000000000000009009090099E900F00909909C900000A9A9E90FBCDF0BE9BDBDADB9E9BBDADB909BB090900090909009000000090000009090FEDFED009ADBCBE9FDADFDFFFEFDBDEDBFDFCBFCBCBDADADB0F9E99AF0BDA00B009000000000000000000000000900900A9B00909B09ADA0E00A00D0B0D0C0000F09BA9F9BCBB0F0BE9BBCBF9B0F9AD90B009090000000000090000000000009E9EF9E000D9ADBDFDAFFFBF9FFBFFFFFFFAFBFCBDBDADADACBDADBCF99E0D090000A0000000000000000000000000B0009000B09A000000900000000C000B00A9FFAD9CB0F9ADBBDB9F0DBF9ADB0B90B99A9A00B09090090000009000000090B9E9EF009A9ADBCBEBFDBDEFFFFDFFFBFFDFDE9FCBE0F9E9DBCB9F0B0DA99A000000D00000000000000000000900900009A90900000090900909090B09A0000900F9FABBDB0F9AD0BCB9B09AF9A9BCBBCBC90900900000000000900000000000009E9CF009E9ADBD9E9FEBFDFFFFFFCFDAFBFFFAFDBDADBE9CBCB0F0BE9E9DA09000000000000000000000000000A9090000009000000A000A000A000009000090FF9FDFBE9BF9BF9B9E9FBD9BD9CB9090B090900090009000000000900000090B09EB009C90F0FEBDFBDFDBFFBFF9FFFFDFCBCF0F0F0F0DA9E9CB0D0909A09000009A000000000000000009000900000909000000909000909009000000090DADFAFFFADBDADBF0F9E9BADBBE9AB09F9B90B0009B009000000009000000000000DAD0D0A09ADBCBDFADFBEFFCFDEFFFF9FEBDF9F0F0F0DA9E90BC9ADA9E0900000000000000000000000000009A009A9000000000000000000000000900900B0BF9EBFFF0BDA9FBDB9AD9BCF9B99B0B09E9009000000009000000000000000909ADA00090F9ADBDADFAFDFFFFFFBFF9FEBFDBEFCBDAD0F0F09E90F090990F0900009000000000000000009009090000000000000900009000000009A090A9BDBFFBDF9FFF9FFBDBEBDBBCBB9F0F0DB9B090900909090000000000090000000000009E00090CBCBFFBDFBFBDBFFFFFFEFFDFADBCBCBCBA9E9E90F09E9E0B000000000000000000000000000000A0090090900000000090009000900009A90BCB9FFEBEFFB0FA9FAF9FBD0BF0FA9B9A9E99A9A90009A000900900000000000000090BC909AC9B0F9E9EBFDEFFFDFFDFFFFDEBDFEBDBCBCDCBC9EB0DA90900D0B009000000000000000000090090900009000000000000000000000A909090F0BFEFF9F9BF0FB9FFF9FBCBBF9F99F9E90B9E90900090009000000000000090000090AC000009A0F9E9FDFDBFDFFFFFFF9FDBFDFE9DACBCB0A90B0D0F009E09A90000000000000000000000900B0900900000000000000000909009090B0F0B09F9F9FBEFC9F90FB9BF0FB9F9E9BFA99F99090900900090000900000000000000000909000900D90F9FAFBEFFBFFFFFFFFFEFFAF9FEF9E90F9E9CA0B09E090000090000000000000000000000000A00090000900090090900000A90B009090DBFBEBFFDFBFEBFF9CFDBF9FADBFBCBDBA9ADB0B0B009000909000009000000000000000000009A0BDADBDFFDBFFFFFFFFFFFFFDFFE9F0F0FA0D0A9D0CB0900B00900000000000000000000000090909000009000000000000900900009ADA9A90F9F9EFA9EDBDB9EBBAF9ABDBE9DB9B0DB9A99C9090009000000090000000000000009090000A90D0BF0FBCBFDFFFFFFFDE9F9EF0FF0F0F0DE9AD0A9A0F9E90D000900000000000000000000900000000000000000000009000B00909E909C9AF9E9E9F9FFAFBEFDBDFDBFDBF9FBE9E9B0BDB09A900090A909090000000000000000000A00909C9AFC9FFDBFFFFFFFFFFFFFEFF9FDADAD0DA9AC9E9C9C90000A090000000000000000000000009A900009000009000909000090090B0090B0BF9E9ADAF00BDBF9BBEBFADBBDAB9F9B9E9DA90B090090009000000000000000000000090900000B0D9BE9AFFDFBFFFFDFFFF9F9EFAFDADA9A9C0B00B0A9A0BD090000900000000000000000009000009000900900900000009A090A9C0B0F0F90F0BDA0BF0FADFFDF9F9FBCBFDBE9E9B9A99F90B090A90009009000900000000000000000000090B0E9FFDBFFFFDFFFFFF9EFEF9CDADBCF0DA9C09E0D0C9C0A009A000000000000000000000000090000000000000000009009009CB090909AFB0F0F09F0B0FFBFBFEBFBDBF0BDBBDBC9F0B0B0D0B09009000900900000000090000009090009A9C9BDADBEDBFFFFFFFFFEF9F0FBBDAF09E0D0A9E09A0B0B09C90090000000000000000000000900000000009009000000A0900B90090B0BBD9CB0F09EF9ADB9FFCB9FF9EBDBDBEDB0BB099F0909090900009009000009000000000000000090009ADADBDFFFFFFFFFFFDF9F0FBCDAF09E0B0AD00900D0D0D00A0900000000000000000000090009000900000000000909090A900A9A9C9FDAFA9BCBE9F0F9FE9BFFF9EBDBBEBF9BF909F0B09A9A9000909000000000000000000000000900009F0F9FBEFBFFDFBFFF9FBEF0F9CBAD0DA0D0D00D0ADB0B0A0B0900009000000000000000000009000000009000909000000090E9090DA9A9AD09FCB9CBE9AF9FFF9AFF9FBDBDF0F0BEDA9BCB90990B90000909000900000009000000090000000090F0DBDF9FBFFDFFFED9FF0F0D0F0BCB0A0F0A900C0C90D0CA9C00000000000000000000000000000000000000000090B0090A9CB09ADBDAF00BCA9FB09FE9A9FFDBFE9E9FBB9F9B9BC9B9CB00900B090A0009000909000000000000090009A9AD0FBFAFFFFCFBFCBDBE90BCB9E9AC9C9C900D0E90B0A9A9090A90000000000000000000090090000000009000B009000900090B90BDA9A90BD0F9FFD0BE9ADEBDBEF9FBFBE9F0FCBC9A90B0A99C90900909000000000090000000009000900D0BFBCFDFE9FBFEDBFDAD9EDA9E09C90B0B0CB0B00B0C9C00A09000000000000000000000000000000000000090000000900B90B0CBC0BCBCBDAF9FFFB0BDBDB9EBFDBFADBDBC9B9B90B9CB99DA0B00009000000900000000000000000000009AD9ADBBF9FFFF9FBDEBDBE9A9C9DA9E0C0CB00C090C90A0F0D0E9009000000000000000000000000000000900009090900A90E9C9B0BDB9E9FEDFFFFFF00ADADBDBEBDF9FAFFBCBCBF90B90F09909090009000900009000900000000090009009AD9FCFEF9F9FFFFF9FF0DF9EBCBC90B09009A90E90AD0900A900B000000000000000000000900000000000090000000B000909A09F0ADF0F0BFDFFFFF0DBCBF0F99FBEF9F9F9BF9090F0B909A090B009A009000009000900000000000000009E9AF0F9F9FFFFFDFFFE9FB0FD0F09E9C9A0D000090E90A0909090C090000000000000000000000000000000000B000B0009DA9A99E9F9A0F9FDFFFFFFB0B0BF0FBEFADBDAFBCBE9A9EB909C9AD9A90090090000090000900000000000000909A90F9FBFBFFFFFFFFDF9FEDFF0BDBE09A0C9A0D0B009000DAC0CA0090000000000000000000900000000090900900900009A009C9E9A9EBDBAFFFFFFDFF00DADF0F9BDBFBF9FBD9BDB9DA90B0900909009009000000900000000000000900000D0F9E9FDFFFFFFFFFBFF9FBCBDEBC9F0D0BC09A00DA00F0009A90B0A0B0000000000000000000000000000000000000909090B09A9AD0BDADF9FFFFFFFF0A9FA9F0FCBDADBE9FBE9E9A99F090B9BC0B09A900909000009090000000000000090B0ADBFBFFFFFFFFFFDFFEDFFDBDEBCBDAD09E09C0090009A00000C90C000000000000000000000000000000009A090000A00909A9F0BBCBDAFFFDFFFFFF09F09E9E9BDAFBF9F0F9B9BDAF09A900099000900900000909000000000000000000009DBDFFFFFFFFFFFFFFF9F9FADBDDF0F9ADA90E9A90CB00C9ADA900090900000000000000009000000000090900000909090BC90F0F0D9FA9FBDBFFFFFB09E9E9A9BFAF9F9EDBFADADA999A9C90B9A09B009A0000900009000000000000009099FBFFFFFFFFFFFFFFFFDFFEFDFFEB0FDAD909E900CA90090000000A9A00000000000000000000000000090000009000A000B00ADA9E9ABE9FDFBEFDFFDF00BF0BDAC9F9FBFBBCBDB9B9CBC90B09000900909009000090900000000000000000EBFFFFFFFFFFFFFFFFFFFF9F9FADBDF9ADACF09ADA9009E0B090909C0090A00000000000000000000000000A90900909090D0909ADB0BDE9AFB9EDBFFFFF000BDA9FBCBEDBCFBF9AFCB0B9A909B0909090B009000090000900000000000000099F9FFFFFFFFFFFFFFFFFFFFFFDFFCBDE9F9B0F0909CBC090CBCA0E0900AD090000000000000900000000009000000000000B00BCB0F90BDBDADEB0E9FCBE0009ADADABDBBFB9F9FDB9F90BD0BC090F0009090A90000090B000000000000000BBFFFFFFFFFFFFFFFFDFFFDFCF9EBDBDADF0FCD9ADADA09BCA9009090A09000000000000000000000000000000009009090B0009090F00F9ADE9A90F9EBFEB009ADBDAD9FADF0F0FA9BCB0F90B909B09099A900900009000000000000000000BDFFFFFFFFFFFFFFFFFFFFFFBFBFDDADEDB0FDB0AD09AC9AC090CBC90009C00B000000000000000000000090900900000A00090900BCB0BB0F0B0F0F0FEFC0F0000A0BDBE9FFBF9F9FADBD90B090B0090B0090A9009000B09000000000000009BFFFFFFFFFFFFFFFFFFFFFFDFDFDAFF9FBCF0BCBD9AD0BC90BCA900A0F00A90000000000000000000000000000009009090B000A090B9C9CB0F0F09AB0FDBFE90BC900BDBE9FDAF0B9F0BBE99F0D090B0090909090000900090000000000009FFBFFFFFFFFFFFFFFFFFFFDFFFFCBD9FE9FBDF0FCBE9AD0BCB09D0F0D00900009000000000000009000009000000000009000909C0B0DAB0BCF0B0BC9CB0ADAB0C0B0A9E9E9FBFBDBDE9F9C9BE9B0B09090A90B09A900000900000000000009FBDFFFFFFFFFFFFFFFFFFFFFFFFDBFFEF9F0FA9F9BC90DA9CB0DA0A09A0BCA9CA00900000000000000000000900090009A0A900009009A9CBCB9CBC0B0B0FDADF00BC0DBCBFBDAF9EB0B9B0BF09900909009900909000090900000000000009BFFFFFFFFFFFFFFFFFFFFFFDFF9EBFC9F9EDF09FCBC9ADA9CB0DA9E99E0D009009CA0000000000000000009000000000900090000B00BCBCB0F9EA90B0E9E9A9AF0000B00B0DAFDFF9FDBE9F90BCA99A9C9A009009009000000900000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9FF0F9A9DE09ADADBC9F0DAD09CA09ADACB00090000000000000000000000009000009000090009090F090E990F0F9B0F0F0F009C0BC9A9FBFBFFBE9F0BF9B99A0D0B0909A900B00900900000000000009BDBFFFFFFFFFFFFFFFFFFFFFFF0FF9E9F9EDDAB9E90B90E9A0B09ADA9C9E9090C9A00000000000000000000000000000B00A900009000B0B0E9BCACA9F0E0F0B0BB000A90A09E9CBDF0F9F9BD0F0DAD90B0900090900900000090000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9EBF0F9ABD0F0F0C0F9CBD0DADA9E9A9CBCB9AD0DA90000000000000009000000009009000900A09A0D0BD0A9DB9E0B9F0BC90F0A09CB0DA9EBFAFBDBFAF0B09A9B0B09A9090900900000090000000000BDBFFFFFFFFFFFFFFFFFFFFFFFFFDBDAD9C9090D0F009E9B90AD0FADA9C9A9CA9000C0B0000000000000000000000090000000000000090090BC0A9DA0E9F9E00B0BEFC900BC0BCB9F9F9FBCBDBDB9F9090909C90000B0090009000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9A99A090909F090CAD9AF09E9E9ADA09E9E9A9009E900000000000000009000009009009000900090BCB0D0A9F9ADAD0F0F09B0AC90B0DA0DAF9F0FBCBCBCB0F9E9ADA909A9009009000090000000009DBDFFFFFFFFFFFFFFFDFFFFFFFFFDBE9C90D9D09A0009E9B0AD09E99E9E90DBC9A9C9E9E00A000000000000000000000000000000000090A009CB09DA0FBF00B0B0F0D00B00F0A9FA9FAFBF9FBF9F9F0B909090BC9090090000000000000009FBFFFFFFFFFFFFFFFDBFFFFFFFFD9FC9F9BDA90BC9D09000C9C0F09E9F09E9A0BCBCA9009090D00000000000900000009009000000900000909A009A0BDBCA9E09E900A09FCB0099E9CBF9FDADBDB0B0B9E90B0909000090000000000000000BBFFFFFFFFFFFFFF9FBFFFFFFFDBDFF9F90D090D9090000909A9B0BCB0F0F0F0D0909DACBCBCA0000000000000000000000000900900009A900E90DA0F9E9E9F09E90F0D000B0F00A9BF9FFAFFBDAF9F9CB9BD09A909A9009090000900000009DFDFFFFFFFFFFFFFFFFDFBFFFDBDB99C9E909090090909000090C9CBDF0F9E90BCADA009000909C00000000000000000000900000000900000900B0999E9E9E0DA9A000B0009E9E90E9FADBF9FABDBE9A9CB0B9090B090900000000000000000BFBFFFFFFFFFFFFFF9FAFDFFDBD0D009990F9CBBC9E0909090090A90ADBCBDBE90D0DAD0F0F0A0B00000000000000000090000000000009090A909A0E90F0B9A0F0C900DA0009E9AC9A9FBFDFBDFADBDF9B0F9CB090900009000000000000009BDFFFFFFFFFFFFFFFFFDBFF90009A9FBEFFFEF9CBE0900000000090F9ADBCBC9E9A9A90B0909D000000000000000000900009000009000000090BC909ADAD0E9C090000A9A00B0BDB0BCBDEBBFFBDBFA9B099AB090DA9090000000000000000FFFFFFFFFFFFFFFFFDADAD090099BF0FFFFFFF9AFF09E0F00000000090F9ADA9A9C9E9CB0CBC0A0F000000000000000000000009000009009090F0B0DAD0F0E90B0E0000F00009ADADE9BFBFFDF9EBDB9F0F0BD9DA9090009090000000000009BDBFFFFFFFFFFFFFFFFBDA900000FDFBFDBFEBC9E9E0900000900000ADAFDBDCD0B09A9CA90A9C90000000000000000000900000090000000DA090DA09A9009A0C9000009FA90C09A9BC0FF9FAFF9FADFB9BD0BA99A909900000000000000000BFFDFFFFFFFFFFFFFF9FF9CAD0090B0DAD9BD0B09090090090000090909ADAABCBCBC9E9DAD0A9E9A0000000000000000000900000090090B090A90909DA9E0D00000000E900A9AC9E0BF9FBFFDBFFDBADE90B9DBC90B0A9000000000000000BDBFFFFFFFFFFFFFFFDFF9E99909090999000090900090009000000000BC9ADD9AD009A90A9A9C900D000000000000000000000000000000A000F09ACB0A0C900A0009009B0A90009A0BF9EFFCFBFF0BD9FB9BD0B0B9090900900000000000009FFFBFFFFFFFFFFFFFBF0FFFFFF99090F09BD99C900900990009A90DAD00BDB0AD0BDBC9E9C9E0A0F0A00000000000000900000090000009090909ADB090DB0B0C9000C9EF90A9ADAD000FB9FBDF9FFFAF9BCB0BDBDA9E909000000000000009B9FDFFFFFFFFFFFFFFDFFBDBFFFFFDF99BC909A909D0BC0C90BC0DA090BD0BCBD0F000A909A099C909000000000000000000000000000B0000A0BCB0000B0C0090000B0F00FA009A9AC909EFFFBFE9FBDBCB9DB0B9A90900B000000000000000FFBFFFFFFFFFFFFFFFF9FFADFFFFFFFFFDBDBC9FDA9C9B9ADADB00D0E00AD0BCB09F9C9E9E9E0A9AC0F0000000000000000000900009009090909ADBC90C9A9CA0A90CBCBF00B0A00A9A00B9FADFBFBDBFBDA9AD9ADB9A9090900000000000009BFFBFFFFFFFFFFFFFFFF9FFBFFFFFFFFFFFDFF0BDFBDE0D0900DA0B09F9ADCB0F000B0909099C0D0B0000000000000000090000000000000009A9A090A9AD0B090CA90A090B000B0D000B0FFFFBDBCBF9CB9F99ADBD090D0000000000000009FFDFFFFFFFFFFFDBFDBF9FDBDFFFFFDFFDFFFB09FCBCB099E9E9A9AD0F00DBB0D09E90D0F0F0E0B0B0C000000000000000000000009009009A9E9C909A9000BC0CA0F0E90FA00A90B0BC00DBFF9EFFFF0FBDA9ADB9B0F909A909000000000009BFFFDFFFFFFFFFFFFFFDEBFFFFFFFFFFFFBFFC9E9BDBC9E0900D0D09A9DBAC0F9E99E9A090090900C90B00000000900000000000000000000909ABCB0C00F09A9ADFAF00B0DA90A00B0B0A00BFF9F9FBFDA9F99ADADB09A900000000000000009FBFBFFFFFFFFFFFFDBF9F0F9FDFFFFFFFDFFFF9E9F0B090A9B0B0F0DA0D9BD0A9E909CB0F0CB0F09AD0000000000000090000000000900900BC90909A99000D0AFFDFBC0FA90A90B0DAD09ADEBFFEBDFBFF0BC9B9BBDA909090000000000009FDFFFFFFFFFFFFFDFBFDF9DBFFFFFFFFFFFFDBD09F0D09E9C0C90D0B0DB0F0BFD090F090D09A9C09E00BC0000009A0000000000000000000090B0F09E90A09A0BDFFFECB0B00A00A00B0BCA09BDE9BDFBFF9BDBB0DBD0909A900000000000009BFBDFFFDFFFFFFFFFFDFADBFCBFFFFFFFFFFBFCBE909E0000B9AD0B0DB0F09C90B0F00BCB0A9C0B009F00090009000000000000900900090BCBDA90F09AC90CBCFFFEDBCACB00B09A9AF0F0F0FBFFFA9E9FFEB0DBA9BF9E9009090000000000BDFFFFFFFFFFFFFFFDBFBDBC9BDBFDFFFFDFFFDBD9E9009090000B0D0BCB9CBBCBC90BD090C90B00DA0009C0090A000000000000000009000090A9CB0BC0BCB00F0FDFACB0BCB00A00090B0F0F0F9FEDBFFBF9FB0DBCB09909A00000000000000BDBFFBFFFFFFFFFFFFDF9FBC9BDFFFFFFBFDFBFF99E9000090C90B0D09CB9C9BDBCBCADA9BC0D0B09E90A909E09C00009000000000000090B0990BC9CBC0BCB0BF0E9F9E0EB00A0A9A0A0F09AF0FBDBCB0F9FBDBB99FFB0B0990900000000009BFFFDFFFFFFFFFFFFFFFF9DB9CB9FBDFD09B9FDB0F9000000090009A0F90F9E9E99CB909C09B0090C90E90B00900B000000000000000000009E9E90B009ADA9E00BCA0A09900B0900009A9A009FADAFF9FFFFDAD0FFB90D0900000000000000BDBDBFFFFFFFFFFFFFFDBDBE9CBDFFFFF99F9FDB0FD0E99A909A90DBC990F9E9CB9EBD0CB0B0C0F0A9A09000CB09F000000000000009090909E9A90B0CBCBCBCB0B0B0F09AFB000A0A0A09AC9E09FFFDBEDAFBFFBF9A9FB9AD0B0909000000009BFFFFFFFFFFFFFFFFFFFFDF9B0909FFFFFFFFFFDBFBDAC90F0DA0009F0F0F9FBDE9D0B9C9CB090C9009CADA90E009000000000000000000B09A9EBCBE9ADACB0A0CA00A000FA9009090A09A09A09AFADBBFDFFBDBF9F9E909009000000000009DBDBDFFFFFFFFFFFFFFFFBDFDF9F9FFFFFFFFFFFDADB9AC90B0D09A90BDBCBC9ADA9FCB9A9CB0B009E090090909E0F000000000000000900BC909CBCBCF0B0E9CB09A90B0F00A0A0A0A90A0B0090F9FFFDFBFBDFE9FBE9F9A900090000000000BFFFFFFFFFFFFFFFFDFFFDFBF0F0F9FFFFFFFFFDFFFCD99E9CB009C9E9ADBDBFDBDBA9C0DB09C09E090A90CA09A09009000000009000900909ADA900FFACF0B0A00A00A0090B00900900A090ADAF0FBCBFAFFFFBDBDBDB90909A900000000099F9FBFFFFFFFFFFFFFFFDFFBFDF9F9FFFFFFFFFFFFDB9B0E9CB00B09E9FDADAD0BCBC9DBDB0CB0B090B0D0A909E9D0F9E000000000090009A9ADA9ACBDADF0B0F0B0BCBCB0FA0A0A0A0A090A90B09ADBFFDFFF9FFBFAFBF0B0900090900000009BFDFFFFFFFFFFFFFFFFFBFDFBFFDBFFFDFFFFFFFFFEDE99AD0C90DA9DA9FBDBFDF9FEBCBC9BC9CA9C000D009090A90000000000000000B0D09A9C0BDADA0FCA00E9E9E9EA0F909009000A00A00A900CBFBF9FF0FFF9FDBFDBC9900000000000ADBFFFFFFFFFFFFFFFFFFDFFFDFBFDBDFFFFFFFFFDFDBDE09A9009ADA9F0DAD0B0F099DB0F0CB0900BCB0A9CA00B0F090F000000000090009AD9ABDAFCADA0BDBB0F0FAFDFF0A0A0A0A9A09A09A9E0B0BCFFFFBFBFDFBBF9B09A09090000000099FDBFFFFFFFFFFFFFFFFFFFDFFDFFFFFFFFFFFFFFFBDA9DAC0B0BC90F0FBDBFDF9FFE9E90F90DADA090900A9C90D0BCB000000000900090B0BED0BF00900F0A0CB0F0D0EAB00B09009000A09A000900FFFBFFFFDFBF9EDBCB909000900000009FBFFFFFFFFFFFFFFFFFFFFDBFFFFBFFFFFFFFFFFFFDE9DA099C9CBBFF9E9DADABCB090F9F9ADBC909CAC00900009AD00090000000009A0B09F9AFC0D0EBDA9ADBACBEAFBDCB00A0A0A0A090A0B0B0E900FFF9FFBFFBFBBF9AD09090000000009BFFFFFFFFFFFFFFFFFFDFFFFFBDFFFFFFFFFFFFFFFFBDAD9E00B09C90F9EBDBFDBDFFF9E9AD909ADA099A0090B0000BDA00000090000900FADAD0B0A90C0F09A0DB09000ABCB09009009A00900B0B0EB09AFFFFFBFDFDFBDB9A9A0909000000099FFFFFFFFFFFFFFFDFFFFFFDFFFDFFFFFFFFFFFFDFCBDA09B9CBCBF9E9DADF0FDA9DAF9EDAE9E90DA0C900000909009C900000000900909FADAC0090B0B0F09A00E0BC909A00A0A0A0A00A0A9A00B00CADFBFFDF9FBF9ADBC99090000000009BFFFFFFFFFFFFFFFFFFBFDBDFF9FFFFFFFFFFFFFFFFBDADBC0CB0B09E9EBDB0F9ADFAD9E9BD9E9ADAD0B00000000009A9A0000000000B0DB09A9A90CAC0F00BC9AD0B0A0AE90A0B090B09A909A09ADADA09BDFBFBFBF0BFFB90A900909000009CBFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFFFFFFDFCBC9009B0D0DE9F9DBCFDADFA9DAF9E9E9AD09A90C00000900909C0000000090909ABCBC000A090B00B00A90B009A99E09000A00A00A0A0B0B0A9000EBFFFFDA9F99B0F99090000000009BDBFFFFFFFFFFFFFFFFFFFDFBFDFFFFFFFFFFFFFFFFF90F0F0C9ADB9E0FEDB0BDA9DEBD0F9E9ADABC9E9A9000000000A9E00000000000F9CB0BC00D00009AC9ADAC0F0E00A9A0A900B09A9009A0A0B0E9090DBFDBFF9BF0DB9E9DA90900000009BDFFFFFFFFFFFFFFFFFFFFFDFFFDBDFFFFFFFFFFF9EFF090B0D0ACBDB9BEFDAFDA99EBDADBDE9DA9E9C000000009090909000000090B0ABC0009A000ACA0B09A9A9A90B0DA090A0A00A00EB0CB9CA90A000BFFBFF9E90BB9E99A9000090000909FBFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFF90F0D09A9DBC9EFC90BD0BDE99CADACB9E9CB09A900000090000BC000009090009D0B009A0090090900E9EDAC0AC0A90A00090A09A900B00A9CA0900BCBDBFFBDB90DB9A090090000900BDBFFFFFFFFFFFFFFFDFFFFDFFFDFFFFFFFFFFFFFDE9CF09A0A9DACBAD09BFECBDA9ACBF9BDBCBCBC9E9C000000000A9C9A0000000A9B0A00CB0C900C9A0A0A9A9A09A90BDA00A9A0A9A00A0B09A9A09A0909FFFFBF9AD0B90F99090090000900B9FFFFFFFFFFFFFFFFFF0FAFDBEBDFDFFFFFFFFFFFFB0D00D9CADBCDADAC099BC9EDB9CBCBCBCB09E9A000000000909A0C0000009000C9A900000A9A0009090DAC9E0A00AD0B0000000B09E0EADA9A09A0000BDADFF9B909B9ADB090009000990F9BFFFFFFFFFFFBDBE9FDBCBDDFAFBFDFFFFFFFDBCDB0B0A0B009A9DADBCAC0A900FA9CBCBDADFA9C9E9000009000C9B00000000090B0C0BC0B0C09A0A0A0B09A0090B0F0A00B0B0B00EA0B09A0E90ADADA9AFFBFBE9E9A9C9B0900900000009B9FFFFFFFFFFDFDFF9F0BC90A90D9EDBFFFFFFFFFFBC00D090C9E0CA900909090B90DA9DBC9F09CBA900000000090B0C900000009A900B000900B0E0900090A9CB0A0000B00A000000A909ACA9A90A9A900CBDBFDF9990909BC9A9000000099F0DBFDFFFFFFFFFBF0FCBD0BC90F9ADBFFFFFFFFFCBC9090AC0B09099C0BCBCAC0C0CB9EBCBAC9EBC9CA000090AD0A9CB00000090000CB09CB00F009A0A9A0AD0A0BC90AF0B090B0A0B0A0E0B0E9A99E9ACB00BDFAFFA9B0B09B909B0909000099A9BFFFFFFFF9FDFF9BDAD09A90090F9FFFFFFFFFDAC0A09090009E0AD00090B090B0E9CB0DBAD09E9C900000909CB00B900000909A90CA09E9ADA09000909A9AD00A90BC00A00A90090A90E90A0EB0F0BCBC9ADBDBDAD09CB0BC0900000909A9DBCBFDBFFFBFFBCBC009000909ADB0F9FFFFFFFDF9900D0BC9CB09000090000000090B09E0D0BCB0B00000000A0B0F0C000000000DA9BDA0000A0A0A0A00A900A900A0CB0A09A00A0A09A09AD0B00A0B0B0B0BFFBFF99B0909DB900900000909A9BDBFFDBFDF0F0909E0A9C0B0D09DBFBFFFFFFFACA090A00B00DAD0B00000000090009E9B0F0BCBCB0000009C90D00B000009A09A9CA09CBE909009090B00AD0E0BC9B0B00A09A9009A0BE0ABC9A9F0F0F0D0BDBDBCB09B09A9A090900909B99BF9FBDA9DB0909E0000D009C90ADB0FDFFFFFDAD909E090900F0000C00C0090000090F090E90D0F0C000009A00DA90900000009A9CB0F0B0000A0A0A0A00A90A9A00AF009A9A00A0A00000BC0AAD0A9AA0B0F0BFBFB9F0090909B000000009AD09EBDBDA0090FFF00C0000A009009FBFFFFFFFFA000900C0090BC000000000000000009E09EB0F09A00000009A90000000009009EBC90F0A9A00090000A90EB0009E90FA0009A0090A9A000B09A0BCBD9BCB0F9E9FF9B90B09F00F090900909B9999EBD90009BFFE0000AC9E009009F9FFFFFFDFDA009A90000EF0A00000000000009A09F09CB0F0D00000090C0F00F0000000BC90BF0AD0000B0A0B090A900E9A0A0F00B0A00B0A00009A00E0CB0B0AACB0BCBFBF9EBF9090099090000009090BCB9FBE900009C09E0000009009BE9FFFFFFFF09090C000B09000C0000000000009A9CA0BCB0CBCA000000009A0090000090909AFC0E9A0A0B000000A00A0B00090009A0A09A000B00A0090B0B0A0CB990DADBDBFFBD90F099A009A909090B0BDB09FF9D0B0000000000009000BC9FFBFFFFF0F0C00B0090000000000000009009C0CB09DA9CB09000000009A0900900000009AFCB090009000A9A0A09A0900B0A0BFA909A009A00A900A0A0CA00B00EABADBAFDBF9FA9090009A090000090D90BDB9FFA90FF0000000090009F9BF9FFFFFFFF0B0B009C009E900000000000000A9A9CBCACA9CAC0000000009C090A000090B0F9000A0A0A0A000909A000A0A000009E0A09A0A0B00A09009A90F00B090CB09DBBFFF9FB09B090900B090909A99090B9FDF909E9C00090090000FD0F9FFFFFDFE9C00909A0000F09000090900A90C9A90B99CB90B000000000B0000900000090AF00C90900909A0A0A0A9A0090A9A0F0B00A009000B00A0A000A00A00A9A9AFADFF9FBF9F09000090090000B90F9F09FFBEDA909A909000009BDBEBFFFFFDFEBD0B09E0A9C09000E09E000009C0E9AC0F0CABCAD00000000000DAD900000900BD000A0A0A9A0A0000090009A0A00000B00A09A0A0B00A00900B00B09A9A9AD09FFBFFFDB09090900090A9099090B0B9F9F9BFDAD00AC0909BADBCBDF9F9FFFBD0BC0090D090000909009A909E9A90D9B0CB9C09A000000000009A9E00009A0BC0000909A9000009A9A0A00A00090A0F0A09A09A9A0A909A0A00B00A0A00E90B0BFF9FBFFB90B000900990000B099D90BFFFDEBFBFF99BCB0D9E9F9BCBFFFBFCFAD0F0000A0F0BC00A900CADA90D0F0AC0BCA9F0C0000000000009F0000000D09A09A0A000A0A9A000000A900B0A000AD0A00A000F0CAA0009A00A0909A90BE9F9FFFFFBDFA909900000A99909B0B0B99B9FBDF9F9FEF0BDA9E90BC9BDADFF9F9DA90F009000009A9CADB9CBCAD0B0D9AD09E00B00000000000000000000900BC0009A9A0B09000A0A0A90A00000A009A90B09A9A0BA9CBA9A0A90BCA00A009AB0FFBF9FFBD9B009090090A090D099C0BDFBDBDE9E9909009009F09E9ADBFCFFBE9F090F0090000009000E9E9DAF0F0AD0BC9DAC000000000000000000000A90B00CA00CB00AE0B090D00A09A0B009AF0A000A00ADAD0A000009CA0A09A9A9EBC9FBDFFFBF0BC9B00009099909A9B09BDA99CB09A9000009009A09F9BDFBDBFBC9FCBEF090009000000909009A09C9AD0BCB0A0900000000000000000009090BC00B0B0B0CA90900A0A0A90A00000A0AD0A0A0A90A0AE9A9A9A0A909A0000A90BBEFFBFBDFF9B909000000BC90990B9099EB90B09CBC9CBC9E9DBDADF0BDFFFDFE9BD99CBCB00090090A000B0D0F0BCBC0BC0DA000000000000900000000B0F00CB0C0A00B0A0A0A0B0BC0AC9A0A0009AB09090A0909A0CA009A0A0A9E0B09AF0DBFFFFFBFFDAD0B90000909A9A99CB9AD9CBC9CB09A990BF9A9ADB0FFDAFDAF9FCBEFADADCB0F0DA09C900C9A90F0F0BD0B00D00000000000000090009009AD0A0B0B0F00E90DA90000B00A00C9ADABC0A0A0A9A0A00B09A0A0F0BC00B0AC00BA9FBFDBDFBF9B90D090000B909CB9099BFB9B090F9C9AFDAFDFF9FF9EBFDBFDFBBDBDFBDBBDF0FADBE0E9F0ADFE9F0F0AD0DA0000000000000000000900F0F0AD0A00A00B0A0A0ACB0E0A90B0B00A0F0A900B000B00B0AA0F09000A0B0C0B0F09FFDFBFFBFDF0A9A0000099C09B90B0FADBCF0BF9E9BFDBF9F9BCF9F9F9BDFF0FCFDE9DEFCF0FAD9E9F9BCBDF09F0F09DA0B00000000000000000000009090000A90B09A009A090B0A9A9CA0A00A900B00A00A9A0A00A0900A0A9A9A0A9A0A0BE9FAFFDBCBFBD909909A009B900BD9999BDB9D99F9F0DBFDFBCFF9EFFDEFF0FFDBFBFEBF9F9F9DEBDF0FCBE90FE0F0BCAD0C0000000000000000000090ADAD00B0CA0CA09A000A0000000A0900B0CAF0B00B00A090B09A0AB000A00900A900909A9FBFBFBF9EBF0BC909000099B0B0B0D9BDABCB0F9B0F9E9FBDBF9F0F9DBF9FBCFDBDF0FEDAF0DEBCF9FDFFF9F9E9E9B0B000000000000000000000A90B000A0B09A90A00A900A00B0A09ACB0CA90BE00A0A90B0A0A00B000B000A0A00A0A0A0DADFFFDF9FFDBD09A009A99AC0999DB0BCBD9B9F9C9F9FBDBDBCBF9FBFADFADEBDADADFDBFDBFB9DBFCBE9E9E9E9E9C0D000000000000000000009009AF09AD000A00A9A900A909A0090A0A00B00AD09A0900A0A9A90B009A000B0090B009A09A9BFBDBABDBBF9A9090099E99BDA9A9099B0BCBCB9BF9E9FAFDBFCBDAD9F9DFBDBFFFBFBEDBCFCFEFCBE9F9E9E9E9CA9A0000000000000000000000DAD00E00B0A90A90CA0A0A0A00A0A0090A0A90BA000A0B09A000A00A000A0000A000A090A0BC9FFFFDBFDEBDB0090009A9099F9B09E9F99BF9E90F9BDDB9E9BCBDAF9EBC9FCBDBDEDFADBDBF9DBFDADE9F0F9CB9C00000000000000000000009A90F009A000A00A0B0009000A9000B0A9090A0CBA90000A09A0B0B09A09000A00A090A00090BCBFF9E9BF9FBFF909A099F9A9A9D09090F090B9F9BCFB9FF9FDBDBDAF9FBEB9FEDBFBDFFEBCFEBCBDFBDADBCBACA90000000000000000000000A9E9E9AC9A900B0000A9A0A9000A90000A0A000BC9A0A9000A09A00A000A0A900900A000B00A09BDBFFFDBFBDBDAD09000B0DB9FB9A9099BDBD09ADB9EF0BDBADADF9DADF9FEF9FCFDFADBDBDBDFBE9EADBCBC99C00000000000000000000090D09A000B000A000B0A000090A9A00A9A00009A0F0A0000A0A90A00B00A00000A0A0B00B000B099EFFFBDABFDAFB99A90099FB0DB0090B0F09A9BBDB9F9BDBCBDF9F0BFFF9EDF9EFBFAFDFDEDAFE9EDBDDBCBC9E0A00000000000000000000000A0BC9CB00A0000A0090A9A0A0000A00009A0A009B00B00090A90B00A90B0A00000000000A000A09A9FFBFCBFF0FFADA99A09DBA9F900099F9DAD09E9E9CBDBDA9E9FF0F0FFBFF9FDFDBFAFBFDBDF9EDABCBC9A9C0000000000000000000000909F0BA00A09A9A09A0A000900B0A090A0A000000E9A000A0000A00A90A00090A090A0A0A09A09000DBFDFBFDBDF9FDBDAD9E0BDDB9F9900B0B99B9F99BF9BCB9F9BDADBDF9FCBFFBEBFCFDFDAFCBEF9FDE9E9EDA909000000000000000000000A09FC0B00A000000090A0A0A0009A00900A0B0A0BF0B0A00A0000B0A09A0A0000A0090090000A0B9A0BFFFFBFFBE9FFADAB990BA9EB0B0909DAF0B0FBC9DA9BCBCFBDBCBBCFBDE9FDFDBDBCBF9FDDBE9E9F9E9AC0A000000000000000000000909E90BCA900A0A0A0A0090000A0000A0A9000000E000090090A9A0009A0900A0000A00A0A0A00900C9FFBDBCBFFDBFBDBD09E9BDFB9D090B9A999CB909BA9FCBDBBCBCFBCFBDFBFCBFAFFEFFCFFEBE9F9F0E9AD0D000000000000000000909AC9EBCA00000A900900000A00B0000A090000B0A9AB9A0A0A0A00000B0A0A0A00B0A00000000900A0B000FFFFFFBFFF0FBCBDB9E9B9F9A909CBD9E9BDA9E9D0B9F9EDBDBFDFBDAFCFBDFF9F9F9F0F9FDEFADF9EDA0A90000000000000000000090A900C0B0B00000A000B0000000A09A0A9A000000CB09000000A0B00009000900009A0B00B00A09009A90BFBDBDBFFFDF9ABCB9E9E9F9E9A90BA909AD99A9F0F0F9BCBDAF9EFDBFDEBDCFEF0FFF9E9F9CFADA9ED90C00000000000000000000090BC0B0000A00A000A0000A00A900000000B00A00BCA0A090A00000A0B0A9A0A00000000000A00A09AC0BDFFFEBDADBFAFDF9F0F9FBCB9099BD9F0990BE9F0BD9BCBDBE9FEBDAFDBFDFBF9FFDADEFF0FF9FADE9ACB00900000000000000909A00BCA000A0A09A00A0900A0900000A0A9A0A00A900DA9000A09009A09000000000A0A00A0A0009000A0900BF9FBDBFBFFFDA99A9B0F9F9E90BCBE90F0BC990BD0BE9F0F9FDBDFF9FE9FAFDFCFADFBD0FF0F0DF0BC900000000000000000000009DA9009A9090A090000A0000A0A0A000009000000AB0A0A000A0A00A0A0A9A0A9009000900B0A0A9009AD00FFFFFCBDBDFBFEFDADB0FBF9AC9B99A99099A0F90BD9E9F9EF0FF0FE9FEDFDAFBDF0FCBFA9FCBF0BCB000000000000000009009C90AD0CA00A0A0000A9A0000A00000090A0A0A9A0A00CF090B0000000009000090A0A00A0A00000000A0000A90BDBFF9EBBCF9FBFDADB9DAF99ADAD9A09E9990BD0ADB9CF9BF0FF9FF9FBEFDFCBFF9FCFDE9FCBCDAC9E90000000000000000A00A90A909E9000B0A00000A090A9A0B0A090000009000B00A000A900A9A0A0B0A000000A9000B0A9A0009A9AD00BFF9FF9FDBFFF0FBDBCBBDBE909B9AD0B9A0C900B9ADAB9EDFF9CF0FEFDBDADBFCBCBF9EBEDBDBAD9A0000000000009000009009CBC0AA0A0B00090A0A090A000000000A0B0A0A0A0ACB0000A00A00000000000A90A000A9A000009A00000009E9FBEBFCBF0F9FDADAFBCBF990F9E90909C9B0E9D0DB9CFB0F9EFBFB9DBEFFBFCBDFF9EFD9F0E0D0AC90090000000000900900B0B09AC909A00A00A90D0A0009A0B0A9A0A009A00000BCA9A09000B000A90A0B000009A0000A0A9A00A0A9A9C09BDFDF9FA9FAFBFFBDBDBD0FA90B99F0B0000990A9B0FB0DF0FBDCFCFADF9EDBFFEBCFBDAF0F9DAC9000000000009000090A09C0DAC90A0A0F00B00A0A00A0A00000000909A000B0B0B00000A0A000A90A000000A00009A0909000A090000A900EBFBFFBDB9DBCBDFADAFB9FDAF9E900DB09000900C90DB0BF0FBF9BDFA9F9FCBDDF9EDBDADACB9B0F000000000000900090CA9A09A0D0BC00A00A90B0A9090A9A0B0A0A0A0A9A0000CB0A0000900A00000B0A0B00A0A000A0A0A900A0A0900A09CBFDADFCFBC9FAFDBF9FF0BC9A9A9F0000A90009B0DADBC9F9CBCFADFDEFAFDEBFEDBCF9E9F0C00009000000000000B00090009E0CA00A9A90A0A0A00E0A00000009000090000A0AB0000A000A9000A9A000000900000A0009000B0090A0A900BFFFBFBFA99EBDBFE9FE9BFDBDAD90009090009B00B0909EBCFADBDADAF9F9EBDADBEDBCBD0A9090000000000909A900A90A9DA90B00B0000A09009CB009A0A0B0A0A0B0A0A0B090CB00009A0000A900000B0A0A000B000B0A0A0000A00900F909FFFDFBDEF9CBCBDF9BFDB9EB900A9000090000D090CBC9CB9DBCBDBD0F0F9EFDEF9F0F0AC9CA09000000900A000009C09C0A9E00B00A9A090A0A0A09A0009000900000009000A0BC0A000000A00A0A0B0009000A000B00000900A000A09A00E0BDFBCBF9FAF9BFAFFDBFEF9CFBC9009000000B000B09A99CACADADAF9FDAD9A9F0F0F0D90A9000000000009009C90A90A909E9CACB00A0A00009A0A00A9A0A0A0A9A0A0A0A00009A900A000B000009000A00A0900A000A0B0A0A90A900A09A909AFFFDBFFDBE9FDBCBE9F9EB909A9C0009000090000000E9999ADAD0F0ADAFDE9F0F0F0AC9009000000000009A00B00090BCBCA900A00090A9A00900B000090000000900009A0AE000000A0000A9A0A0A90A00A00000A900000000000A09A0090FDFFBEBDAFDFCBFFF9FBFBD0F090A009000090090909090ACAC909A9ADBC90B9E9F00909000000009090909009B0D0F0F0F09000A909A0A00000A0A000A0A0A0B0A00A00A009090A0A09000A000000000009000B0A900A0A0B0A0A000000B0E00BBDFFDBDBFBFFDBFFFCBDAB0BC09000000000000000009090BCBC9C9009E9C090090E00000000000000ACA9E0C0A90B0F0BC0A900A0000000B00900A0900090009A00A9000A0E90000A00009A0A9A9A0A0A0A0000A000900000900B00A0090B0CBFBDFEBDEDBEBF0FBFFFDF90B00B009000900000000000090000A00F009A9E0F0E90900000000000B090909B090F0F90000000A00A9A09A00A0A090A00B0A0A00009000A000BCA90000A9A000000000900090A0000B0A0B0A0A0A00A90A000090FFFBDFBFBDFFDFFFF9FBE9E909000000000000000000000090909000900090009000000000000900C0BCB009E90900F0F000A9000000A0000900A000A000900A0A0A0A09A0CB00A0A000000B0A0A0A0A0A0A090A0000000090000000000A9A0F9FBFFBCBCF9FFF9F0FFF9F99E00909A0000900000000000000000090009000900000000000090A099B090C9E90BCAF0900A0000A00A0000A0A0A090B00B0A0A90000000000B0000090000A000090900009000A09A0A0B00A0A0B0A000A9009000FFDFFFFFBE9BFFFFBCBFBCB09000090000000000000000000000000000000000000000000009C9A0000A9A9AD0BD9AC00900A09000000090009A0A0A0000900A9A009A0A0CBA0A00A0A09A0B0A0A0A0A0A900A009000A900000090A900A0A0909AFBDFBDFFEDAFFFFFFDFBCBCB00000000000000000000000000000000000000000000000000009E9C9C9C09AD0AC0B000A0000A09A0B0A0A0A09009A0B0A000009A00090BC090000900000000009090000E900A0A0000A09A000A00A00009A0E9FFFBFFBDBDBDBFFDBEBDB909C90090000000000000000000000000000000000000000090A9A9090BA9AB9E9EBDA9C0A0090A00000000009000A0A0000000B0A0A00A0A0C90A00A00A0A00A0B0A0A0A90A9A0B0009A0A00A00A00000090A00090FBDFDBFFFFCBCBFFFDFFBCBCA000009009000000000000000000000000000000000009A09C90F0BC9DADCB0900C0B0000A09000A0000A00A0B00900B0A9A00000009000BA00A90A0000090009C0000A00000CA9A0000900090A0A9A0A000B0A90FAFFFCBFFBFFDBFFBF0F9B090900000000000000000000000000000000000000000000F0B0F0F9BEBDBB0F0F0B0000B0000A000A0A09000000A0A0000000B0A9A0A0A0CB0000090A09A0A00A0B0B00A9A0B0000A9A0A0A0A090000000B0009A09FBFBFDADFFBEFDFFFFBC9F000A900000000000000000000000000000000000000090090DA9BCF9F0FC9E9F0C09EB0000A00A900000A0A90A00000A9A0A00000000000BC0B0A0A00000009A0000009000000A0F0000009000A0A0A9A000A000BC0FDFFBFBFDFFBFFF9FFBF09F090090900000000000000000000000000000000009E90F0BDFEB9E9F0BE9BCAB9E9CA0A900000A09000000009A00B000900B0A0A9A090CB00000009A0A90AC9A0A0A0A00A9A9000A0B0A0A0B00900000A090A900B9AFFFDEDBFFFFFFFF0FCBF000000000000000000000000000000000000000000000F0F0FA99EDBE9F9FC0BDCF0A9000A9A0000A0A000A0A009A00A0A0A00090000A0B0A00A90A0000A09A09009000A9000A9A090090000000A0A0A900A00A0B0E9AFFFFBE9FFFBFFFFDBC9AD09000000000000000000000000000000000000900BDA9DFBDEFFADF9EF0BD0FA0F0A9A00000A000009A00000A0000090090A0A00A000E90B00A00A0900A00A0A0A00900A00000A0A0A0A9A0B0009000A000000090990BFFDFBC9EFDFFFBEBDB0F0A9000909000000000000000000000000000000000FABCFB9F9FAFF9EDAFF0F000000A00A009A000000A09000A0A00A0A0900A009A09E000000900A0090B009000A0A009A0A9009009000000A00A0A90A9A09A0A0E0DBFFFCBF9FBFFFFDFADB09C0090000000000000000000000000000000090DBC9DFBDEFEFFDF0FFBFDA00A9A00090090A000A0A00900A000090A0000A0090A000E90A0B0A0A000A0A000A0A00009A00900A0A0A0A0A0A090A090000000000090B0BDBFFFCBCFFFFFFBFDADE9A900000000000000000000000009009000900B0BFEBCBFF9F9EBFF9EDE0CB0009A00A0A000000000A00A00B00A0900A0000A090A09A000000000A90000B00000B0A00000A0090090000900A090A0A0A000A090A90F0FE9FBFDFADBFFEDEBF9BC9CA90900000000000000000000000009000BC0FCBDFFF0FFEFFDADEFAFB0000A00A000000A0A9A000000000A000A009A0B00A0000E9A9A0A00A00A0B0000A0900000A9009A0A0A0A0B0A000A00000900B000A00A09A9BFEDEF9FFCBDFBDFCF0B09000000000000000000000000009A00A000B0BDEBCBFF9FF9EFFF090C0F0B000000A00A9000000B0A09A0009A00B00000000A0A0BC00009000900000BCA90A000B000A00000900900000B000A9A0A00000A00000A09CA9FBFFE9FFFFFFBF9FCBCBC90000000000000900000900900909090DADABDBFDFEF9FFDA09E0BA0000A9A00090000A00000000000A0000000A000A090000CB00A0A0B0A00A0A0000000A000B000A09A0A0A0A09A000B000000A0A9009A0B09A09FFDFFFFE9EFFEDEFA9F009A000900000000000090000DA0D000000AD0BDEF9EBF9EF9A0DA09C90A0A0009A00A0A000A00A00A0A0900A0A0000B000A09A0B0A09000000A90909A0A0A09A0000A90A00009009A000A000A0A00900A0A0000000B000BFFFFFF9F9FF9FDF0DB0DA9000009090900000009A09A0A9E9E9D0FCBDAFDF0F9E0FA000A0A009000A00A00000A90A0000090A0A0090A9A000B000000F09A0A9A0000A0A0009000000B0A000000A9A0A0000A90B090090A000000A00A0A000B0009F9FFEFFFFFFBEFADE99CB0B09C0000A9090F009F090D0009AEB9F0BDAFBFCBF90F09E9A90A0A9000000A09000000A9A000000A000000A0000A0A009E0000000B000009A0A0B0A000009A0A9A000000A9A00A00A0A0A00A90090000000A90000BCFFFFFFFFFFDF9FB9ACB0D0DA0B09090E0909A90F0F0BDAC99CFADFEDBCBF0CAC00A0000A0000A0B00900A000A090000A000000A0A0090A0009000E90A90A0A00A0B0AC0000090A0A0A0000000A9A00009A09A009000000A0A09A09A0000A900FBFFDFFFBEFFFFEDEDFBDA9A090D0ADA99F0BDEF0F0BCABDBEFADFA9BCBCBCB090090B0A900A00000A0A000A000A00A000B00B000900A000A00A0A9A90A00900090000B0B0A0A0090900B0A0B00009A0A00CA0B0A009A0000000000090A90000009FBEFFDFFFFFFFFBDBEDBD9E9AF99CBE9FCBB9F9FDBDDAFDBCBCFDE9E9E9E000A0A0000B000B0A000000009A000009A00A000000A000A09A0000E0A00B0A0A0A0A9000009000A0A0A000900A0A00090A90000000A00A9A00A00A00A0000A90A000FBDFFFFAFFFFFFEDBEBFADF9FEB9DB0BDFCF0F0BFAFDAFDBDBE0BCBDAC9E00900B0A000A00009A00A0B000000A00000000A0A00A0090000A00DBC9A0009000900A9A0A0A9A000090A0A000900A0A090A9ADA9A0000000900000A00A0A900900009EBFFFFFFDBFFFFFDFCFBEFE9FEBCFFAFBFFFFFCF9AFDAFEDBFCBCA09A00B0A00090A900A000009000000A0A90A00A0A009000900A0A00900A00AC0B0A0A0A0ADA09000009A9A0A9000B0A0A90000A00000000B000A0A09A0000090000A00000009FFFFFFEFFFFFBFFFBFDBDBDBDBF9FFDFF9E9FBEFDAFF90FCB0F0DAC0000090A0A000B00A0A0A00A0A000000009009000A00A0A00000A0ADB00B000009009000CA0A9A0A0090009A0000900A0B00B0A0B0A000A09000000A90A000A0090A0000009FDFFFFFFCFFCBDFFFFFEFEFFFFFFBEFFFFEDBDADBCFF0BC0000000B0A0A00000A0009000000000009000A0A0A000A00B0000009A0000ACB00A0A0A0A0A0B0B090AC90A0A90A000A00A00900A0009000D0A000A00A00900000A9000A0000000000AF9FFFFFFFFFFFFFFF9F9FFFFFFFDBF9FFFEFFEFF0E0CBC0000B0009000A9009A00A0A90A0B009A0A00000000A000000A009A000A00F90A090900000900000A009A09000A00B009A09A0A009A00A0A0A90A000900A00A0000000A00B00A00000900F9FFFFFFFFE9F0FFFFFFFADFBFFEFFFFDFFF0BF9F000A0A900A0A0A900A0000A000000000A00000B0090A000B0A0009A000A0900A0E900A0A9A90A0A0B0090A000A0A90A000A00A0009A000A090900A900A0A000000A000A090000909090000F0BC9BFFFFFFFFFFFFFFFDFFFFFFFFFDEBFC09E0E0CB009000A9000000A00A09000A0A00A00000A0000A0090A00900A000A090A0AF90CA000000A000900A0A009A9090A900A0000090A000A0900A0A000A900090A00090A00A000A0A0A009A0000CBFCBCBF9FFFFFFFFFFFFFFCFFDFEA9F0F009FDB00F0A0A900A9A0A00090A0A0090000000A09000A0000A000A0A900A900A0000CAB00B09A0000B00A0900B000E0A00A009A9A0A0000A90A0A000CB0000A00A000B00009000A090000A0000B0090AD0FCFFFFFDEDFFFFFBDBFFFE9FDE0FCA00BEDF000000A00000900B0A0000A0A00B00A900A000000A000A9000A000A0000A90BD0A000A09A9A00B09A0A00B09ADA909A0000900A900000009A9A0A9A0000000A00A00A000000A09000A9000B0AD0B0B0BCA0FBFFFEF0FEFCBC9E00BCB09CBCBFADA9A9000B0A0A0A0000B0090000000000000A09A090A000A9A00B000B0A00AC0A090A00A0000B00A0C90B0FADA9E0A000A00A000A0A0B0A0000000009A00A000000000A90A000A0B000A0A0090AC900CBDFBCB00909E90BCBC00BC9E0EB0BDADA0000A0A009000000B000A0A0A00A00A0A000000000090AD009A000A0009A0BB00A09A900E9ACBE9A9AF0F9FFFF09C0B09A009A00900009A0A9ADA0A00009000B0A9A000000B00000A009000A090ACB0000000000000000000F000A9090ACBDA9A0A00900A0A9A9A00A9E90000000000000B00A000A00A9A0BE0BE9000A000CF090A00A090A9BDBCB0DBFFFFFFFFA9A0AC09A000A0A0A00090E00090A00A00A000000B0A0A000B00090A00B00A0A90000000000000000000A00BCB0A0A09A0AC0009A0A090000000B00A9EB0B0A90A9009000000A009A00F00BDCBE9E90A909A0A090E90A09ADBFF0FFFFFFFFFFFCF09CB0A00A9000900A0A009A0A090A00A00A0A000009000A00A0A000A0090090A9A9A0000000A0900B09CB00009009A090B0B000000A09A0A0000B0F9F00000A00A0A00A000000A0DA0BFCBFF0F0A000AE9E900A90A09ADFFFCBDBFFFFFFFFFFA9EBA0DA900A9A0A900090A09C00A0900900900A000A0A0000000000000A00A0000000A0B090000A0000A0A0B0A0A0000A0000A00A000A0090A9ADFBF0E0A0000000000000A90A09ABDFCBFFDFFADA9A0B000A90A09CA9ABDFBF0FBFFFFFFFFBDF9FDFA00A000000A0B0A000A0B000A0A0A00A900B0000B009A00A9A0A00A00A9A00A090000A0B009ADA909000009A0B00B0A000900B0000A0009A9FCB0900A00A0000A90000090AC9EBFFFFFFDF0E000DBA90A90A0B00DAFBCBBEDFBFBFFFDFBFFFFFDAD0A90A90000009A9000A9000000A000A00A00000A00090000900009000A90A0A0A0000A0A000A0A0A0A00000A00000B0A0000A9000A0A9E9BCA000000000A0000A00A009AB9E9FDFFFFFF9F00BC00A9E9CB00B09F0F0C9BFDE9FBEBFDFFFF9E9A000A00A9A0B0A00A0B0E0B0A9009A000000B000000A00000A009A0A09000000909A0F0909A900090090A00009A0B00000A0000A09000DADA090A09A00A90000A00000A000E9FFFFFFFF0E0A0CA9E90B0B00B0BF0F0DBBE9A9B0F9F9FBFFFEDA00B090B00000000B09000000000A0000A9A000A00A000A0A000A00000A0A0B00A0A0900A0A00A00A00A000A9A0000000B009A0A00A0A9A0B0F0A000090000A000000A0900F9FFFFFFFBCE9090B9A9AF0F09AC9E9FFBEF0DADADF9EB0BDFFDBADA00A0ACA0A0B0B000A0A0B0A0A0000B00000000900900009000000A900000000000A0A00000009000000B0000A0A00A000A00009000009FFF9F000A00A00000A09A000A0B0ABFDFFFEDB0A0A0CF090A90E09A9BFFFF9FFBDBFBFBDADA0BBEDB009A909090900C0BCBC0900009009A000A00A0A0A000A0B000A90A00A0A9000A0B09090B0B00A0A0A0B0000A00090A90A0000A00A0A9A0A9FFE9E9000000A0000000090000BC9BFFFFDAC90000BA9AF9EB90A0FFFFFFFF0FADFDFFCB0BDFDBF0E9A00A0A0A0ADABCB0A9A0B0A0A0A00A09009000000A00000A00A0900000A0B0000A0A00000A90000000A0A90A000000090A0090000009BFFFFF0A00A00000A90A00A0A0A90BEDFEFDA0B0A9A09DAF90B0CA9FBFFFFFDA9F9FBFFDBE9FBFFFFCB000A9E9C9ADABDFBE9E0000900000900A0A00A00A00000A0000000A00A000000A000000A000000A90A09000090A00A00A09000A00A00BEDF9F00000900A90000000000090EBDBF9FA0F000000EB09EBCB09A9FFFFFFFF0A9FFFFFF9FFFFFFFBC0B090BABE9BDFFFDF090B0A0A0B0A0A0000009009009A00B00A9A0000900B0A90A900B00B0A0A00A00A0A0A0A00A09A00A00A00B00B009BBE00A9A000000A00A09A009A0A90EBCF0DA0A0A0009EB90B9E0A9ADFFFFF0DBCA9FFFFFFFFFFFFDFBC00AC9DBDFFFFFFFEFA0009000000090A90A00A00A0000000000009A00A00000000A0000009009000900909000900009000900000000A0C09A900000A00000000000A0090A900B0A0909090A0F90E9E09A9CBBFFFFBFA09BFFFFFFFFFFFFFFF0B0B0BBFFFFFFFFFFF9CB0A0A9A0B0A0A00A00A00A00A00A00A00A0A00A00A00A00A00A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0B09A9A00A00A000A00A00A00A00A0A9A0B0A9A0A0A0A00B0A9A09A00B9FFFFFF000B0FFFFFFFFFFFFFFF9E00BDFFFFFFFFFFFF0A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0000000000000000000000000000000000000000000000000000000000000000105000000000000B4AD05FE")); - strs.Add(func2(2), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D20540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00F00000000000000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000000C00BFE000000A9000FFFFFFFFFFCFFFFFFFC009FFC00000000000000000000000000000000000F0000000000000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB09F00000000FCBFFE9E0BFFFFFFFFFF0FFFFFFC09FFFE0000000000000000000900000000000000000F000000000000000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000009009F09FFC0BFFFFFFFFFF0FFFFFFFFEFFFC00000000000000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0B00000FF0000000BFFFFFFFFFFFDFFFFFF0F9FE0000000000000000000000000000000900000000F00000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE09FFFC0A9F0000FC00BFFFFFFFFFFFEBFFFFCFFEFC00000000000000000000900000090000000000000F0000000000000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF009CBE09C00000000BFFFFFFFFFFFFFDFFFCBFC90000000000000000000000000000000000000000000F0000000000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0009FF0BFA9F0A9BFFFFFFFFFFFFFEFFFFFFC000000000000000009000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF009FCBC0DFFFFDFFFFFFFFFFFFFFFF9F0FC000000000000000000C0000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00AF0000000000BFFFFFFFFFFFFFFFEFE0000000000000000000D000000000000000000000000000000F00000000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9FC00BF0090BFFFFFFFFFFFFFFFFDFC00000000000000000C00000000000000000000000000000000F0000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD09EBFC9ADAFFFFFFFFFFFFFFFFFFFE000000000000000000000000000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000009FFFFFFFFFFFFFFFFFFFC00000000000000009C0000000000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0BFDBFFFFFFFFFFFFFFFFFFFFFFF00000000000000090000000000000000000000000000000000000F00000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000F0000000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9FDB9FFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000000000000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDBFFFBFFF99FFFFFFFFFFFFFFFFFFFFFC00000009000000000000000000000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBBFFF9FDFBDFFF9BFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000F00000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FBFFDFBDFFBFFFBFFFF9FFFFFFFFFFFFFFFFFF0000000000000000000000000090A0009CB0DA9A9AF9E9BE900A00F0000000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFFFFFBFFBFBFDFBFFFFF9BFFFFFFFFFFFFFFFFE00000000000000009CA90A90F00C90BDA9ADA9FF9F9E9BD9B0C9C0F0000000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFFFBDFFF9FD0F9F9DFBFFFFF9FFFFFFFFFFFFFFFC0000000000000DADA99E09CB0F9BCBDAD9F9BDB0BCB9ADAFCB9A9FF000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFFBF9FFBDA9F0AD0B0A09DB9BFFFBFFFFFFFFFFFFFFE0900000009CB0B9BDA99F9BDB0F9B0B9AB0F9ADF9BDADB99BCBDA9F00000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFDBFBFDBFCF0F0FDFCBDAD0D9F0BEFDFBFFFFFFFFFFFFFFFFC000000000009CBCF0BCB0F0BDB9E9F9E9DB9E9B0F0BDB0FE9B9ADBF0000000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFDBFFFF9FF0F9FFBCB0BD0F9A9E00D090BDFBFFFFFFFFFFFFFFC0000000C0B9FB9B9BDB9F9BDA9E9B9E99A9E9ADF99F9ADB99F0F9EF0000000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFBDBDBDADEADBDA9C9F9F0FBDADA9DB0F0F9E9DBFFF9FFFFFFFFFE000000B09DA9CBCF09E9A9E9F9BD0F9ADBDB9F9A9E9ADADBE9F0F9F000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFBE9FBFBE9FDBDBCBCBFBC9E9F9E0DBDA0DB09E09E9CB9FFFFFFFFFFFC00009000A9FB99B9F09F9F9B0F0B99E9ADADA9E9F9F9B9AD9A9B0FF00000000000000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFFFDF9FDFBCDFDADA9E90B9C9CBFBCBFDBF0F9FBC9E99E9AD0FFFF9FFFFFFFE0000C0DBDB0DAD0F0BC9BCBCF9BCBC9BDB9BDB9F0B0F0F9BE9E9F9F00000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFFFFDBBBFFB9CFB0BCB0F09FDE9FA90DB9CBD0F9E9CBF99E90F9A90BFF9FFFFFFC00000B9A9ADB9BF0BDBBCB9B9BCBDBBDA9EDA9E9B9F9F0BC9B9F9AF0000000000000000000000000000000000000000000000000000000009FFFFFFFFFFFFFF9F9BDFCB0DCB0DBC9DBDBF0A9E99FF0FCB0FB9E9FBC9EB0F09EDBCF9BF9BFFFF000909CBDBDB0F09BCB0DBDADADB9A9CBDB9B9F9E9E9A9BDBFCB0F9F9F0F0D000000000000000000000000000000000000000000000000000FFFFFFFFFFFFD9BF9FFB9FCB0BCB0DBE9E90DBDB9E09CB09AD0DBDA9DBD9C99E99E9B0F0FFFFFFFC0F0A9BCBCBCB9F0B9DB0B0F9B9E9DB9B0F0DA9F9F9F9E9A9B9DB0FF9F99BBF990C000000000000000000000000000000000000000000000FFFFFFFFFFFB0BFF0FBCDADBC9E9BCB0D09AF09E0D9F9A9F0DA9E09D0A00F0BCBDA9F0F0F0FB9FFF00009CBDB9F9BCBDF0B0F9F90FCBCB0F0F9BF9F0BCB0F9F9F9EB0F9FB0BDAFDBCF9AD09A0CBCB0000000000000000000000000000000000BFFFFFFFFF0BD9FF9F9C9ADA09F09C9CB0BFD09E99FA9AD9E9F9F99F0F9F99BD9B0FD0FF9F9E9FFFF009ADA9B0F0BCB9B0B0F9E9AF9B9B9F0B90F90B9F9BDB0BCBCB9DB0F9F0BD9A9B0F90F0DB909FF000000000000000000000000000000009FFFFFFFBC9F9EF9F0F0BC9A9DA99E9A9CBD0BFD9E90DFDA9F9BCBCBCBDBCBEDBEDF9BF99F0F9E9BFFC00009C9F9BDB9E9F9D0B9F90F9E9E9F0DB0FBCF0BCBC9F9BFC9A9FBCBDABDBC9B9EB9BADBFA9AF0000000000000000000000000000000FFFFFFE90BDADBF9E90D0BC9E90E90F0F90BD0BA9FFB9A9F9E9F9F9F9F0DBDBCB9FBE9EF0BF9E9E9FF009090B0BCB0D9BCBA9BCB0F9BCB99A9F0BD09B9F9B9BA9E99BE9A9FF909DADB0DB9DAD9BC9DBD9C00000000000000000000000000000FFFFFD09BDFB9F0BC9E9A9C9A90F9CB090BDA9F9DF09FD9FDADBCBDBDE9BFBDFBDCBD9DB9FDFFBFD9FE000E000D0B9FBADBDDADB9F0BCBDAD9F0BCBFBCB9E9E9DB9FAD9BDBF9A9FAB90DA9F0B9ADB9BE9ABC000000000000000000000000000BFFFFCB9BCFB0FD0D0A909CB09CB9CB0FDBCBDF9EBDBF0BE9BDBDBF9E9BFFD0FBDFBF0FB0DBF0FFDBE90009090B0B0DB0D9A9A99EDAD9BDA9BAB9F9B9CB9E9F9F0BCBDBADA9F9DA9D9E9B9E9BC9FA9E99F9CBC00000000000000000000000009FFFE99DADB0DF0B0BD00F0B0FA9C0B9DB0DBDA9F90F9FFFDBDBFFDFF9FDBDBF9FBFDBFF9FBCBF9FAF9FBC000AC00C9ADB0BDBDADB9B0F0BDAD9CF0BCFBDF9B0B0F9BDAD9BDAFABDABD9ADB9E9BC9F99E9AF99B0000000000000000000000000FFF99EBDBDFB09E9C00F09FC90DBDB0F0DBADBD0BFF9F99FBFFDB9B9FFBDFBDBF9F9FDBDFDBDDFFDFFAFDBF090090009A9F0BCB9ADADB9F0BDAB9BDB9F0B0FDBDB0BCB9AD0BDF9DA9DABD0BDBD0B0F9E9BD9AD0F00000000000000000000000BFF09E99ADB0DB0009A99F009BDBCB0F9A9CDBCBFDBDF0FF9BDBFDFFFF9FFBDFFDFFFBFFFBFFBA9FBF9F9FCBC009A090E9C9BDB9CB9F9CB9F909DADADA9F9F9ADADBDBF0F0BCBBDA9FA9D0BCB9AB9F9A9BCBE9BF9B0000000000000000000009FE09F9DAD9ADA0D0F0D9E09FF0F0B9F9E9DBA9DBDB9EBFDBFDFFDBF9F9FFF9FBFBF9FFDBDFF9FDFBDFFDAFBFB0000000909ADA9CBBCB0BBCBCBEB9BDB9F9E9ADB9BC9A9F9BDB9DBDA9DBAF9BCBD0DA9F0DB99E90D0F00000000000000000000FF99BCB0F0E90DA090B0A9DB09F9FDE9E9DA9DEBDADFFDBFDBFBFBFFFFFF9FFFFFDFBDFBFF9FFFF9FFBDBFDBCFF009CB00AC99FB9C9BDBC9F9B990FCB0F0F9BDB0F09BDF0BC9ADFCB9E9D90F9BDA9BDA9F0DA99EB9BCB000000000000000000BF00DB0DB9B0F0090BC9D0BCBDA9A9B9E9A9FBF9F9FB9FBDBFDFDFDFF9FFFFFFFDFFFFFDFBFFBDBFBFDBEFBFFBD9F00000900AC9FABC9ADB0BC9E9B9BDB9F0F0F9F0FA9A9F9BF9AFB9E9BEBD0BDADBCB9F0B9F0F99E9BDF00000000000000000FC0BD0F90D0D00F0D09A9F9BDADBDF0F9F9F0D0F9FBDFFDF9FFBFBFBFFFF9FF9FFBFDFFBFDFFDFFFFFFF9FDBDFBEBF0090C0909B0D9B9F90F9BF0BCBCB0F9BDB9E9BD0F9F0F09E9F9E99E990BDADB0B9E99BDADB9E99F0B0000000000000000BF0BDA99ADA0B0909A9F0F09E9FBCB9F9CBC9FBF9FBDFBDABDBFDFFDFDF9FFBFFFFFFBF9FFFFBFBFDFFDBFFBFEBFFDF0000B00A9ADBA9E9E9B0F09DBDB9F9ADA9E9BDA9BDADB9E9FDB90F9BCBCBDB0DADBCBCB990F9EA9F9F000000000000000FC0DADBC9009C9E0F9CB9F9F9F09FDADBF9FBDBDFF9EBDBFDBDBFF9FBFFFFFDF9F9FDFFFFFBFDFFFBFFBFFFDBDF9FAFF0000909C9A9DBDB9E9F9F9A9BCF0FDB9F9F0BDBCB9F0F9B0BEDB0F0B090BDB9DB0BDBDAF9A99DA9EBC9000000000000BFC09D09AD0DA0099A0BCB0F0F9F9BDF9CBF9E9F09FF9FF9FBDBDBFF9FDF9F9FFFBFFBDFBDFFFFBDFFFFFFDBFFBDFBDBDF0900C0009E9A9E99A9E9F9E9B9B0BCF0F9F9A9BDA9B0F9FF9B0F9BD0BDB0F0BDBD09AD9E9F0B9F999AC00000000000FE09A9BC90B0090F0D9DBDBDBDBFCFBB9B9C9BDBFF9FDBDBDBDBDF9BDBFBFFFF9FDBDFFBFFBDF9FFBDBFBDFFFDFFBDFFBFE00B09A9C90DB9F0DBDB0B9F0F0F9B9BDA9E9F0BDBCB9E9FB0F9BC0BCB0F9BCBDA9BF9A9B0F9E9ADADB0000000000FF0DA9F09000C9E9ADB9EB0FBDAF9BBFCFFCBBDADBDBCB9F9FDBDA9FDBF9FFDB9FFBDBFBFDBFFBFFBFFFDFFBFBFBBDBFF9FF0000000B0FBADADB0B0F9E9F9F9BCBCB9F9F0BDBCB9E9BDF99ADBD09BDBCBBDBDAD0BD0F909BDB090BD000000000FFF09C9E09E9B09F09AF99F0F9F9FDDBDB9BDFDBDFBDBDFBDADF9BDB9F9F9FBDFBDFFDBFDBDFBDBDFDBFFBFFDFFDFFF0FFBDF0000D00909DB9A9F9F0F9F9A9ADBDB0F0F09E9BFCB9BCBCF9DA9A9CBDB9D0B0BDBDABD0FBC9ADBDBCB9000000009FFC9B0900000F09F9DBE9F9FF9FABDBBCFF9BE9BC9FFBDBD9B0FDADBDBDF9FF9FBDBFDFBFBDFFFBFBFBFFFBFBFBF9FF9FFBFF090A09E9A9E9D0BCB90B0F9F9F0F9F9B9FB9E9BDBCBBFB9A9DBDA90BCB0BDBDA9BD0B9909BDB0B09F0E00000000BCA09F0C90D090F0FBC9F9F0BFDDFBFC99BEDBFDBF9D9EBFBDB9F9BDBDB9FF9FDFBDBFBDFFFBDBDFDFDF9FFFFDF9FB9FF0FDF000900009F9F0BDB9E9F9BCBCBB9E9ADA90F9F9ADBD0F9E9FADA9CBDBDBCBD0B9E9BDBE9AF9E9C9FB09000000000099F00B0B0BE9BDBC9F0BF9F0BBBDF9BFFDBDB9F9FBBF9C9F9F99FD0BDFB9FFBFFFFFDF9FBDFBFFBFBFFFF9FBFFF9FF9FBFBC0000D09E9B0BDA9E9DA9E9B9BCF99F9F9F9ADADBE9FF9B099BD0B9E9A99A9F0DBC9A99F90F9B0A9CBC0000000000CB0B000DBC9CBC9BFBFC9F9FFDDF9FF9BBFBDFBF9FD9FBF9F9FFBBDB999F9F9F9F9BFBFDBBFDBDFFFFFFFFFFBFFFFBFFFFFF009A0A09CBD0B9F9A9BDB0DADB9AF0BCB0F9BF9BDA9FEDBCBCBD09BDBCBDA9F0B9E9E90F9AD9D9B99BC900000009AD9C0DA09BF99BFDBD9FBFF9BFBBF9FFDFDBF9F9FBFBDBDB9F9FD9F9FF9F9F9DBDFD9F9FDFBFFFBDBFF9FBFDFDBFFDBBFDBFF009009A9EBD0F0F9ADADB9F9E9DBDB9E9ADB0F0BDADB90B9F9A9E9BC9A9F90BDA99BDB0BDB0BADAF09AC000000099A0909DAD0F0F9BCBFBDADFF9FDBFBDBFBDBFFF9FDFBDBFF9F9BF9F09F0F9EBDB9FF9FFBFFFBFFFFDBFFFFBFBF9FBFDFBFFF000C900999A9BDB0DBDB0F0B9FA9ADB9F9BDB9F9E9FBCB9E9A9CB9E9B9DB0BDA9FBCB09CB0F0D9F99E900000009CBC0B0F0B9F9FDADF9FDBDBF9FDBFBDBDFDFFF99BDBBDBDF9FBFFD9F9F9F9F99F9FF9BFBDBDFFBFBFFFFBDBDFF9FFFDFBDFFF000B00B0FAD0F0BCBA9ADBDBCBDBDB0F0F0F0F0F9BF99E99BDA99F9E9EB0F09F909F9E9BDB99AB9CB9F90900000B909C99BC9A9FBDBBDBF9BF9FFBFDFFFBFB9F9FFFBDFBFFBF9F9FBFDBDBDB0FF9F9FBFDFFFFBDFFDFFBDFFFF9FBDBFBFFFF9FF00000C909BB9F9BD9FDA9ADB9BDA9F9B9BDB9F0BCBE99E9E99E0B9BD9F9BDA9FB0B99E9ADAD9CBBCB0F0A90009CBCA9AC0F9FD0F0DFBFDF9FF9BDFF9F9FFDBFF9F9FBFDBDBFFFF9FBBDBDBD99BDBC9DBF9FBFFFFBFBDFFBDBFBFFFFDFFFFBFFFB09C90AD0D0F0F0B0B9F9F9E9EBDB0F0F9BCB9F9BFDBC9B9BC9BDADA9A9E99F0DBDE99BDB9B0B9CB9F9F9CB909B9090D9B9F0BBDBF9F9FBFBDFFBFBFBFBDFF9BFFF9FDBFBFDBF9FFDFBDADBC9CB9BFBDBFDFFFFBFFFBFBFFBDFDFBFFBF9FFFFBC00A0090B0B9F9E9F9E9A9E9FDB0FDBD0BCBDA9E9FB09BE9E9BDADB9F9F99EB9BF0B9ADADA0DBCB9E9A90B0C0BDA09E9ADADBDFDBDBFFBD9FFFBDBDBDFDBF9FFDB9FDBF9FDBFDBF9F9DBDBDBFB9FDBDBDFBFFBFDF9FDFDFBDFBFBFDBDFFFFF9FF009090BC9BCB09B9E9BDBDB9A9F9A9ABDBDA9F9FF9DAD9F9DA9DBC9ADBCB9CBC9BDADBDBD9A9BD0BDBDBDB90DAD009F9F9F0B9FA9DBDFBFDBDFFFFFFFBFDBDBFDBFBDFFBFFDBDFBFFFBDBDBD9FDBDBDBFDBDFFFBFFBFBDFBFFFFFFFFBFFBFFFF0000E00B0F9F9F0F9F0BCB0F9F0F9F9DBCB9F0B0FFA9A9BA9DA9BBD9A9BCB9FBDA99A9A9AD9CB9F0BCB0BCB0990DA9CB0F9FDADFBFDBDFBFFBDBFFBFDFBFBF9BFF9FB9FDBDBFBDBDBD99F9DBDBDBD9FD9BFBFFFF9FDBFFBDBDBDBFBFDFBDFBFFF0090909C9A9E9B0F9F9BDB0F9F0F0F0BBCB9FDBF09F9FC9DA9F0DA9DBCB9E90BDBC9DBD9A9B9E99F99F9900BE9A9CBDB9E9BFBFDBFFFBDF9FBFF9FFBFFFDFFBD9FBDF9FBFF9FBDB9FFFFFFFF9F9FB9BFDFFFFFBFFBFDBDFFFFFFFFFFBFFFFFBF0000AC9A9F9B9CB9E9E9ADB9EB9FB9BDFBDA9ADF9F09A9BA9FBDB9EB0B9CB9BCBCB9BE9A9CBC9BF0BF0F0F9C90C9B9CBD9FD9D9BFDB9FFBFFDFFFFFFFBDBB9DBFBDFBBFDB9F0DF9FDBFFDBDFDBF9DFFDBFFF9FFF9BDBFFFBF9FF9FFBFFFFFFFF00090909CBCBCB9F9F9BDB0F99F09E9E90BDBDBFB0DBDBC9CBDADA9DBC9BDE9F9BDAD9BDA99BF09F09B0909BCB9ACB9FAF9BFBFDBFFF9FDBFBFBFBFBDFFFDFBDF9F9FD9F0D9B9FD9BDB9F9BF9FDFBDBFFFFFE99FFFDBFBFDFFFFFFDFFFBF9FFF900C0A0B9BDA9CB9E9ADADBDBE9BF9F9BFCBCB0BCBA9ADB9B0F9BDA9F9E9B9A9E9BDAF09DAD90F09F0DBD09F00D9BCB9DBCF9FBF9F9DFBBDFFFDFFDFBFBFFBDBBF9FBF09B9D9F9BD9FDBDFDBDBF9FFDFFFFF9009F9BD9FBBFBFBFBFFFFFFFBDFE09A90C0F0BDB9E9BDB9F0B0F9F0F0BCB9BDBDBDF9DBDBCADB9FE99F0B99E9DB9F0B99FB09B0F9BDA9B0B0FB09A0DBDBBDB9E9FF9FFB9FDFBF9FBDBFFFDFBDBDFDBD9DBD9CB99BDBF9BDB9FDB9DBD9BD990000909ADBF9DFDFDFFFFBF9FFFFFBF00000909BDA9E9BCBCF0F9F9ADB9F9BDE9A9ADFA9ADADB9B9F099E9BD0F9FB0F0BDBE909E9F9BCB9F09CB9C9E9DBF0FDA9FDBF9FBFDFDBFFFFFFFFF9FFBDF9F900000909B9CBD9D99C90909090900909009DBDCBD9F9FFBFFBFDFFFFFFBFFFFF009CB0B9E9BD9ADBDB9B9F0BDB0F0BCB9BDBDAF9C9B9AD0DADBDA9ADA9AF0DB9F9AD9BDA90BCB9E90DB09F0099A9DBF9FF9BFDBF9BFBFFBDFFBDBFFFF9FBDB900B090900909009000909C9AD09099CB09F9BDBBDBFBFF9F9FFBFBF9FFFDFBFFF000000CB9E9ADBDBA9E9E9FDA9F9BDB9FCBCB9FBBC9F9B9BDB0BD09BD99BF0F0BDBBCB9DBDB9CB9E90090BF9AD9F0FDB9EDBDBDFFDBDBDFFBFFFF9FFBFDFBDA9D9BDB0D90D0909B9DBD9BD99F9F9F9DBD9F9FDBF9FDFBFBF9FFFFFFFFFBFFFBFC09A9090F9F9A9AD9F9F9B0BDA9E9ADA9B9BCBFC9BA9F0F0BDF9A9F0B0F09B9F909CB9E90B0FB9E90000FD00DABCB9BDF9BDBFBFBFDBFBFFFFFFBFFBDFBF9F9FBFDBDF9BDB9DBD9F99BD9F9F9BDBDBBDFBDFBFF9FFBFFDFFFF9F9FBFBFFFF9FFB00C0A0F0B0F9F9BE9A9E9FF9BDBDB9F9E9E99B9BC9CB90BDA9AD90B0DBDBFCBCBFB9E90F9DB9C9000099B09B9DB9F0F9BDBF9DBDFFBFDFBDBF9FDBDBFF9F9FBFDBF9BFDB9FBDBDBDBDFBD9DBD9F9DDBF9FBDF9FF9FF9FBDBFFFFFDFFFDBFFFFC09A9099BDF9E9BC9F9F9BCB0F0F0BCBCB9BCBFD09BBDAD0B9F90FBD9A9BC9BDB090F9F90ABC9B9F9F90E90BC9ADF9FCBFF0FFBFF9F9FBFFFFFFFBFFF9FFFFFDBFDFFDBFDF9DBDBDBDBDFFFBDFBDBFBDBFFFBFF9FFFFFFFFFF9FBFBFFBFFFFBFF00000CBCB0B9F9FA9A9ADB9F9B9BDBDB0FCB0BEBC9CB9B9CB0F909AD9E9BF0BCB9F0B0F9D9BD9FDF9F99E9CBF9A9E9BD0FBD9DBFBFF9FDBFDBDFDB9FF9FBFDBDBF9F9F9FFF9FFDBDFFFFFFFFBDFF9FFFFFFF9FFBFDBFDBFDBFDFDFBFFFF9FFBF009CB00BDBCB0F9FDBD9ADF0F0F0B0BDB9BDBF99B0B9E9CB9F9E9F9BA9F09F9B9E9BDB09A9DBFFBFFFF090A90F9F9F9BF9FBFF9FDDBFFBFBFFBFBFFF9FFFDBFF9FFFBDBF9FF9F9FFBFB9F9DBDFBDFFFBFFFFFF9FDBFFFFFBFFBFBFDFFBFFFBDFF000009B0F9F9FA9ADABDB9F9F9BDBDADADA9F0F0D9E90B9E9A99A9C9DA9FBCBCB9E90DAD9FF9DFFDBF90F9DF9E9EBDF9F9DBDFBFBBF9FDFBDF9FDF9FFBDBFDBFFB9FF9F9F9F9BF9FBDFBDBFF9FFFBFDFDBFF9FFBFF9FBFFF9F9FFFBFFFBFFFFF09A09F0F9B0FBD9F9BD9AF9E9ADAF0F9B9F0DB09AB9F9CB9F9E9DAB0BDB0DB99CB9F9B9BF9FFBDBFFDF09E9AD9B9CB9F0FBFBF9FDFFFFBDFBFFFBFFBDFFBDBDBFDF9FF9FBF9FF9FDF9FDBF9FBFBFDBFFBF9FFF9F9FFFDF9FFFFFBFFDFFFDFBFFC09C009BC9FBCBE9ADAF9E9B9F9BDB0F0F0BBDBC9DA9A9E90B9A9D9F0BDB0FA9BCB0F0D9FF9FFBDBFFF909F9AD9FBDE9F9FD9FF9BF9FFFBDBDBFDBDFBDBDBFFD9BDBDBF9DBF9FFBFFFBFDFFFDFDBDFBFDBFF9FFFFF9FBFF9FF9FFFFFFBFFBFFFF0090BC0BB0DBDBD9BD9F9F0F0F0BDB9F9F9FB09B0F9C99BDBC9F0B0BDA9F9DADB9F99FBDBF9BDF9FBF0DB0BDBC9F9BDBF9BFF9FF9FF9BDFFFF9FBFBFBFFFDBBFD9E9F9EBDBFF9FF09FFBFFDBFBFFBDBFDF9FBDBDBFFFDBFBDFBDBFBFFFFFF9FF00A009BD0FB9F9AF0BA9E9BDB9F9F0F0BCBF0DB0DB0B9BCB09B0F09DA9DB0BDB9E90FF9DBDFFF9DBFD0B0FDBCBBF9F9F9FFDB9F9FF9FFFFBDBFBDFFDFDF9FBDDBF99DBD9F9F9FF9FBDBDB9BFD9F9FFDBF9FBDFFFFDBDBFFDBFFFF9FFFBFFFFFFC090F0DA9BDEB0F9F9DF9BCB0F0F0B9FDB9DB9CBB0D9E9BDBC9F9FA9F9ADBCB0F9DB9DBDB9F9FFBDF0DBD9ADB9D0BDBFE9BBFDBF9FFBDBDFBDBDBDBFBFBF9FFBDBBFBDBF9E9FBDF9DBF9FDFDBFBF9FBDFF9FFB9FBFFBFDBFFBDFFFFFFFF9FBFFF0000B0FBCBBDF9B0FAB0F9F9BDBBCF0BCFADA9C9BA99ADB0B0B09DA9F9A9BDB0B09FBFFDBFF9FFBFB00BDB0DABDF0F99FD9FBDBF9FFBFBFDBFFFBD9FDFDBD9FBDFDF0DBDB9D9BFFF9EFBFBFDBDFFDBFBDF9FFFFDBDF9FDBDFBFBFFBFFFFFF9FFA0900909BD9A9E9F9DBDA9BCB0D9B9F9B9FBD0B9C9F0D9AD9C9F9A9F09DBCB0DBDBD99BFF9FFF9FDC9F09F0BD9A9F9FF9FBDFBFDBF9FDF9FFDBDFFFBBFBFFFBDBDB9FB0F9FBFD9F9F99DBDFBFFFBFDBDBFFBDBDBFFBFBFFFBFDFFFFFFFFFBDBFC000DADBCBF9F9F9EBDB9F0F9FBEDA9E9EF90B9E9B09BAD9A9B9E9F09FB0B9DA9BDBFFFDFFBFFFDB0B09F0BDBE9F9BF9FBDBBDDBFDFFFBFF9FFB99BDF9FF9F9F9FBDBDF9FDBDBFFF09CB0F9FFFBD9FFFFDBDFFBDF9FDFDFBDFFFFFFFFFBFFD9FF009A090BF0F0B0FB9E9CB9B9AD9B9F9F99E9C99AD9AD9B0DADA90BDB0D9F0B9FDFDBDBF9FFF9FBF09FE9F9E99F9FCBFBDBFDBBDBF9F9F9FFBDFFFFDBF9FF9F9F9F9DB99BFDBFD99F9B9DBF999FFBDBDBFFFB9FBFFFBFBDFFBFBFFBFFFFFFBFFF000090F9DB9F9F9ADBFB0F0F9BE9E9E9BF9A9EB9AD9AD0B09BDBD0BDBA9ADA9BBFFF9F9FF9FFFDBD009ADB9E9DA9F9FCBDBFDBF9FFBFFF9FFBDF9BF9DBFBFFBF9FE9DBFD9BDBF009FDB9DBFC0909BDBDBDFFFDF9F9FFFBFDFFFFFFFFFBFFFFBFD009E90ABDA9E9F9F09F9BDBC9BDB9F0FFE9099E99ADBBDBC909A9F09DBD99DFDBDBF9FFBFF909F0BDBDB0D9BE9FBDB9FBDBF9FFBDFDBDFF9FFBFF9FF9FDFBDFF99B09DBC0009DB9B9FFBDFB99F9DBF9FF9BDBBFFFBDFFFBFFFFFFFFFFFBDBDFE09A00F9DBBDB9E9BFF0BCB0BF0BCB9F9B99F9E9DADA9C90B0BF9F0BCB09A9FBF9FF9DF9FC909FB0DAD0FD9BE9F9DBFDBDBF9FF9DBFBFF9FFF9FF9FBDB9FBDFB90F9FDB09B9D9AD9FFDBDBBFFF9FBFFFFB9FFFDFDBDBF9FFFFFFFFFFFFFFFFFFF0000909AFCB0F9BCB99F9F9F9FDB9E9BFCB0B9B09BDB9AD9F090BD9BDBC9FBDFF9FFA9F9909BFDA9B9B0BAD99BFBF9BFF9FF9FBFBDF9FFFBFF9FFDFBDF9FBDFDF9FFBDBDBDBD9BFD9FFFDFF9FFFFFFDBDFB9BFBFFFFFFFDBFFFFFFBFFFBDBFFF0090E9BF9BDF9E9BCBE9BCB0FA9ADB0F9F0D0F0F09BCB9A99F9F0BC9A9A99FF9DBFFDB9DBFDBFC9CBDE9C9BE9DA9FFD9BF9FF9FDFBFFF9FFDFFFFBDFBDBBDF9BDBDBDBFFDBCBD9FBFFBFBDFF9BFFFFF9BDDFDFFF9FDBDFFFBFFFFFFFFFFF9FFF90E900D0F0B0BDBDBDBCB9F99FBDADB9FB9A99B9ADA9F0DA90B09F9ADBD9FF9FBFF99DBFFF9FF9A9DA9DBFC9FBDF9BFFF9F9BFBF9FDBFFFFBFFF9FFBDBDDBBFDB9FBDFD9BF99BF9FFFDFFBFFFFFFFF99FBBFFBDBFFFFFBFFFFFFFFFFFFFF9BFFC0909A9B9F9F9ADABF9BDA9AF9FBDBCBF90DBCBC9B9F09B9CBD9F9AD9B0BFBDBDBD9FBDFF9FFD09DA9BE999BF9F9FFDB9FBFDFFDFFBDBDBDFFF9FF9FF9FBFDF09FD9FB9FFD9FF9FFFFF9FFFFFFFFFF9FFFDF9FFFDFBF9FFFFFFFFFFFBFFBDFFBF00AC09EDADA9F9BD09E9F9F9E9CB0BDBCB90B09F0F0F0DA90B0BC9B0D9FDDBFFD9BDFBFFFDBF0B0DBD9BCBDBCBF9FBDFBDFBDBF9F9FFFFBDFFFFFFDBFF99F9F99FF99F90BF9FF9FF9FFDBFFFFBFF9FF9FFBFF9FBFFFFFFFFFFFFFFFFFFF9FDFF0909A9B9B9BDAF0BFF9BCB0F9FB9FDBFBCBDBDA99B99B09F9C99BC9BA9BFB9FFBF9BDF9FFBFF9CBBCBE9F9ADBDBF9FBDFBDFBDBFDF9F9FFF9FBDFFFF9FFBDBDB09BFDBDBDBF9FF9FBDBDFFFFFFFFB9FF9FFFFFFFFDBFFFFFFFFFFFFFFFF9FFFFA0009CADADA9DBD90BCB9F9BF0F0B0FF99090B9CBCBC0F90B9BE99AD9FFD9FFFDFFDBFFFB9FD009C999F09F9FBDFBDBF9FBFDFF9FBFFFBDBFFDFBFBDFF9FFFBD9F99BCBDBD9F99FFDBFFBFFBDBF9FFFBFFF9FFDBFFFFDFBFFFFFFFFFBFFBFFBFD09E099BDBDBA9AFFB9F0BCB0F9FDB9BDA9EB9CB09B9B90F0F099E99BDB9BDFFB9F9FDBFDFFF0BDB0FF0BF0F99FBDBFDBDFDBBDBFFDB9FFFFFFBFDFFBF9FDBD9F09FDB9F9DBF9FFDBFDBFFFFFFFF9FBFDFBFFBFFFDBFFFFFFFFFFFBFFFBDF9FFF0009A9E9A9F9F9F90F0BDB9F9E9A9FF9C99C9A99F0D0CB990BCB90F9FF9FBFFDFBDBFF9F99F090FB09F9DB9FFBDBDFBFBFBDFBD99FFFDBDF9FDBFBDFDFBFFFBDBDA9C9F9A9DBDBFDBFFFFFFFBDBFFDFBDFFFDBFFBFFFFFFFFFFFFFFFFDBFF9FF0090CB9F9E9E9F0BF9F9ADBE9BBDE9EB9A0BD9E90B9B9CB0F99ADB09BDF9FFFBDFBDFFFBFF9F0D9F9F9EBDB9F9FFBD9FDBFBDFFFBDBDFFFBFBFDFFFBF9F9FBDBDBDBB90F9F9FBDBFDBFFFFFFFFFFFBFFBF9FFFFDFFFBFFFFFFFFFFFFFBFFDBFF9A0A90F0B9F9A9FDADADB0DBCDA9BFF9C9D0B090F9E90B9D0B0D099FFF09FBFFF9F9BFDF09F09A90F9F99BCB9FBDFBF9BFDFFBDBDBFBF9BDFFDBF9FDFFBFFDFFFDBDDF99F9F9DBF9FFFFFFBFFFFF9FFDFFFF9FFBFFFFFFFFFFFFFFFFFFFDF9FF0D090F9BD0BFDF9ADB9BCBBDBBDBCBF90B0B9DADB090BD0B09DA90F9B99FBDFFFFF9FFF99F00DBDBDA90FDBDFF9F9FBDFDBDBDFFFFDBDBDFBDBFBDBBF9FD9BFBF9F9AB9FDF9FBFDFBDFFFFFFFFFFFBFBFFFFFFBFFBFFFFFFFBFFFFBFFBFFBDBFF0009B0F0FF9B0BF9ADE9BDA9CBCBDBE9CBCB0909DBC0BD0F9A9A99FDFF9FFFFBDBD9FFCB9F9A90F9BF9B9F9B9FBF9FDBFBFFFBFF9BDFBFBDBF9FFDF9F9BF9FDBF9F9DF9B9BDF9F9FBFFFFFFFBDFBDFDBFDBFFDBDFFFFFFFFFFBFFFFFF0BDBFFC09ACBDB9B9E9FD0F9B9ADBDFB9F9BD9A999ADA9A99B09A900D9D09BF9F9BFBDFFDB0BFD9F00DBDBC9FD0B9FDBDBDBFBDBDBDBDBDFFBDFDF9DFF9BFF9FFDBDBF9FBDB0BD9F9BDB9F9FBFFFF9FFF9FFBFDFBFDBFFBFDBFFBFFFFDFFFBFFC99DBFFE0909BCBCBF9ABF9E9F9A9A9F0BCBBF90E9D09C90E9DADA9B9A00BFF9FD99FFBFBFD99BF00009E9B99AD9EBBDFF9F9FDBFFBDFFBFDFBFBFFBF9FDBDBF9B9F9DBFDBDFDBCBDFBFDBDFFFFFBFF9BFF9FFBBDBFF9FFFFFFBFFFFFFBFFFFFF09BFFD090ADA9F9B0F9F0F9F0F9FF9ADB9FF0CB99A9B0BF9B0999C9C9B99FF9F9BFFBDFFFFF0F900C9BDBDF0F9BD9CFB9FBDBBFDBDBF9F9FBDBDB9F9F9FBFF9FDF9FB9F9BDB99F9F99DBFFBFFFFDF9FFF9FF9FDFDA9FDBF9FFDFFF9FFFFFFFF009DFF0F00DB9F9ADF9F9F9A9B0F90BDB0F9DB90BE9C0D9090BCB0B0BC009BF9FD0BDFF9FFBDF9F09009ADA9B9F9FBB9FD9FBDFDBFFFDFBFF9F9FDF9F9F9F9FFBFBF9DBDBC9BCB9F9FBFF99FFFBFB9FBD9F9ADA9B9F9FBDBFBFBFFFFBFFFBFBFF09BFF00A9A9F0BDB0F0F0F9E9F0FBDADBCBBCBD09B9A0F9AD09C9C99B909FFDBF99BBDF9FF9BF00000999FDDBDA9DF9BF9FDBBF9F9BBD9BDADB0B0F9EBF9F9BDBDBF9F0FBCBDF9DBDF9FFFBFFFFDBDFBFCF9BDFDB9F9FBDBDFFDBFFFFFFFFFF0099FF0D009E9FCBF9BBF9BCB09B9E9F0B9FDB00BC9C990BDA9B9A9AD0D09BF9FDBDFDFBFF0BFD00E900F99A9F09FB9FDBFFBDFBFBFDFBFDBDBDBDF9BD99DBFDBDBDFF9F99F9B9FBDB9FBDFFFFF0BFF9E9BDBDB9BDBF9F9FFBFFBFFFBFFFFFFBF090FF0009E9B9BDAF0DBFCBDBCBDFB9FDA9BC9BD9B0B0BD090DAD0909A90FFDBFD9BFBFDF9DF00900E9BCFBDB9F9FDBBFDB9F9D9FDBB9DA9F9F9F9BDB9EB099BFDBDB9F9F9BFDADBDFF9FBFFFD9FC9BD9F9BDBFFFFFFFFFBFDBFF9FFFFBFFFFC9FFBF0A9E9BCBCBD9FBF0B9B0BDAB0F0B9FFBC00B0D0D9A9F0B909CBD009BFF9F9E9FFFFDBFB0000900DB9DBCF9E9BDBDBDF9FBF9BC9FBDB9FBDBFFBDF9DBDAD9AFBFDBDBC9DBDBDBDBFF9BFFADBB9F9F9BDBDF9BDBFFFFFBFFFFFBFFFFFFFF0B9FFDC909BDBDB9FA9CBDBDAD0BDBDBDADBDB99ADB0B0F9090DA9A90B90F99FF9F99FFFB9FDAD000E09ADABDB9F9F9F9FFBF9DBDF9BF0DBDBDBFDBDFBDBF9BDBD99DBBDADB9BDBDBDBDBDFFFF90DFBDBD9FFDBFFD909A9FFFF9909F9FFFFFFFAD0BFA9E9ADADADA9FFB9E9ADB0DADADBDADF9E0990D0900F0B99C90BC090BFF99FDBBDBDF0BD00009009B9DA9F9FBDBFDBDFBF9BAF0DB9BCBDBDBDB0DBD99DBDBBF9FDBDBDE9BDBFBDBFFBFF09FBFDADBFFFFFD90BDBDFBD0000BDBFBFFFFFF00BFADA90D9BF9BDF0BDE9BDA9F9B9F9AF9BF009BCB0B0DB90D0F0BC99B0B9DF9FF99CBDF9BDA0000009DEDB9F9AD9FBDBBFBF9BD999B9E99BC9FF9FDBF9FFF9DBDDBDBDBDB99DBF9DBFBFDFF9BF9909909090000FFFF900000F9DBFFFFFBFF09E90C90DABAF9ADA9BDA9BCB9F0BCF9AD9BCDB9C09D00B09E90B0909AD09C9BFF99E9BDBF00900000000B9ADBDBDBFADBDFDBDBDBCF0D09F9FF009F9FF9F090BE9EBFBFBFBDF0BD9FBDFDBFFE9DBC09FFF00000909FFF0009090FBFDBF9FFFFF09E900A99D9DBDB9FCBDBCBCB09FB0BDBADBBCB9A0B9C9F09A9DBC909A90B099FF9BDBFDBD00090009000F9BDADBD9F9FBBFF9EDB9900000999BF0000009FFD9999909FDBDBDF9BF9FBFBDBFDA99BB09FF009FE000FC009FFF099DBBDFFBFFFD0000A9CA0BE9E9E9BDA9F9B9EB09F9E9DFADF9C09D09A90BC9CB0B0E990F9F00F9FDBDA900000000000090D0BDBDEB9F9FDB9F9BC9E9900000BFC0000090FFFFFD099F9BD0B9BDF9F9F9FFFFFD0FD9D09000090000000FBFF090BBDFBFDFFFF0ADBC9009C99BF9BDABDB0F0F9DBC9ADBA99BF0B9B0BC90F990B09D099E9090099FB9FFD0000000000009CBB9F9BDB9FDE9BFDBFF9B90A9C9C0000009FC00BFF000BDBDFDBBDFDBBFFFFFFFFFB09BFBFBDBD0C009009F9FF000BDBDFADFBFBFE09B000A90A9AF0BCB9DB0F0F90BCBBF9AD9EFBD000D0BCB90E90DB0B0B9E9AD9A009F990000000000000009CB9F0BDFBB9FF9FB99FCBD909A9DE900009000000AD99F9BF09DB9BDFF9FFBF9FFDF090D9DADBF9FFFFF9BFA90B9FBFF9F9BFFFF9000E0900D09D9BDBCBE9F9B9AF0B0D0BDAF9BFBD9A99090F99A9AD9C9C9909A9C90000009000900900909009CBDBDBD0F090BDFE9BDBEDB0DB090FFDBC009BC99BF99F09FADBDFBDFFF9FFFDBFF9E9A99DBD9FBFFBD00D09F9FC9FBFFF9FFFFF09F9E090A00A9DA9BDBCBDE99BC9BBDA99AD9BD0AD9E9CB09E9C9B0B0B0F90C900000000000B0C000000A0DBBD0F9FBFD9BDF909F9F99BBDB09CB99FFF9FFDBFFDBCB09F9F9FFBDBF9FFFFFBFF9F9BD0B090B990909BF9BF9FBFF0F9CBFFBFFBC00F0DAC90B0F0F9E9BF9A9F0DB0D0BDAD9BEF0B99A90B09F9A9B0D09C900B9B0000000000000B00009C09BC90F9BF9DBADA90BF9E90FDFCBDFBDDA909AD09AD090909F9F9BDBDBFFFFF9FFFF9FB0D0FCBDBC9EDBDBFDBFDAD9E9F9A9BFFFFFFF09FB009000D0B9CB9F0F9F0FB0DABDADBAF9F90F0DA90F090D0D0B90BCB99C0B000000000D09C0900000F0BDB9FCBFA9DBDAD9009F9F09BDFBDFBDBFD9BBD99F9F9FF099E9F9FFFDBFFFFF9FFDDFBB9909F9B9BFFDBFDBFDBFBDBFFF0DBFFFF00BC0F009E90BDABDADB9E9B0DBAD0B9AD9CBBF90B99E99FA9A9B9CB0990E9B00D0C09000000A0000909009CBDA9BD9FF9DB9A0D9E909F099ADB9FBDBFFDFBFF90B999FBDBDBF9D9FFFFF9FFBFBBC9CB9F000C9009BDBF9BD0900090009BFFFFF90F09FE000A00D0BDBCB9E9F09DBDAD9AB9FF9CBC9E90A99C909E90DA0B90D90A0000000C09009C00A009F9B9FDBFBDBFAD0D9A090F00BF0D9E99FFDB9FBD090F9CB09DA9BC9FBBF9F9FFF9FDFD9090D0AD0000000000C00900D00009FFFBFF00BF0F00909C9A9ADA9BDE9B0BCB0BDAF9DA9F0B09B90F9DA9ADA90B09D90F0AC90000000900C000009C9A9BCBDB9F9FBC9FB00090F00BD09BF0F090B0D0000F090B0C9B0DF9BFFDFFFFFFFFFFBFBE0000900900000090000ACB0A909BFBDFFFE9C09E90E00A0D0DB9FDA9BCBDBCBDA909ADFBD0BD0E909AD9009F9C9A9E99090090090000000900900B0DADBDAFCBDBD9F9DF0000909009E0990F00D9000000000C900C990909BFBDFFBFFFDBDBD990000900F0D0000909090909C9BFFFFFFF90BF09E9000900A90FA9F0F90B09B0DBCBDABFBD0B99B0F9ADB9090B0D09E9F00000000000900A00000C09F9EF9BDBFDA9FB0BD000000D009C009090A00D09F090090090A09FF99FFFBFFBDFFFFFFF099E000900000C0A000F0C09A9FFFBFFFFFAD0BF0F0BC0090BC9DA9F0FBCBCBDA9B0BD9F90BC9E0D9AD00DBCB09A9A900900000000000009C0B090B0BDB9FDBDB9F9BDFDBF90009000009E0C009C9A0C0000000000D9FF9FFF9FFDFDFBFFBDBFF9090C000009099C9FB09BBC9FFDFFFFFFD09ADF0F0009AC009BAD0B909B090BF0DADAFF0BC9A999AD9B9B090D099C90F000F0000000000000C0A0DBCB9F0B9E9F9FDBF9AD9F000009A9099A90000090900000009909BFFFDBFFFFFFBFFFDFFF9FFDB900000A09EBF009DADBFFBFF9FFFFA9E9FFF09C000900F0D9F9E9E9CBBD09A99F9BD09B0DAC9A9C0CBDA9ADA9A90000009000000900090090099F0DBDBDBFF9BD0BDBE9BD0009FEBCBCBC909000C9000909BDBFDF9FFFFFFBFFFFFFFBDBDBFFFFFBDBD9DF990BDBE99FFFFFFFBFFFD0B0BF00F0B000090B9A9A909A9C90BC9CB0BFBD0DB99BCB9B9090909090D0BC0000C0000000C0000D09ACBDBF9FDBD9FF0FBDBD9EDBF90909F9090BCBC0F000099DBDFFFBFFFFFFDBFFFDFFFFFFFFFFFFFF9FF9FFBFFFDF9F9BFFFFFBFFFFFFA9C90FF0F00D000000E9ADA9C9A90F0B0B0F0DA0B09E0990F0DBCBCBCBCB0900900000000000090000A0D00A9FE9BFFF99F9FADBF99FFF0009000090BF9B99F9FFFBFFBDFFFFFFF9FFFFFFBFFBDFFBFFF9F9FFFFFBFFFBFFFFFFFFFFFFFFFFFBDA0AFBCBCB0A00000909C90DA9C9E09C90D09BC909E99F0F09B0990909090E900000000000000000090C9B99DB99E9B90F9F9FDB09FBCBFD09E9FDBDF9BDFFBDBFFFFFFFFFFBFFFFFFDFFFFFFFFFFFF9FFFFFFDBFDFDFFFBFFFFFFFBFFFBFFFF09BD9CB0F0C00000000000000000090000000F000090000900000000000090000000090090000009000900F0BDFF9FDF9BF0F9BFDAD9F9BFF99DB9FFBDFFFFFFFBDFFFFFBDFFFF9FFFFBFFFDFFFFFBFFFFFFFBFDBFFBFFFFFFFFFFFFFFFFFFFDE00FAFD09A9000000000000000000000000000F000000000000000000000000F00000000000009000000090D0B09FB9AD9DBDF9BDBBF9FF9FFBFFF99FBDFBDF9FFFBFF9FFFFFFFFFFBFFFFFFBFFFFDFF9FDBFDBFFFFFFFFFFFFFFFFFFBFFFFFB90090BE9EDE00000000000000000000000000F0000000000000000000000009000C00000000D00000000BC09BD9FBDFD9A9FBDEDBDF9FF9F9FDBDBFFFFFBFFBFF9FFFFFFFFFFFFFF9FFFFFFFFFFDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9CB009F0B9A9E9C000000000000000000000009E000000000000000000000000009A000000900000C000900B009AF0DB0BDFBDB9BFF9FF9FBFFBFBDFF99BDFFFDBFFDBFFFFFBFDBFFFFF9FFF9FFFBFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCB000BCBDEDF00000000000000000000000000E9A09000000000000000000000C0000900000000A900090C900D099DB9FDBBCBFFDBDB9BDBDF9FDBF9FFFFBDBFFFFFFFBFFFDFFFFF9FFFFFBFFFBFDFFFBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC009F9F0B0BCB000000000000000000000000BC00A0000000000000000000090009000000000000000000AD0BD0BF0F9BC9F999F9FFDBFFBDFBFDFFBDBDFFFDBFDBFFFFDBFBFFBFFBFFFFDFFDFFFBFFFFBFFBFFFFFFFFFFFFFFFFFFFFFFFFFDA90000BE9F09F0C00000000000000000000000CB00000000000000000000000000000000900009C009000909000BC9BDADBF9FFEDFBDBFDBDBFDBFBFDFFFBFFBFFBFDBFFFFFDFFFF9FFBF9FBFBFFBFF9FFFF9FFF9FFBFFFFFFFFFFFFFFFFFFFBF0090BC9BC0BC0B00000000000000000000000BC0000000000B00000000000000C000C00000000000000000FAC909BC9DBD9FDB9BBDBDFBFFFBFFDFDBFBFFDFFFDFFFFF9FFFFFBDBFFDFFFFFFFFFFDBFFFBDBFFFFFDFFFFFFFFFFFFFFFFFFFBD00900FDAC0BF0BD00000000000000000000000CB009A0C00000000000000009E0900090000000090000000009F09C9BA9BFB0BDFFDBFB9F9BDFDBFBFFFFDFBDFBFFFFFFFBFFBDFFFFFFFFFFFFDBDBFFFD9FFFFFBFFFDBFFFFFFFFFFFFFFFFFDAF0E09AF9F00F0DAE0000000000000000000000BC00000900000C00E00A000009000900000000000000D000900B90BC9F9C9FDBF9BF9DFFDFBFBFDFDBF9FBFFBFFF9FBDBFFDFFBFFDBFFBFFFDBFFFFFF9BF99DBFDFBFBFFFFFFFFFFFFFFFFFFF909009F00ADBF0BD00000000000000000000000E9A0000A00000B009009000000000000000000000090A0090009E90B90FBDA9F9FD9FBF9BFDFDBFBFF9FFFDBDF9FFFFFFDFFBDFFFFFFFFDBFBFFBFF9FDE99FBF9FBFFDF9FFFFFFFFFFFFFFFF9E9A090DB0D0F0BFE00000000000000000000000BC0000000000000000000000000000C000000000000090000D009BC90F909FDB9FBFBFDBFDBFBFFDBFFFF9FFBFFFBDBDFBFBFFFFBFFFFBFFFFDFFF9F0099E99FF9FFDBBFFFBFFFFFFFFFFFFBF0BC0F0A00BE9BCD000000000000000000000000DA00A090000000ACA0000009000009000000000000000C0900BC90BC90BF90BDBF9FDBFDFBF9FDBFFDBDBFBFFDBDFFFBFFFDFFBFFFFFDFFFFFBFBD090B9F99F9FFF9BFD999C9B99FFFFFFFFFCF0900090D09C0BE900000000000000000000000E9C000000000009000CA0000000000000000000000000900A09ADC9BBD9CB99ED9F9FDBDBFDFBFF9FFFFFFF9FFFBDBFF9FBFBFDFDBF9BFF9F9FFC99099F09BFDBF9FF9BFE9000FBCBFFFFFFF9F0090FC0BF0BCF00F0000000000000000000000F0A00000A00000000B0000900000000000000000090000009C09A909C0B9F0F9BF9BF9FBFDBDFDBFFBDBDBFFFBFFFFDFFFDFFDBFFFDFFFBFFFF0B00FBF09FDFBD9F09FF090B9D9099FFFFFF9A0BC0A90BC009B0BC00000000000000000000000AC9000000000000E0000000000000000000000000000000900009CBC9B9CBDB9FDBFDFBFDBFBFBFDBDBFFFDFBDFF9FFBFFBFFFFFFBFFDFF0B00909B9D0BBFFBD9B09F909090CA00FFFFFFFF0F9C909CB0F09AC9D0C0000000000000000000000DA00C00000009A090E0000000000000000000000000909000BD0A90B9CB9CBD9FBC9BDFDBDBDBDFBFFDF9FBFFFBFFBFF9FFFDBFFFDFFB9F9D9900C9F09DF9D0B09FBDAD0BC09009BFFFFFFF900A09A0C90BC9B0A000000000000000000C00000F9E0A00000900000009E00000000000000000000000000000009C090FBCB9BCBCBFF9BFBFFDBFBDFDBBFFDF9FFDFFDFFFFFFFFFFB9B9F900B0C99BF09F09FB9FDA9F000900B0009FBFFFFF0F09C0BC9AC9BEF0F9F000000000000000C0000000F0090000000A000AC0000000000000000000000000000009C09F090F09F9E9B9F9DBDF9F9FBDFFFB9FDFBFBFF9FFBFFFFBFBFFF00C09009F009AF909B9FF09C90900909009009BF9FFFFFFF000B000099AC90DA0000000000000000000000C000E00E000000000009A0000000000000000000000000000009000BF090F0BDBCF9FBFF9F9FBDBBD9FFFFBF9FFDFBFFFBFFFDFFBD099BD0BF09DBD9C9F9E9090B09BC90000BC909E9FBFFFF90909C000D0AC9F0B0D0000000000000C0000000000F090000000000000000000000000000000000000000C0AD00A0909CB909E9DB9F9F99FBFFDBDFFBDFBDFDFBFBFF9FFFDBFBFF099BC9A9C9D0B0B09BC9900090BC0000090000E9BFFFFBF9E00000090A90B00BC9A000000000000A00000000000F0A00A00000000000090000000000000000000000009090F090C0090FD09A9F9F9FFF9F9BFDB9FFBDFBFBFFDFFFFFF9FFFFD0F00FF9CB9A009FD0B00A09DBC00900009A90A90B9FF99FFF9000000E900C9F09A9C000000000000000C00C00000AD00900000000000A00A00000000000000000000000000000009A90DA9BF9F0FBF99BDBFDBFFFF9FBFDF9FFBFFFFF9FF99F0B09F90099C099F000D09D90A09090009E0C009DADF900BFF000DA00900000B00E0DA0C000000C00C000000000000DA00C000000000000000000090000000000000000900000090F09CB09DE90F9BDE9FFFBDBF9F9FBDFDBFFF9FF9FFDBF99F09C9E909BC0009F99DB0B00A09000000B00909C0B9FA09FF0000900900009DBC0B99B0000000000000000000000000AD00A0000000000000000000000000000000000000009C000000A09B0B9DF9FDF9F9F9FFF9FFBDFFBFFF9FFFFFFB0BCBF00900900C0B00BCA0000D00D0D09DAD0D0D00009B0F0909F0909A00000000A00900AC0F000000000000000000000000F0A0000000000000000000000000000000000000000000900090D00D9CBA9E9BBDBFBF9BFDB9FBDBDB9FFBDBFFFDBD99F0909BD0909000999CB0900B0000E90B0B009A9E09F0F09F90A00D0000000909000D9B00000000000000000000000000F0D00000000000000000000000000000000000000900000BC0000B00B09DB9F9FBD9DBFDBFFFFDBFFFFFFDFFFF0090F00000F0000AC009AC0900009C090B00F0C9CBAD099BE900F00C909A009000000E00F0ACBC0000000000000000000000000A0000000000000000000000000000000000000000000000000909C909FB0F9ED9FFBFDBDBDBDBFBDBDBDBF9F9090F9090F9000090909C90900D09A09E90C90090B0D9ADAD90BD0009000000000909090F00D900000000000000000000000000F0000000000000000000000000000000000000000000900900C000ADBC0DF9F9BFBDBDBFBFFBFFDFF9FFF9FFF009F90C090000900F0009A00000AC00000909ADA9C9AC99B0E90A09000A90D0000000E0000B0AD0000000000000000000000000AD0000000000000000000000000000000000000000000000000009009B0BDADF0DBFDAD9F9DF9BF9FF9BFFBFC0909CB00AD000009000B00D00900909000000900090900E9B9C9000909C00000000A900090D90A0000000000000A00000000000DA000000000000000000000000000000000000000000C0000900900F0DB0BDB9FBDAFDBF9FB9FF9FF9FDB9FD0B0DA900090000090009C0900000D0000000000090000BF90C0A009A0A0900A000090000B0A0AD0000000000000000000900E000AD0A0A0000000000000000000000000000000000090090000009E0090B0DBDBDF9BD9BFDBF9FF9FBBDBFFFD090909C009000909C00900900900000000909000000AD9C9C009090C9090A00909000C0090C90D000000000A000A000090E000000DA0909CA900000000009A000000000000000000000000009000009000DB9E9FA9FDBFF9F9E9F9F9FDBFBDBF0BC9A09000000000000090000000909090000000F09000B00B00009A0C0D09C00000000000000B000000000090090000000900000E9E0A090000000000CA0C9A0C000000000000000000000000000000909E99F9F9BDF9BF9BDBFFBDBFC9F9FC9900D000090000009000090000900000000000900009000F90E90E0090A00000000900000090BC00000000000A00A000000CA0000F0090CA00C000E9A0909A000B0000000000000000000000000000000009F00F9FCB9FCBDFF9F9FBFDFBDBF00A0D000900000090000000000900000C00000A0000000BD0009009090E90090000000090F00BC00000000000000000000090000000F000B090A0B000C0A0A00F0000000000000000000000000000000000009F9BCB99E9BDAF9BDBDFDB99FF099C9A90000000090000009000000000900090D0090090BD0AD000F00E90009A000900000000BC0B0000000000000000009E0000000F000000E090C0B0A9C00D00000000000000000000000000900000000090009F9F0F9FDBD9FDBFFAFBCBD900A000000000000000000000000000900000000000000F00000BD0090909000009000000009009000000000000A00000000000000000F000090A0A90C90A09A0A0000B000000000000000000000000000000000900F9F9F99EB9ADBF99D9F9BCBD09090900000000000000000000000000090009000000F090900B00F00009C000000009A00F00F0000000000000000000090000000F000A0A09C00A0A090A0090F000000000000000000000000000000000000009DA9E9AF9DFB9F9FFBF9FDB000AC000009000000000000000000000000000000090090000E9BC9F00000A09000900D009009F000000000000000000000000000000A00909C0A0B0909CA00D0E0000000000000000000009000000000000900009ADBDBDBDBBD0F9F9FDADBC0909000000000000000000000000009000000000000090000090C0B000AD009AC0000A000009E000000000000000000000000000000F0DAC00A09000ACA00D0A0000009000000000000000000000000900000000009BDA9F0FC9E99FADBFDBCB0000090000000000000000000000000000000000000BC0000BC090C00900F0009A0009009CB0B0000000A0000000000000000000000DA009A00A0A0D009A0000000000000000000000000C00900000000000009000C09DADB9F99E9FDBF9F9BC0090000000000000000000000000000000000000000000909000A9009E9000000C090000A00D0000000000000000000000000000000AD00A00D090DA0BC0000000000000000000000000009000000000090000000090A9DBDAFCB090FBDBCBC90000900000000000000000000000009000000009000009A00009000B0000090090000C9A90F0000000000000A000000000000000000F0B0C09A0A0A0000000000000000B0000000900000000000000000000000000009CA9E99BC9BF909C9000090000000000000000000000000000000000000000900000009A9E900900F00000B00900C9000000000000000000000000000000000F00A9A0009C90F000000000000A000000000000900F000000000000000000009000909BC09C00AD0B0F90000000000000000000000000000000000000000090E90000000C00090E900000000000B09A0000000000009000000000000000000000F000DADA00A000000000000000009C000000000000009000000000000000000000000090A9090BC90000000000000000000000000000000000000000090CA900000D090B900E9000090BC90090C00D0000000000000A9A00000000000000000F00F0A00000000000000000000000A00000A0900000000000000000000000000009000000D000D00BC90000000000000000000000000000000000000000090000090000AC00D00000AC000000CA90A0000000000000A00C000000900000000000F000000000000000A000000000000009009C00B000000000000000000000000000090009000900900000000000000000000000000000000000000000000000C90C0009090B000BC090A09A09A90090000000B0000B0CB0A00000A0000000000F0B0A900000000000090A0000000009A00000000909000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000BC0AC090009A0090000C000F000000000A00009A0900000000000000000BC0000C00C00900B00A00000B0000000000009000000FE0000000000000000000000000000000000000000000000000000000000000000000000000000900000000090090000CBC09C009C09000900000000000000E09ACA0000000000000000FA90CA0B009000A000000000000000000C90AC0000000C00D090000000000000000000000000000000000000000000000000000000000000000900090000000000000000909A900000000A000BC00000000A09000090E09000000000000000009C0A90000A00A00000000000000000009000900DA00900000000009000000000000000000000000000000000000000000000000000000000000009000000900E9000000AC0000090000000900000000000000A009A0A9AC00000000000000000EBC000000000090000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000900000C9090B0C0000B00F0009C000000000090000009C09A00000000000000000DA9A000000000A0000000000000000000A000B00000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000DA0000000900A009000CB0B0000000000A000000A0AC000000000000000000F0C00000000000C0A000000000A000000000000E900CB0000000000000000000000000000000000000000000000000000000000000000000090C00000000000090009E90000A09C00000B0000000000000000000A00909A00000000000000000DA00000A0000900900000000000000000000009000900090AC09000000000000000000000000000000000000000000000000000000000000000000000000009000090000909000090009C0000000000000A000000900A0000000000000000000F00D00009A0000A0000000000000000000000000000000009000900900000000000000000000000000000000000000000000000000000000000000000090000000000000C0AC90000CB00000000000000090000000A00000000000A000000000AF00A00000CAF0000000000A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009A90000000B0000000000000000000A000A009A000A9C0A0000000A000F000000A0900000000000000000A0000000000000000900000000000000000000000000000000000000000000000000000000000000009009000000000000900009000C000900090000000000000000000A0000900000000C0A090F000B09C000C0000900A000000000009A000000000000A00000B00C0000000000000000000000000000000000000000000000000000000090D00000000000000000000000000E0BDA909E0900BC0000000A00000000000000009A0000B0A900A00000CA000F00000A0000000000000000000000000000000000009A00000000000000000000000000000000000000000000000000000000000009000000009C00900000000009C0000E0000BC000000000000000000000000A0000A000000F0C00000B0000AD000000000B0000000A00000000000000000000000009000000000000000000000000000000000000000000000000000000000090000000000009000000000000009009009000000000000000000000000000000000090A9E00B0000000EBC0DA0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009C0000000000000000000000000090900BCA0009ACB00000000000000000000000000000A09E0C009A0000000A90A0A900000000000000000000000000000000000000000A0C09009C00000000000000000000000000000000000000000000000000000000000000009C00000000000AD00900CB0900000000000000000000000000000090A0B0B0AC000000900F00DA000000000000000000000A0000000000000000000090A00000900000000000000000000000000000000000000000000000900000000000000000A90009CA0F090B000900C000000000000000000000000000A0B0A0D0000009000000ADA000F00000000000000000090A00000000000000A000A0900000F00AC0B0000000000000000000000000000000000000000000000000000000900009A000000009000000D000B00000000000000000000000000900C0CBCA0A00000A000000000F00F0000000000000000000C90009000000000000000000A0900090000C9C00000000000000000000090000000900000009E000000900090000F000C9C0A90B0C00BC00000BC000000000000000000000000000CA9A9009009A0B0000000000B0000F0000000000000000B000AC0A000000000000DA00A0900000000090000000000000000000900000090C0000A0000000090900000000009000900009C0000B090000B0F000000000000000000000000000A0A90000A00000000000A9009A00A0F0000000000000A00000B0090000A00000A09A00C900CA00B00000000000000000000000000009000090009000D00C90000000000000000090A0B000090000000090C90000000000000000000000A0000009000A00000A0000000000A0C000000F0000000000000D00000CA0C0A000000000000B0A000000000B000A090A0D0000009000000000C000000000D0000000000000000090000000000090AC09C000DBCB00000000000000000000000000009A00A00000000000A00000000A0BCB00F00000000000000A00000090A90000A00000000000CB000000C000900009000A000000000090009000000000000090000AD0000900000D00E090DADA9000090F000000000000000000000000A000900A000000000000000090000E9A9000000000000000000009E00A00000000009000000000B0CB000009E9A00000000C0000009000D000009A00C0000000000000009000BC0ACB0F00A0900000000000B00000000000000000000000000000A00A0000000000000000000C90A90CAC9A00A0F00000000000A09009C0000A0000A00900A000000000000000009A0000A900090000000A90E0000090C0B0000F000000000000090000900000000000009000CB0000000000000000000000A0900000000000000000000C0A00A000A09A00A900F0000000000000A0C00A000000A000000000000000000A00A9E000C0B000000000090A9C009000D0A900000900000000000000000000009000C90900F00DA900000000000000000000000000E00000000000000000AC00B09A9AD0DA00000000F000000000090009A0090C090000000A0000000A90009009000BCB00000000B000E0000000000B00000090E0000900900090900009000C009000000900B0000000000000000000000000000000000000000000909A00B00CA0C0A0A0000000A00F000000000A000000000B0E00000000000000000A0A00000EBC00000CB0000090000CB000A0C0009C00A09000000000000000900000090000A9E0BC0BC00000000000000000000000000A0900000000009A9AC0E00B0E9A090A90000B000000F0000000E9000DA000000000090C00000000000000900000A90A9A00B000B000A090B000BC9090A000B0D00009C09C000000000900000A900D00900000000000000000000000000000000000A00000000AC000AB0B0C00000A000000000000000F0900090000A000000000000A09A00000000000000000009E9C00F0000C0090C0AC0ADA0ACA090DA0C0000C0A000000B00000000D09000CA000000000000000000000000000000000000000000A00B000B0E9C00CB09A090000000000000000F00000A000AD00000000000000000000000000000000000000A0B00000B000A09A00BC00D090CA000900B09090090009000900F00A0A00090000000000000000000000000000A0000000000009000000B0009A0B0A00A00A0000000A000A00000A0000000000000000000000000000000000A900000000000B0BC0A0000000000090009A0A0A900900A9C0A000C0A0000C0E0B00BC9C0000000000000000000000000000000000000000000A00A090A0009A00000000000000000000000000A0F000A00009000000000000000000000000000000000000A900C0A9C90009E000000E0A000C9C0AC0AC00000C0A90C0000A909C0F0A000A0000000000000000000000000000000000000000000000A0090A00A90A09A000000000000900000000F0F000CB000A00000000AC00000000000000000000000000B0B00A0A00A009090A09090E9A0009000090A90B00000000900A0B00F00000DA00000000000000000000000000000000000000000000000A000000000000000000000000A0000000F00009A00A00900000000090000000000000000000000A0C0000F000000000A0090A0E00000B00A900A00000000A90000000C0E9000B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000F00AC00C9000000000000A00000000000000009000900900ADA000000000B0CBCBCA900000000000900DA000090009A00090B00000C0B000A000A00000BC000000000000000000000000000000000000000A000000000000000000000000000F0090A90A0000A0000000000000000000000000A000A000A900000B0000B0CB00A09ACB00BC00000A00A00000000000000000090000B0C000000D00000009AC000000000000000000000000000000A000A9000000A0000000000000000000000ADA0000000E09000000000000A00000090DA9AC00C000000000090000900B00B09A09000000009000000009000000000000A00E0A900A90090DA00000000000BC0000000000000000000000000000C00000000000000000000000000000A0000F000000A9090C00A0090A000000000A90AA0C009A9009A000A9A0000A0000AD0CAC9E000000B00A090090A000000000009090B09000F00A00A000000000A0900000000000000000000000000000B0900000000A00000000000000000000000000AC0000000A0A00000A090090000090CA9C9A09A00A0000000000A0900A9E9A0B09A0000000000C000E00000000000B0CA0CAC0ACB0000000000000000000A00A09000000000000000000000090C0A00000A0000000000000000000000000000F09A0000000000D0000000A000000A9A90A00000C000000900C0000000000000000009A09A0009A9A00000000000000900090BC900E90000000000000000000000A0C00000000000000000000A0BC000000000000000000000A0000000000000F0000000000090A000000000A90000C0AD0F00B0B000000ACB0A90A00000B0F000BC00C00C9A0000C90B000B0000000A09A000A0B00A000000000000000000000000A000000000000000000000009E00000000000000000000000000000000000F0000000000A00000000000000A9A9ADA0000000000000000000000000000000000B00B0A00000B0A0000A0000000000000B09C0CBC00000000000000000000000000A000000000000000000000A00000000000000000000000000000000000F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010500000000000089AD05FE")); - strs.Add(func2(3), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000080540000424D80540000000000007600000028000000C0000000E0000000010004000000000000540000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFB009A00A9009A9AA9A900009AA9ABE9EB0B0BB09A0AB0A9A9B0FA0FA0CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFE9A09A9EBEBFBB0BB0AB09AC9090AB0BCB0BA9E9AA9A90B000009AAB09009BEB0BAD0EB9E9F9B0C0B0FADB0F0BEB0FCBC0BCBFB0F0BBE0B09BA0BBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FFA9DABEBFFFADFFADBF0BEBBAFAF0FBBAB9ADABADBE0AB0BCBFBC090E0A9AFA9BC90BB9AFABEE0BB0FA9ABEBE9B0FBA9AB9A9A0FB09E0BDAFA0DBE9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FABFFFAFAFEABCBAA9F09AF0B9BBCBE9EBE9ADA9A990FAB0000BFA9090B09E0BAF00A9ADAB9BCBE9F0BCF0BE9FA9EB9CA90FBEAF0BFBA9ADBA9ABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FE99A9FAFFFFEBDA9ADBCBFA9BA9EAFACB0B9AF9A9AFAEB0900BB9A0000A9AF0BBCB0B9E9BADAFAB0BABEBBBC9EAA9EBEABBE90B9B0B0BCBE9A9FADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBAFBA9BEBE09ABFEBABAB0F0F0F9DBFBBAFAB0FAF0B090BCBC00090B0B0A0BBE9B0BCA9AF9A9BC9E9FAD00ABAB9FA9CB9C90B0FABFF09ADBFEB00B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBE9ABDEFBDBBFFCAB0F0D0FB0BBA0ABF0FDA9F0A90009A09A0B00000000D0BDA9AFADA9BDBEBFABABBADABFBDA9E0BEB9EBABE9A9EB0FE9AB09FAFBAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B9E9FABADAFEB0BBDE9BABBA9FEDBBF0BFABC0A900BFE0BC0900B090B0B0BFAFE9A9A900A0B0E9CF0C0B0F0CADABF0F0ABBCB0B0BCBEB0A9AFA9A9E9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABA9F9FAF0FCBCAB0BE90EDABBABCBFA090B090FBFEF009A0B00A000F0B00B0BE9EBAF9FBFBBBBABB09FABB0F9AFA9FBCFBCB0E9B9A9FAC9F0BC9F0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBF0DA0A0FBEBABBDEF9AFBBADA9CB0A0BCA00BAF0BFFE9BA9009090B09ACBBAFF0BADB0A0BADACBDE9CA0BC0BAAF0FBAEB00B0B9A0F9EB9ABAFABABBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BA9BFBACB9EDAB0BAF9AE9A9FA90900090B0F0BFBFE000CB0A00009A9B0ADB0BE900A99ADABFBABEA99A0BF0F9AF0FF0BFADA0E9BABBEBC90BC9E0BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9E9AF00FBFEBA9EBBC9A09BCA000A09A9ABCB9BFFEE9AF0B009090BAFBEB9BAF0BAFF9ACB0BFACBDBBE0DBFAF9EB0B0BE909A99B00BF0B0AABCBABDBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BA9AFBCBCBBEBBCABAD000090909009AC90B0AA9FF090B0B00A0BC90F090F9EBCB0AF9ABF0B9BAA9CB0A00FAABCBEBDAFAF0E09BE90FBF9CBB0BCA0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF0FBDA0BABE90CB9B0FA9AB000A00B0A9A9A9F9EBFE0BC00090900BA9BEB0BABCB0FB0BCB0FBEBDBFA9E9BFADBCBA9A0BE90BBB0E9AFA90FA00BE9A9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A0B0EBFBCB9EBBAF0F0BC90B0090000909A9E0BBFEE900B0DA000900FA0B0B0BBE9B0BEB0B0AB0A0F0BBC0A99ABAD0BFF9EB0C009A909EBA9E9F0BCADBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BDBFBB00BE0BAC9AFA9ABFE09A00909A0BCBA9AEBE90AB00A90A9ABFBE9F00FC9AEBC909ADB9EBFB0BC0B09AE9CB0F0A0A90B9EB090FAB0FA9A0FA90ABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0A000CBE9BE99BFA90F090AB00000009090F0BFBFE0B0DA900090BCBA90AB0BEB90BAFADBA0FB0EBEBABEBC9AA9A9ABF90FA009A9EB09E9AFADA9CA9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB9FB9A9AE9BEFAF9A9ABEB9EBCB00000A0B0BE9AFF0FA090B00A90B0FADB009BAE9ADBAB0FFB0FBF09BF00B0D0F0EB00AB09EB0DA90A9AF0B0B0CB00B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0A00EBCB9BEB0BA0F0B09AE90B00B00090A909FFF09009A00090A0F9A9BAB0B0BFADA0D0F0B0BA9A9E00AF0A0BA9BC9E909AB09A09A9CA9ADACA90B0BCFFFF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9B9BB0BE9E9E909F0BCBEB90B9CB00900BB0FAABEE0B9E090B0BDBBAF0E90C9AE90B0BAB09AFDABE9ADB9A909A9E00A90E90D0A09E0B09A9A090A00009BFE000909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0CACBE0BA9A9AB00B0B0BC0BCAB0B0000009AFBE9A9E090A0009ABEFABBAB009BADAF09ABE9ABBDAFBAFA9E9AD090B0A90A0A9CB0900B0DADB0B000900BC90000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB9ADBE9FA9E9EB00F0F9A9E900BCB0B900F90FBEDA9A09090A9A90BC0DB0B09AFB00BCBCB0BCBEB0BDA9E0BC0A0BC090A9090B09A9B00B0A00009000900000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00A9AA9A0BF0B0BFBA90ACB0B0F0B0B00A90ABAFE90ADA0A0090DAFB0BA0BC0AFAC0BCB0BADAB0B0FEBA90B00B0900BCA9CB0A00A0000B09090900000000009000009BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BF0F9FADA0BBFF0E90A99ABCB090B0E9000B9FE90E9009009AFAA9A9A9F0A909BBB0B0BC9A9EBDB0B9E0BCA9000BA009A0090B0909A900A0000000000000000090009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9AB0BBF0F0B0B9EBDAE90B0E0BC9AF0B00E9F0A9A9A090A9A9FAFCBB0B0B00FAF0E9AB0B0BAB0F0BBF0B0A9A909A9090A0000000009090000000000090009000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBE9AF0F09AFAF0A9EA90A90B090B09A90B0BAF090009A0909BE9BA9AFBBC0A90F0B0A9CB0F0DAFABE0000900000000A0A9090A9A900A0000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09A9ADBF0BBE9B0BBE90BBCA909A009A9AC9A0BEBA0F0009A0BEBBE09F0009A90BABE090B0B0BABBCB090B000090009090900A090000900009000000090000000009009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9A9F0A00ABE9B0FA09ABC0B9E0A9F9ADA9A9E9D00C90A9000F0BDA0DA0FBBE9E09F9FA0B0E0BCBCBAD0A009000000000000009000000090000000000000000000900000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9A0B9DA9CB9EB0BDAD0BBC0B09000A90BF0BAA9A9A9009A90BAAFFABBA0A9A9A0A0BDAC9B09A9BE9A909000000000000009000900900000090000000000000000000900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9ADA0A09AB0A0BE0B0A9E0B00B0B0B0A900F09E09000B000B0BFF0B0F9F9BE9A9E9BEA9BA0DA9E09E9000000000000000000000000000000000000000000000900000009BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE09A9BC9A9CBE9E9F0F0B09A9AD00B09C0B0B0BC9AA9A009A9ADABFADAABABCBCB09EB9C009A9A09B0A00000000009000000000000900000000000000000090000000909C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09A9C00A90A09A9A0A0BCBA0D0A0BC9A9A900BE9AC90090BCBFAFABCBADA9BA9A0A9BCAB0F0B090A0090000090900000009000000000090000000009000900000000000BE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFE90A9A90A90B090909A9A0DBA0990B00B9E09F0A9A09A000B0BFDEBE9FBEBEFAD9000B0090A0F0BCB000009000000009000000000000000000000900000000000009000BF0BFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBFFA09000090090000000909A009A0A00B00A90A0F009A09A9ADA0BADBB0A9F09B9A0F0BADB0A990BCB0000900000000000000000000000000009000000000000000000009FE0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA909090009000000000000000009A00909A09BC0BFF09AC090090BFF0FAE0BF9ABBEE0B0A9F00A900A090090900000090000000000000000000000000000000000009000900BF09FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF909090000000000000000000000900090BF009E00B0BA0A90B0A9AFA9ABA9BFABAD00BFF0900BA9DA0F0B0B00000090900000000000000000000000000000000900000000009A9ED0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000090000000000000900000009000000B0B0B0BECBDA0090CB9EBFF0F009CBBAB0BEBE909E0A9009000B00090000000900000000000000000000000000000000000090000900BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00909000000000900000000000000000009009009A09BF0A090A0B0ABBEBEFAFEBBCB9ADAF00A9AF090A9A9E9009000900000000000000000000000000000000000000900000090009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09000000900000000000000000000000000000A9A009FEA9BCA9090BB0FFFFABF0BCBEAB0BFEB09E9A0A90009000009000000000000000000000000000000000000000000090090090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000000000000000090000000009000909AF0DA090E0F0FFFEBEDFA9EBA99AF0BF09ABE09009A9A09090000000000000000000000000000000090000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00009009000000900000000900000000000000009A00BF0BA09A99BBFAABFFBB0BE9BCBA90F0FE090BCA9A0009A000000000000000000000000000090000000000900900000000090D0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9000000000090000000000000000000000000000090A0BC9AD00A000BFBCBCBEF0BAFBCBAB0BABCBAF09009A9A0900900000000000000090000000000000000000000000000000900A9FEFFFFFFFFFFFFFFCBF9FF9FFFFFFFFD99F9FFFFFFFF000900090000000000000900000000000000000000009BEBE90A909E9F0BBFFA9EBC9B0B0BCF09EF0BC9A09A00090000000000000000000000090000000000000000000000090090A99EBFFFFFFFEF9A9BF9FF9F9F0F0BDBFFFB0FB9F09FFFFE00000900000000000000000000000000000000000090BAE900A90BABBAFAFEA9EB0BAAF0FEB00AFBE9A0900909A00000000000000000000000000000000000000000000000000009C0A9FFFFFFFB9DBDFDBFDBFBF9FBDBE999DDB9CB99A990FF090000900000000000000000000000000000000900009FBAF09A09E9E9E90BCB0E9EBDAB0DAF9CAFFE9E0B0A0090909000000000000000000000000000000000000000009000000B0900BFFFE90DB0FBFFDBFDF9FBD9F9BFFABDBFBDBDB0F90900000009090009000900090000000009000000000000A9E90A09F0BFAFAFEBBCB9E9EBF0BAF0AB9BAFA9A0909A00000000000000000000000000000000000000000000000000000000BCBFC9909B0FBDBFFF9FBE9DAF9FDB9DBBDBDBCBF99ADA00000000000000000000000000000000000000000009BEFA09A00BF0BE9A9E0B0A9A9E0B009EF0E0FE9AC90A000900000900000000000000009000000000000000000000000000900B09009ACBF0F9DBDAF9FBDFFBF9ADB9FFBCBDBDBF09F0909090000000000000000000000000000000000000009A9A909AD0B00ADCB0F0900909A9A9E0A90BFFA9EB0A090900090000000090009000000000000000000000000000000009000909009A09909F9FBFFF9F9FF99F9FDF9FB9DBDA9B99DB0B9000000000000000000000000000009000000000000000AF0E90ABCBFBEB0E9A0B00A000900C90000BEF0F9ADA000900000000000000000000000000000090000000000000000000000000090A9F09B9F9BFBFF9BFF9FBBDBDFFB9F9F9FABD9CB0909090000000000000000000000000000000000000909A90A90DA009BCBB0F00F090900B0000B0009AF0AF009A9000000000000000000009000000000000000000900000000000090009009009BFBCBFDBDF9FCB9FBDF9FB9ADF9F9B0D9A9B90000000909009000009009009000000000000009000009E0B0F0A9FAEAB0CB0B000000000900D0009009AF00B000009090000900090090000000000000000000000000090000000000900090BDBC99FBDBFBF9FB9EF9FBFF0F9F0F9ADF9BBD9E9A90900000000000000000000000000000000000000A9A0BCB0ADA009F0EB0009A900B009AC000000000009A0F0090000000000000000000000000009000000000000000000009000000900090B9AFBDBFFDBF9FDBDFF9F9FFDBF9BDB9BD0B09000000900000000000000000000000000009000000900090009009ADA0B90BCB000090900009C0D00000000090B0009000090000000000000000090000000000000000000000000000000090B9CB9DBFF99F9FB9F9B9FFFB9BF9BE9F0BCBD0B9B9090900900000000000000000000000000000000000B0A9A9A9A09A9E0AD0B09009ACA00000090090000009000090000000009000000000000900000000000000000000000000000000090909B9EBDB9FBFFBCFBFFFBDBDFF9EF9F9FDBB9BD0D0B000000009000090000000000000000000000009090090000009A090900A000A9A90909000000C00090000000000000000000090000090000000000009000000900000000000000900900A9DA9F9F9FF0F9BDB9F9BDBEBF9BD9B9E9B9C99A9A09090900000000000000000000000000000090000A00B00B09A9A09A0A9A9090900090000090090900000000009000009000000000900009000000000000000000000900000000000000099A99F9B0F9BF9FDB9F9FFF9F9FFFFBEDBCF9B0F9C9B09A00090000900000009000900000090000000000900090A00090009000000009090B090000000E000000000000000000900900900000000000000900000000000000000000900000000009E9ADBBDF9B9B9F0BF9B9FBF9B99F9F9B9EDBCB909C090900000000000090000000000900000000009009A0009090009000900909A00A0000000900009000000000000900000000090000900009000000000000000000000000000000000909AD9BDB9DB0F9E9F9F9BDF9BDBFDEF9F0FDB9B9B9CB0B9090090900000000000000000000000000000000A000A0000000000000000009090900900C0D09C09000000000000900000000009000900000000000900000000000000000000000000099BDB9EB9F9F9B0B9F9FB0F9F0BB9ADB9B09E9E9A9090A00900000009000000000000900000000000009009090000000000000900090000009A090A00C0000009000090000000009000000000000009009000000000000000000000000090099A9A9E99DB9B9BDBDB9E99F9A9BDBDF9AFDF9B99C9B0090900000900000000000000000000000000090009000000900000000000090000909A000C0D0D0F0909000900000000090000090000000009000000009000000000900000000090000009DB99FB90DADA9B9F9FB9B9F9BDBA9F99A9EDB0B0D9A900900900000000009000000000000000000000000900900000000090000009090009090900CAC0C0000000000000000000000000000000000000000000000000000000000000000009A9A9F990F9B99BD0B9090D0F9FCBD9F0BE9F990F9B0A9CA90000000000000000090000000009000000000000000000000000000090000009000E0C0C9C909000900009000900000000000009000000000000000000000000000900000000000909D9ADAF9AD0BD0BD0BDB9F9A9B90B0DF990BAF090D9009009000000009000000000909000000000000009000000000000000000000090B00F0D009A000C090000000009000009000000000009009000000900000000090000000000000000909A9BDB99099F0B90BD9B0B0BD0F9F9B9ADABD99BDA9A9009000090000000000000000000000000000000000000900900000000090090000900DE900D0D000000090090000000000009000000000000000000000090000000000000009000000BC9BC9B0BDA9090F90B0C9D90B90B09CB99D0B09CB90D0B00909000000000000000000000000000000000000090000000000000000000009ADAD00C000009C00000000000090000090000900000000000000000000000000000000000000000909B0B9C99090B9F9AB9F9B0BBD0B9F9B90B0F0F0B0F0B0909000000000000000000000000000900000000000000000000000000000000900C0DAD090C90C00000000000000009090000000000900000090000900000000000000000000000090B90D9A9ACB0BD0909C90B0BD90BD00A9CBDA999099909000000000090000000000000000900000000000000000000000000000000000000009ECF0E00C09000090090000900000000900900000000900000000000000000000000000000090090F9BC90999D9A9ADA9A90D09A9A9FBD0B909F0AD00BCB09090909000000009000090000000000000000000000000000000000000000000090009C90D0900009000000090000000000000000900090000000000000000900000000000000000009090B0B0B00B90999909A9B09C9090BD0F9A9990B00909A00000000000000000000000000000000000000000000000000000000000000000009E9C00CAC09C00000000000000090000900900000000090009000900000000000900000900000B0B090099C9BD0F0B0F9F990DB9BDA909B90D0F09090A9C9090000000000000000000000000000000000000000000000000000000090000000900C09E9090000090900000900900000000900900900900000000000000000000000000000000990D009BDA9A90B9BDB90B0F9B9ADADB9E9EB9B09ADA990B0000900900000000000000000000000000000000000009000000000000000000000000FC000C0C0090C0A009000000000900000000000000000000000000090000000000900000090090B9090999B9C999CBD99BC9F9BDBDE909DADA99090090090000000090000000000000000000009000000000900000900009000000090090000909C9090090009C0D000000000900000009009090909009000900000000000000000000000090B009BE90F0DB9BE9B9ADF9B9BDBBDBFFF0B9BDAC9A9A090090090000000000000000000000000000000000000000000000000900000000009000C00AC0C000C9009000000000000000000009000000000000000000000000000000000000009A099B099B9B90F99B9F9B9BDBDBDFFF9F0FDADA99A9C900B0000000000000000000000000000000000000900000000000000000009000000000909C9C9A90C9000C0E90090000900009000000009000009000000000000000000000000000090990B0D0BC9F9F99BDF9BDFDB9BFFFBDFFFB099F9AD90B09009009000000000000000000000900900000000000000000000900090000090909000CCAC00C00000CB0D0C00000000009000900000000900000000000000000009000000090009A90E909B999B09BDBDB9F9BBFFDF9FDFBF9FDFCB0F90A9000900000009000000000000000000000000000000000000000900000009090000000090B0C9E90D0D0B0C0CBC900090000000000090090000900900900009009000000000000000009099BD09FBDF9BDB9BDB9FD99BFFFFFFDFFFBFBDB0F99E9A909090000000000000000000000000000000000000000000000000000000909009A000C9F0C0CAC00C09C9C0E090000090009000000000900000000000000000000000000000000909F09A9B09B9F9F9F9B9DBBFFFDBFDBFFFFBDFDEDB9E9909C00000900000090000000000000000000000000000000000000009000000000000090C9CC0C90909C9CE9E0C9C00009000900009009A0000000000000000000000000000000000900B09BDBD9F0F9FB9BDBDBFD9BDBDFFFFF9FDFFBDB0F9BCB0B0090000000000000000000000000000000000000000000000000000009000090900CBCA0F0CAC0CAC90C9CBC9E9000000009000000090090900090000000000000009009000000B9DB09B09B99B9D9F9BDB99BFDBFBFFFFFFFBF9FE9F0F0BC9090009000000000000000000000000000000000000000000000000090000090000909C0DC0F090D090E9CAC0C0C0C900900000009000000000000000000000090000000000000090B09F0DBF0BD0BB99F9BDBD9BBDBDBF0DB99FFFDBFF9BD9B0BC9000000900000000000000000000900000000000009000000000000000000900000FC0FC0C0C0E0C9C0D0F09C9A0000000090000900090000000009000000000000000000009A999B9B9099DB9D9E90BDA9B9D99F9E9FBDFFF9FBFDBFCBADBC9A09000000000000000000000000000000000000000000000000000009000000000C0DEC0DAD009C9CA9E0C0CA0C09000900009000000009000000000000090000000000000909ADAD9E9F9FB0B9B99B909909A9B0999BDBBBDBFF9E9E9BD909B090000000000000000000000000000000090000000000000000900000090000909C9E90FC0E9EC0E9C09C9009C9CAD000A00009000090009000000009000090000000000000BD9B90B9B9B09DBE9DBCBB90F990D9F0F9FDFDBF9FFBF9F9EB9FC9E0000000000000090000000000000000000000000000000900000000000000000BCCDC0F0D0DAD0E9CA0C9C0009CAD0909000090900000000000000000000000000090000D0B09F9DA99BDB999B0999CBB9EBB0B9B9E9BFF9FBDF9FDAD9E9AB099900000000000000000000000000090000000000000000000000000000900000C9ACBCCADEADE0D0AD0AC00D0C0D0A000090000A000000000000000000000000000000090B9F9A9B9F0DB9ADBC9BCB99D099D9F9F9BF9F9FFDFB9EBDBBDBD9FCA0000900000000000000090000000000000000000000000000009000000009090EDCCCBDE0D0C9CAD0CD0BC00E9E0D009A00000909000000000000000000000090000090B9DB9DBDA99B9F9B99BF9B9F0BDA9B09FFFDFFFFFFBDFF9FBCBDBF0B90D0000000000000000000090090000000000000000000000000009000000000CD0BB0CE0FCADAD00F000C0C90C9E0F000900900000000900000000000000000000000BD9EB90B09B9F9F09F9F999D099999999F99FFFFFF9FFFBDB9F9FBC9F9E900000000090000000000000009000000000000000000000000000000000000DACCC9E9C0FC0CAD00DAD09ACBC0D00BC00B00090009000000000000900000000000000B99B9F9BD9F9B9F9BB9F9A9B9BD9BDF99F99FFFFFFFDFF0F09BCBF9CBDA900000000000000000000000000009000000009000000000000000000000090DAD9E9CAD0BCF0DAD0C0C0C90CB0E9C9A000900009000000000000000000000000009BDAD9E9BF0B0BDB9BDD99999D9D9F999DB9DBDFFFFFDFF9F9BFFBDBFBF0F0F090000000000000000000000000000000000000000000000000000000090C0DCC0E0D0EC90CAC0E0DAC90E90C9C0E90900A0900000000000000000000900000099E9B9B99F99BDB9BDB9B99F9990909999099FDFDFFFFFB9FB9F9BDBF0F9F990000000000000000000000090000000090000000000000000000090009000CBC0AD0F0D09ECBCBC9C0DA0D0EDA0BC900A009000009000000000000000000000090B9F9FDBF9BF99DBDA99CB09999B9B09BF99999FFFDFFDFD90B9FFBDF9DBDBE90000000000000000000000000000000000000000000000000000000000009CF09EC0E0C090C9CA0F0CD0E90CDC00E9009000B090000000000090000000000000BDA9F9BDBD9BE999BDF9999900B9F9BFFFF099099DFDFBFBDBDB9FFBFFBDADF0F0900000000000000000000000000000000000000000000000000000000900CDC9E9C90F0E9E0DC0CB0C9CE9A9AD00F00A9000000000000000000000000000909F9F9AF9BFBD9BE9B9909090B9BFBFFFBFFFFFF9D9B9FD90B90BFFDFDBFFFFBF0000000000000000000000000900000000000000000000000000000000000F0C9E9E0AC0C9C0F0909CC9E090C0D00F0090009000000000000000000000000009F99BDF99F9DBAD99CB090B9F9FFFFFBFFFFFFFFF00999BFBD9F9FFFFFFDBDFC9C90000000000000000000090000000000000000000000000009000000900D0CBECCD0D09E0F0C0CAC0BC0F0E9E0BC0900090009090000000000000000000009A9AF9B9BF9BBD9B9B909009BFF9FFFF9FFFFBFFFFF0000999A99BDBFBF9FFFFFFB0A000000009000000090000000000000000000000000000000000900000EDFC9E9AC0DA9C0F0F009C0BC0D009C0BCE9000090000000000000000000000000BDBDBDBF9BFDFBD0F090009BDBF9BFBC0BDBD09B90B909000990BDBDFDFFFFF9FDF99000000000000000000000000000900090009000090090000090000090000FE9EC9E0CCBDCD00DA9CC9E0F0E0FC090090000900009000000000000000000DB99BDB99F9B9DB9090000B090090909990909909D0000009A09F9BFFFBFFDBFFE9E0000000000000000000000000000000000000009000000000000009000DED09CC9E0D0BCCA0AD0CCE9A0D0C9D009E0000090000000000000000000000099A9FBDB9DA9B9FB009000909909B90999B0F9BDEF90999F9A9C9999BF9BDFDBFFF9F090000000000000000000000000000000000000000000000000009A000DAD0FECBC9CADE0BCDCADA90CDCADACACFC90009000090000000000000000000009F909F9FBDBDF9DB90B9F090909099090999099999F9FFFFDB09F0BDBFDFBBF9FDFBDA900009000000009000000090000000000000000000000000900009000C0F00BCACBC0DCCB0D00CE9A0F0CD0D00E0900009000000000000000000000000B9FB99A99B9B9B99E90B9F9BCB9DA9DB9FDBDF9FFFFFFF9FFDB09BDBDBB9FDDBFBEDBD00000000000000000009000009009000000000000000900000900009A9DCFDC9C9C0F0E9CCA0D09CC90CB0F0FC900000000900000000000000000000090F9DBD9BD9F0F9BC9BD9B9DB99F999B9F9BDBFFBFDFFFFFF9A9DB099BDDB9FBFDFFDBCB0000000000000000000000000000090000000000000000900000090CCAD0CA0F0CBC0D0E90DA0CA9ACF0CC0C000090900000009000000000009BF0099BB9B9BFDBB9B9B99B90BC9B99F9DBF9F9BDBF9DF9FFFF9F0F99B9DBBDABFDBDFBFFFE90090000000000000000000000009000000000090000000000900000C9AD0F0DC0F0C9CAD0CA09C90CD00DA9EDE90000000900000000000000000BF000BD0F0F09B9C9F9DA90BD99A9F9B9B99B9DB999BBFFFFDFF9F9F0D0B9DB9D9FBFD9FDBDF900000000000000000000900000000000090000009000900000009CBCDED000F00F0E9CAD0D0E0E9A0F0CC090C00090090000000000000000000909090B99B9BD9BB99A9D9F9B09D09BC99F9DA90F9D09B9FDBDF99A99B99F9DBF9DFBFFFFFBEDA900000009000009000000000000000000000000009000000000C0C0E9EFC90C90C9C0D00A0909C0D0DA9ECE90000000000000000000000000000000BDBD9F9B0D9F9DB9B909BF9BD09B0B9B99F90B9FDFBDFA9F9F9F0DB9B9F9FFBDFFFFDFDB00090000000000000000000900900900000090000000000090090D0D9C9C0AC9ACB0E90CBC9CACADACE9CC900009000000090000000000000000909B99CB9AD9F9F09B9AD09BD9090B999D99CB09B9FFFFDBFDF0BD09BB9F9FBDFFDFFFFDFFED0900000000000000000000000000000000000000000009000000C0F0CADECD0C900D00F00CA909C0D09CB0C909000900000000000000000000000009CBB9F9DB9B99F9D99B909B9B99E99A9B9090D9BD9FFDBDBDB9B99DB9F9DBDFFFFFFFFDBBC00900000000000000009000000900000900000090000009009E9C0FCDA9AC9E0FC0F0CF09CEDA9E0DE0CDA00000000000000009000009000009090F9DFF9B99F9F99B9BD9F909D9F99A99009B090B0B90FBDF9BD90F9BDBDBFFFFFFFFFFFFDE9900000000000000000000000000009000009000000900000000C9C0BCFCD0E9C09E0DA0DE0900C9CA9CB09000090000090000000000000000000090BB99BDBF9F99F9BDA99090B0990900990990BC90099DB9BDB0999F9F9F9FDFFFFFFFFDFBCA0909000000000009000000090090000000000000000090090D0E9CC9CBCAD0E9E0DACDE0DACAD0E9C0C000900000000000000000000000000909A9BD9BDBD9BDFBDBDB9DA9B909B09C90B099CB99F0909B9BC909B9F9B9FBFFFFFFFFFFFFED0900000000009000000000000000000900000009000009009AC0C90C9EBC0DAC9C0F0C9E0F0C9DAD0CADA90000000900000000900000000000000090DBF9F9FBDB9DBDBDB9D09AD909B00D9B0B99F999BDFFD9B9B99F99FFFDFFFFFFFFFFFFDFF00090000000000000000000000900000000000000090000C0DCBCDACDCF9C9ACBC0F0E9C0F0AC0AD0D0C0090009000000000000000000000000009B99B9FBDFBDBF9BDBDBBD990B0999B09D99B99BDFFFFFF0D09DB9F99FFFFFFFFFFFFFFFFCDA90000000000000000000000000009000000000090000909C09C0CDA9E0CA0CD09E0D0CBC0DC9ED0E0F090000900000000000000009000000090909FFF9BDBDBDBDBDB9F9D9A999099BD9B9BDDF9FFFFFFFC9B9F9BDBFFFDFFFFFFFFFFFFFFFB00000900000000000000000000000000000900000009000A9EC9EBCDE9F09C9A0E0DACBC0DA9AC0F0DC00009000000000000000000000000900009BF9BDF9FBDBDBDBDF9F9B9DB099AD9BDBF9FBFFFFFFFFDB9DB9F9BDBDFFFFFFFFFFFFFFD90D0090000900000000009000000000009000000000000000DCDAF0D0F0FCC0AC0D0BC90C9E0CCDAD0E9AD090A00009009000000000000000000009A99F9F9FBDB9BDBDB9FBF9F90B0999BDBD9BBDFFFFFFFF0D9B9FFFFFFFBFFFFFFFFFFFFFFFF00000000000000000000000000009000000000000000009ADADC9EF0FCB0D09E0D0ED0F090B00DADCE0C0A09009000000000000000000000000909F9BFBF9DBDF9F9BDF9D9F9BD990F90BDBD9FBFFFFFFFF9BDF9BDBDF9FDFFFFFFFFFFFFFFCBF000000000000009000000000090000000000009000000000DAFE9EF0FE000C0DAD00E0CAC0DA0D0BCDE909000000000000900000000000000000B0BD9F9FBDB9B9F9F9FBF9BDB9E999BDB9BD99FFFFFFFD9BBBFDFFFBFFFFFFFFFFFFFFFFFBD0900000000000000000000000000009000000000000000009ED0FF0FFAD0C9ADAC0DE9C9C9A0C9CACDA9C000090000000000000000000900900099F9FFF9F9F9F9F9BDBF9DBDBDB99A9D99F9B9FFFFFFFFFFDFDFFBFDFDBDBDFFFFFFFFFFFDF9E00090000000000000000000000000000900000000900900CB0FE0FF0FF90C00D0F00C0A00D0BCADF0CF09090000090000000000000000000009A99F99FBDBDBDBFDB9F9FBDB9BDBD9B0FB9DBDBDFFFFFFFFFFFBFDFBFFFFFFFFFFFFFFFFFFDE9000000000009000000000000000000000000000000000909CFF9FDAFDAC90E9E00DA0D0C9AC09C00F0CE00000090000090000900000000000009A9FFBDF9F9FDFDF9F9F9BDBF9B9BF999DBD9BDBFFFFFFFFFFFDFFFDF9F99FBDFFFFFFFFFFFF0900000000000000090000000909000000000000000090CAC9CAFAFDAFF00C9C9EDAC90CB0C9ACBCFCE90900090000090000000000000000000009F9FDFBF9B9BD9FB9F9F9BD9F9F90BDB99B9DBDFFFFFFFFFDFFFFFF9F9FFBDFFFFFFFFFFFDE90000000000000000000000000000000000000000000009C9EBDCF0BFCB0E9E0E9C0D0E90C9AC9CBC090000900000000000000000900000000099BDBDBBDDBDBDBFD9B9B99F9F9B99F9A99F9F9BFFFFFFFFFFFFFB9F9F9F9BDBFBFDFFFFFFFE9000000009090000000000900000000000000000009090DE9ECD0EBCFCBFD00D0D0ADAD00DA0D0E9CADE90000000000000000000000000090090009BDBFDBBDBDBDB9FDDBDB99BF9DF9F9DB999F9BFFFFFFFFFFDEDF0F9FBFFFDFDFFFFFFFF9F000000090000000000000000900000900000000000000000C90BC9CDABCF0CF0ACD0C0ECD0DAC9CE9C0000900000090000009000000000000000090BBDBFDBF9F9BDA9BBDA9F099A9B09B99F9F9FDFFFFFFFFFCB9B9F9F9DFFFFBFFFFFBFFFE9090090000000000000009000000900000000000090000090FCDCBCBCDCBC090DC9ADAD09AC0C9E0DCBDE900009000000000000000000000000000009FFBDBDBBDBDB9D0909D09E9D99F9D9F9BDB9BFFFFFFF99BDBC9090B90B9BDFFDFFFFFFD000000000000000000000000000000000000090000009000C0000C0C9E9EFCAC0A0CC0CBCC9E9E0D0AC00000000000000000000000000000000000909B9F9B9BDB9BD9A9A990B0990B0B9AB9BDBDFFFFFFDD0BC990A90B090B9FEFF9FBFDFA9000000000000000000000000000000000000000000000000090DAD0DAD0FC99C9C9CB0F0C0BC0C0DACD0FC9090000000090000000000000000900000909FCBF9F90F9A99D99A9090A90909D0D9BDBF9FFFFEB909A09909C99F9F9F9FFFDBFBDB00090000000000090000000000900000000000000900000900C0C00CDAC9EF0CAC00C90DAC0BCBC0DACD00E000900090000090000000900000000000090BBDBCBFB9D9B0B09099A9909090B9B9DBDBFFFFFD0E909000909A09B0FDFBDEBCBDBC09000000900000000000000090000000000000000000000000900DA0CDAD0FF0D09E9CA0D0D0D0DE0D9ADF090000900000000000000000000000000090099B9B99DB9A9D090B009000A909099FBFBDFFFFDA9909090B9A999CDFBF0F9999B9A0900000000000000000009000000000000000000000009000000C90CD00DE9EC0CAC9C0CDACACACA0D0ECC000009000000000000000000000000000000090B9F0B0B0BD909BC90BD09990B090F99BDFFFFDF090B009090000AFB0D099A09ADBC900000000000000000000000000900000000009000000000000000C90EDE9ED0F0D00ADA0C9C9C9CDAC9E9ED09A0000090000000000000000000000000000909D090900B0F00090BFA00909A99BFDBFFFFE99F00090F0009090DF000099F9B0B0000090000000090000000000000009090000000900000000909C90CC9C0DEBD0CAC9C0D09AC0FCBCDAC9E9CA0D09000000090009000000000090000090090B0B90909090B0900009DF00909099BBDBFFF9E099090BC9000000A9009B090F0D0900000000000000000900000900000000009000000009090C0000C9A0CBCBCDCAD09C09A0E09E00C0ADF0CCB0DA000900909000000000000000000000000000990B0B000BC0000F0BE009A909A9F9FFFFFF99A09009A00909090009E909B90B000000000000000000000000000000000000009000090000C90F0D0C0D0CDCBE09C0E0BC0D0D0C9EDADC0EDBCDE090B0C9A000000000000000000000000000909AD090900900909A090990090B9DBBDBFFF9E009009000000000009E909E9CB009000000000009000000000000009090A90900000900000DA0C0C000D0CBCBED0CBC9C0BC0CA9E090DCAFDAC0E9E000AB0C0000000000000000000000000000909A90099C000000900000900099B9FFBF9FF90909009009000009FE90A99A90900090000000000000000000900000009000000000000090009009E9C0E9CBC9FE9CAC9C0DA9C09CECA9C0EDBE9C9F0DDEB090000000000000000000000000000909ADB0B09090000099B009090F9B9F9FFBDF9CA090090009C9FBD00990BCB009000000090000000000009000900000009009009000000090C9C00C9C0C9CF0F90D0DA9CADC0FCA90DCBC9E0DE9ECBFAFC000090000000000000000000000000090909009BDAD9CB9A0009A09B99FFBFF9F0B9B0900909B0B9A0009BCBF0909000000000000000000000000000009000000000900090000C00009C000DACBCFCCACAC0CE9CAFC09CFCAC9ECDE9ECBDAFC090A000000090000000000000900000909A90B09009A0B000909009B09FB99F9FF9F00900900000900909A09009000000000000000000000009000000000009000900000900909090D0C090D0C9CBCB0D0DAD09CAD0ADE009CBED0F0EDBEFFF900D9C90000000000000000000000000090990D9E0909900900909909DB99FBFF9F90DB0090909090090B09090900000000090000000090000000000090000000900090000000C00C000900E0DACF0FE0E9C0ADAD0FCFADEDE9C9ADAF9EDFBEFEF0A9A009000000000000000000000000000A9A990B000990900000B090F99F9B9E9B0900000009090090000000000000000000009000000900000000000090000000009009090D09C0C0AD0D0D0DE9FC9CADCC00E0F0DADACADEFFDEFBFAFFBDADFED0000000000000000000000009009099090A9090900000900009FB9BF9FFF9F9DAD000000000090909000000090000000000000000000000090000090009090900000000E0C00909C000C0F0DE99CAD00BCF0D0FEF0E9DEBEBEBFEFFFFFEDFADA09A09000000000000000000000000000909090000090000999B999F9FBF9DA9B99A90900000000000000000000009000090000000000009000090000900000000000009C909C00C09CF0F0DE9EE9C0FCC90DAD0D0ED0E9FDFFFFBFFFEFFADFAD009000000090000000000000000909B0009000900009090BE9DADB9F9F9FB9F0F09000090090000000000000000000000000090009009000000000B00900090090009C000C00D090C00D0CF0FFCBED0BCE0C0ADADBEDE0CBEFFEFFEFFBFFEBDA0009009000000000000000000000909B9A09000090CA9C9D9B9B9F9FBDF9F9DB9F9BD9F090090000000000000000009000000000000000000900D00D00A90000009009CD09C00C0C9C0C9E0F0FADCBEC90DADC0CAC9ADCBCBFBFFFFFFEFFBFE0D000A900000000000000000000000909C99A9DBDA999B9FB9FDF9BDBDBFF9BBDB9E90B00090000000000900900000000000000000000000000C9A9FA9ED009090000C0A00C09C00B00BCE9CDADDFAFC9EDE0C9E9C9EDCBCFDFEFFFFBFFFFEFE9000900000000000000009000009090B9B9B9DB9BF9FBDFB9DB9B9FBFFFF9FFDBDF9B9009000900900000000000000000009000000000009000FADFCBDE90F000090090D0D00C090C0DC09CFADFEADBFE9E9CBC0E9E9EADC9AFFFEFFEFFFFFF9E90009A090000000000000000000009099ADB09F99BF9FBDFFBFDF9F9F9FFF9BF0B9FC9009000000090000000000000000000009000000000900DEBFEFBEF0DCB0000C0000D090C09C00FCB0DFA9DECBFEBEDCBC90C0DCACFC9FFFFFFFFEBFEFEFE9009000000000000000000009090B0D9BDBDBF9DBF9FB9BD9FBFBF9FB9FF9F9F09B00000000000000000000000000000009000000090000090DFBFFE9EDACC9CA909C000C090C00D00DCF0DFCADBF0FFFABC0EDADA9CBCBEBFFFFFFFFFFFBFC9000009009000000000000000000909B90B9B99FBD9FBDFFBFBDBDBDBCB9DA9BDB0009000000000000000000009009000000000000000000000FAFFFBFDAD0F0C9C0C09C900C09CDACD0E9EBC9C9ECFFF0FCDE90CC9EFC9EDFEFFEFFEFFFFFCB000909A00000090000000900000909B09F9FF9FB9FBDBDB99F9FDFFBDBD9A9D090909000000000000000000000000009000000000900009000DBDFAFCFADAD0C9C0C90C000D09C000DAC9CBCFCBCF9E9EF0FA9EDEBCC0BCDADBFFFFFFFFFEFBC0900000000000000090000000090909DA9B99B9DBDFBDBDBF9F9B9BDBDBC9B09A90000009009000000900009000000000000000900009000090FAFFBF0FC0C9CAC90C090D000CA0DC0DADEDF0EDACBCF9EFDECBC9CBDCCADCADFBFFFFFEFFFEF00009009000000000000000000009A999F0F9FBBDB9FB9BDB9F9F9CB9A9B00909090000000000000900000000000000000000900000000C0000DFFFFFF0FDE0DC0CB0C000D0D0D00F0CD0F0FFFADFCF0F9FAFBCFACCADADADCFAFFFEFBFFFFFF0F09009000900000000000000000009A99B9B0DDBDBDBDBF9DB9EB99F9D0090B000000000000000000000000000000900900000009000900909EBFFEBCF0C0D009C0C90D000C00C9C9CAD0F0FFFFAFBFEF0FFCF0CDADAD0C0DADFEFFFFFBEFBEF0000000000000900000000000090909DA9DBDBBB9B9F9F99BBD99DB09B0909009090090000000000009000000090000000000000009000000CBFFFBDF0DAD0E9C009C00C0D00D0C0CADCF0FFFBFFFEFBFFEBE9EF0D0DE0F9EDADBFFFEFFFFFFDF0909009000000000000000090009A9BDB9F9F9DBDBDB9DBC99A9B0F09A000900000000000000900000000090000000000090090000009000BDFFFFEBEDC0D0C09C00D09E09E0DAD0DADADF0FEFFFFFEFBDF9E9EBCE0DCCC00DECBFFFFFFFFFAFC0A090000000000000000000000090090B9B9BBDB9BDBB9B9BD0990909090090000000000090000000000000000090000000000000000090CBFFFFFCBCBC0D0C09C00E09C0D00D0E0D0F0FFFFFEBFFDFEEBEFFDEDBDADA9FCAD9FCBFFEFFEFFF090000000000000000900000000909B9BDBDBC9B9F9BD0F9F9A9F09A900090009000900000000090000000000000000090000009009000009EFFFFFBCBCCBC0BCC09C9C00D0CD0C9DE9CF0FFFBFFDAFADBDFBFAFACECADCC0D0ECBEFFBFFFFADAC090009000000000000000009009B0D099B99BDB9BE9B9B0D9900900909090000000000000000000000000009000000000000000B009CC9FFFFEFBCFCC90C9C0A9C000CD00F00FCE0DE9FC9EFCBEDADAFAFEFFFFBDBDADADE9C9CD0FFFFFFFEF9C00900000000000000000000090099BCBDBBDBDAD99BC99A009B09000000000000000000000000000090000000900000090009000000BCFBFFBFEF9E9ED0C0D0C09CD0A9C0CD0D0DE9EFBE9EBC9EDEDFFFBFFFFFEFEDADADE9E0FC9EFBEFFFAFBC00000000000000000000000090A09B09C9B9B9BBD9BC999A090090900090000000000000000000000000000000900000000000900009EFFFFFBFE9C00D0C0C9C00AD0C9C9ACADA9E9CFCFC9EF0FBFAFFFEBFEFFBFFFFFE9EDBCBCBDFFFFBFFCA9000009000000000000000090999009B9BC9BD0D0B90B00900090000900009000090090009000900000090000000900000909000900CBFFFFFFCBEDED0E90D0AD0D0C9CACD0DCDE9EFB0F0FE9FBEFFFAFFFFFBFFFAFFAFFFBEDF0FEFBFEFEDA90090000000000000000090000000A990D09BD9B9B9A900B09090090000000009000000000000000000000000000000000900000000DBFFFFFFEBF0D00D0CC00D0C0C9E0C9C9E9E9EDBCF0F9FFEFFFBFFFFFFFFEFFFFFFFBEFFBEFDBEFFFFBFFC0000000000009000000000009090900B9B099A909C9090900000000090090000000000000000000900900009009000900000000900ADBFFFFFFFCF0CF0D09AD0D0F0C9C9CADCF0DEAFFFFEFAF9FAFEFFFFFFFFFFFFFFFFFFFFFFBEFFBFFFEFBF090000090000000000000000000909009CB0D9BDA99A090090090090000000000000000900000000000090000000000000000900090EFFFFFFFBF0F0C0CC0C0C0C0D0C9E9C0E9EBDF0FFAFBFFEFFFBFFEFBEFFFFBFEFFEFFFEFFFFBFFEFFFBCF00090000000000000000000009000090B099A9C9900900090090000000000009000900000009000000000090090090009000900090DBFFFFFFFFFE9E9CB0D0DAD0D0E9C0C9E9C9CE9FFFDFFCFBFFFFFFFFFFFFFEFFFBFFFFBFFEFFFEFFFBFCFB0900000000000000000000000000090090B090B09A9009000000000090000000000000000000090009000000000000900090000B0EFFFFFFFFFFE9CD0D0C0C0D0E0C9C0CDADCFEFBFFAAF0FBEFFAFFFFFFFFFBFFFFFFFFFFFFFFFFFFFBFEFBFC0A0900000900000000000009000900900909A90B00900090090009000090000000000900000000000000900009000A0090090AD0FDBFFFFFFFFFFFE0C0C9CBC00D0D0D0F0CDA0DADADFFBFEFFBFFFFEBFFFBFFFFFFFFFFFFFFBFFBFFFFFFFEBF09000009000090000000000000000000900090909000900000000000000090009000000090000000000000000009090000000DADAFFFFFFFFFFFFF9F0F0C0C9C90C0CAD0DACDE9CFFAFFEFFBFEFFFFFFFEFFEFFFFBFEFBFFEFFFFEFFFFFFFFFC90090900000000090009000000000900009000090909000900090000000000000000000000090090000000900000000009009AFFFFFFFFFFFFFFFFECD0C9C90CAC9E9C0C0D0F0FBCBDFFFBFFFFFFFBFFFFFFFBFEFFFFFEFBFFEFFFFFEFBFAFCBC0B0000000000000000000000000000000009090000000000000009000000000000000000000000090900000909AC9090009EFFFBFFFFFFFFFFFFE9F00DAC0C9C9C0C0D0F0F0DECBFFAFFFEFFFBFEFFFFFBFFFFBFFFFFFFFFFFBFFFBFFFFFFBE9000B00000900000000000900000000909000000090009000090000000000000000900009000000000000900000900009000BFFFFFFFFFFFFFFFFFC0FC0D0D0C0C9C9CAD0CCFADBFCBFFFFFFFFFFFFFEBFFFFFFFFFFFBFFFFBFFFFFFFFFFFEFF0900090000000000000000000000000000000009000000000000000000000009000000000000009000000000900009000090BDAFFFFFFFFFFFFFFBFC0D0C0CB0CBC0E9C0DA9CDACBFCFFFBFFBEFFBFFFFFEFBEFFFFAFFFFFEFFFFFEFFFAFFBDAC009000900000090000000000009000000000000009000009000000900000900000000900009000000000009009000009000CBFFFFFFFFFFFFFFFEDAD0F0D0C0D0C9C0D0EDCB0FDADBFFFFFFFFFFFFFFFFFFFFFBFFFFFEFBFFFEBFFFFFFFEFFE90900090000000000000000000000000000000000000000000000000000000000000000000000000090009000AC0090B000DBFFFFFFFFFFFFFFFADAD0C0C0C0D0C9C0DAC9CADEDAFFFAFFFAFFFBFEFBFFBFFFFFEFFFFFFFFFFFFFFFFAFFFFFAD00009A00000000000000000000000000000090000000009000000000000000000009000000000009000000090909A000000BCBFFFFFFFFFFFFFFF0DC0D0DAD0CB0CBC0D0E9DCB0FDADFFFFFFFFFFFFFFEFFFFFFFFFFFBFFFFFFFFFBFFFFFFFFEFC00090B09090000000900000000000000000009000000000000900000900000900000009000090000900000000009090900BFFFFFFFFFFFFFFEFF0DAC9C0C9CC9C0D0C9CCADEDAFFAFFFFFFBEFFBFFFFFFEBFFFFBEFFFFFFEBFFFFFFFFEFFFF0B0900000000009000000000900000000000000000900000000000000000090000000009009000000000909000909000000DFFFFFFFFFFFFFFFFBCF0C9E0D0E09C0D0F0E9AD0F0FCBDFFFFFFFFFFFFFFBFFFFFBFFFFFFEFBFFFFFEFFBFFBFFF0FC000909000000000000000000000000000000000000000000000000000000000000000000000000900000009000000B09FBFFFFFFFFFFFFFFFFDE9ED0C9C0C9C0F0C0C9CDCF0FCBFFAFBEFFFFFFFEFFFFFFFFFFFFFBFFFFFFFFFFFFEFFFFEFFBDE9000009000000000000000000000000900000000009000000000090000000009009000000900000000000000009000AFFFFFFFFFFFFFFFFFEF0CD0C9C0D0C0D0C9C9CE0F0FCBF0FFFFFFBFFFBFFFFFEFFFFEFFFFFFFFFFFFFFBFFFFFFFBFEFBCA9090000900000000000000000000900000900000000000000090000900009000000009000000009000B0090900009FFFFFFFFFFFFFFFFFFFBF0ADAC9E0DAC0DAC9E90F0F0FCFF0FFFFFFEFFEFFBFFFBFFFFFBEFFFFFFEBFEFFFFFBFFFFFFBCF9C0A09000000009009000000009000000000009000000090090000000000900000900000000000000900000000099FFFFFFFFFFFFFFFFFFFFFCFD0C9C0D0C9C0D0C0CDC9CF9ADAFFFFFFFFFFFFFFFFFFFBFFFFFBEFBFFFFFFFFFFFFEFFFFBEFBCA909000000900000009000000000000000000000000000000000000000000000000900000009009000909009090FFFFFFFFFFFFFFFFFFFFFEBC0C9CAD0C9C0F0C9CBCADEBCFFFFBFFFBFFBFFBFFFBFFFEFFFFFFFFEFFFFFBFFEFFFFFBEFFFFCF90C009090000000000000000000000000000000000000000009000000900009009000009090090000000000000BFFFFFFFFFFFFFFFFFFFFFBCBCBC9C0D0E9C0D0E9C9DE9CFBCBCFFBEFFFFFFFEFFEFFFFFFBFFFFFFFBFFFFFFBFFFFFFFFFFBFAFB0900000009009000000900000000000900000000090000000000000000000000000900000000009000090909FFFFFFFFFFFFFFFFFFFFFFDFC9C0C9C0D0C9C0D0CAC0DE9CFBFBFFFFFFFEFFFFBFFFBFFBFEFFBFFFFFFFEFFFFFFBFFFFFAFFFFDE9E0909000000000000000000009000000000090900009000000000000090000009000000900900009090000FFFFFFFFFFFFFFFFFFFFFFFFADE9CBC0D00D0E9C9C9CFA9EF0FCFFFFFFBFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFEFFEBFFFEFBEBE09000090000000900000090000000000009000000000000009009000000000000000900000009A9000000FBFFFFFFFFFFFFFFFFFFFFFEBCD0C9C0DACDAC9C0E9ED0DCF0FBFFAFFFFFFFFBFFFFBFEFFFFFFFFFFFFEFFFBFFAFFFFFFFFFFFFFFDBDA09000009000000009000000009000000000000000000000000000000000900009000909090000000090FFFFFFFFFFFFFFFFFFFFFFFDFCADAC9C0D00D0C9C9CCBCEB0FEDADFFFFFFFBFFFFEFFFFFFBFFBFFFFEFFFBFFFFFFFFFFFFFFFFBEFEFADBC09000009000900000000000000090000000000000000000000000000000090000000000C90C9C90CBFFFFFFFFFFFFFFFFFFFFFFFBE9D0D0CBC0D0C9CAD0D0C9CDE9FBFBFFFBEFFFFEFFFFFFFBFEFFFFFFFFBFFFFEFFFFFBFFBFEFBFFFBFBDBCA9000000000000900000000000000000000900090000900000009000900000000090000B000B0A00BFFFFFFFFFFFFFFFFFFFFFFFFEFCED0E9C0DAD0E9C0F0ADE9ADE9EDEFFFFFFEFFFFBFFFFFFFFFEFFFBFFFFBFFFBFFFFFEFFFFFEFFFFFFEFE9009000000000000090090000000000900000000000000900000000000000000900009000BC0009FFFFFFFFFFFFFFFFFFFFFFFFFFF9E90C9C0D0C0C9C0D0CDC9EDE9EFBFBFFFFBFFFFFFFFEBFFFFFBFFFEFFFFEFFFFFEFFFFFFFBFFFEBFEFBF9EF0090000900000000000909090900000000000000000000000000000000900000090090009090AFFFFFFFFFFFFFFFFFFFFFFFFFFFE9CF0C9E0C9C9C0DAC9CBC9E9FF0FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFBFFFBFCFF9EDA0090000000900000000000000000000000000090000000000000009000090000000090000DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9CD0C9C0E9CBC0D0E9CFCBC0FFBFFFFFFFFFBFFFFBFFFFAFFFFFFFFFBFFFFFFFFFFFBFFEFFFFFFFFFFBEFFAD090000009000000090000000900090000090000000009009000090000000000909000090FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCF0E9C0D0D0C0D0C9CCBCBCFF0FCBFFFBEFFFFFFEFFFFFFFFFBFEBFFFEFFFFEFBFFFEFFBFFFFFFFEFFAFFDBCF0C000000000000900000090000000090000000000000000000000000090009000009090CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF0C9CAD0E0D0D0ADACBC9CBF0FBFFFFFFFFBEFFFFFFFEFFFFFFFFFFBFFFFBFFFFFFFFFFFFFFEFBFFBFFFBEFBFA909090000090000009000000000000000000000090000000090000000000000090000BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FD00D0C9C0DACD0C9C0FED0FDE9EBFFFFFFFFFBFFFBFFBFFFFFFFFFFFFFFFFFFFFBFFFFFFBFFFFFFFFFFFBCFCBCA000000000000900900900090000000000000000000000000000900090090000090CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFC0CF0C9C0D0C90C9CADD09EF0FBFFFFFFFFFFFFFFFFFFFFFFAFFFFFFFBFFFFFFFEFFFFEFFFFFFFFFFEBFFEFFBFCB09090000000000000A000900009000009000000000009000009000000000090900BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9F0C9E0D00F0CDAC9D0EDE9CFADE9FFFFFBFFBFFFFFFFFFFFFFFFFFFEFFFEFFFFFFFFFFFFFFFFEFFFFFEFFBFFCBC9C0009000090009090900000000009000000000090000000000000900909000ACBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9E0C9C0DACD0CF00DACE9CBCBE9FBFFFFFFFFFFFEFFFFFFEFFFFFEFBFFFFFFFBFFFFFFFFFBEFFBFFBFFFFBFFEBFFFFBE9009000000000000B00900000000000000900000000009000900000000909BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAED0DAC90C90C90CD0C9DE9CF0DFCFBFFFFEFFFEFFFFFFBFFBFFFFFFFFFFFFBFEFFBFEFBFFFFFFFFFFFFFFFFFFFEBCBCBCBC0000000090090000009000000000900000000900900900E0009000000CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBCD0D0ED0CBCC90E9CA0DE9EFAFBDEFFFBFFFBFFBFFBEFFFFFFFFBFFFBFFFFFFFFFFFFFFFFFBFFFFFEFBFFEBFFBFFFFFBE9AD0900900A9009090000090000000000000000000000090900009000DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEDADE0D00D0C90E9C0DCDE9E9CDBCFBFFFFFFFFFFFFFFFFFFFFEFFFFFFFFBFFFFFFFFFFFFFFFFFEFFFFFEFFFFFFFFFBFBFFFF0B009A0990C9AC00090000090000090090090009090000009000C9FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDAD0C9C0DE0D0C9C0DA9E9CBDEBEFBFFFEFFBFFFFFFFFFFFFFFBFFFEBFFEFFFFBFFFFFFFEBFFFFFFFBFFFFFFFFFFAFFFFFBFBFEBC09FACB9E9BC9000900009090000000000900000909000090B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBC9CBC09C0F0C0F0CD0DE9E9F9EDAFFFFFFFEBFFEBFFFBFFFFFFFFFFFFFFFEFFFEFFFFFFFFFFFBFFFFFFBFFFFFFBFFBFFFFFBFB9A9DACB9EBFA9E0C0900000000000900000900000090090CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9E0C9CC9C0D0D0DACF0DE9ECFBFFFFFBFFFFFFFFFFFFFEFFFFFBFFFFBFFFFFFFBFFFBFFFEBFFFFFEFFFEFFEBFFFFBFFFFBFFFFEDABDBFEFDADE9FBCA9A909009090009000009000000F0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FC9C9E09C09CBC0D0D0DADE9BCF0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFEFBFFFBFFFFFBFBFDE9FBFBFFBFFCBDAC00A09000000000090009090F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9E0D0C9EC9C0C0F0CBCBCF0FCFBFFFFFFEBFFFFFBFFBFFFBFFAFFFBFFFEFFFFFFFFFEFFFFFFFEFFBFFFFFFFFFFBFFFBFFFFFBFFFFAFBEFFFEDAFEBFFEDBF09C0009A90900000000ACBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC0D9E0D009CAD0D0C9CE9E9EDBBCFBFFFFFFFFFAFFFFEFFFFFFFFFFEFBFFFFFFFFFFBFFFFFFFFBFFFFFFFFFFFFFFFBFFFFBFFFFFBFFFFBFBFBFDBDFAFBE9EF0BDAD00C0AD09000D09FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE0D0CDCC9C0DAD0F0DCDE9ECFBDEFFFBFFFBFFFFFFFFBFFFFFFFFFFFFFBFEBFFEFFFFFAFFFFFFFEFFFEFFFFFEFBFFBFFFFFFFBFFBFBFFFEFFAFFBFFFFFF0FCADAF0BFCAACC99AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0BD0C9A009C09C0D0CDADA9E9F0FBFBFFFFFFFFFFFBFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFBFFFFFFFBFFBFFFBFFFFFFEFBFBFBFFAFFFBEF0FFADBFCBFCBFDFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FCCCBCDCFC0BCC9CADADADCFDAFDEFFFFFFFEFFBFFEFFFFEFBFFFFFFFFBFFFFFFBFFFBFFFFFFEFFBFFFFFFFEFFBFBFFFFFFBFFFFBFBFBFFEFFEBFFFBFFBFFBCFBCEBDEBCFAFEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A9C00000DC9AC0D0C9CFADADEBDBFFFBFFFFFFFFFFFFBFFFFFEFFFFEFFFBFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFBFBFFFFFFFFFFFFFFBFBFFFFBFFFFFFADBCFBDEBDFBFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9FCD0DEDCD00CC9CBCBCF0DCBCBDEBFFFFFFFBFFFFBFFFFFFFFFBFFFBFFFFEFFFEFFFFFFFBEFFFFFEFFFEFFFFFFEFFFFFFBFFBFBFFFFBFBFFFFBFFFFFFFFEFFEBEDEBCAFCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E9E0909AC909C90CD0CF0BCBDEBDEBFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFBFFFFFFBFFFFBFFFBFFFFFBFFBFFFFFFFFFBFBFFFFFFFFFFFFFFFFFBE9E9EBCBFDBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F9C0DCCCC9ECCACC9ACF9EDEDE9EBFFFFFBFFFBFFFFFFBFFBFFFFFFFFFFFBFFBFFBFFFFFFFFFFFFFFFFFFFFFFFFFBFFBFFFFFFFFFFFFFFFFFFFFFFFFFFAFE9EDBCF9EDAFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE9C00B09C909C9BCD90CF09E9FDFBFFFFEFFFFEFBFEFFEFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFFEFBFFFBFBFBFBFFFFFFFFFFFFFFFFFFDBDE9ECBCE9EDADEFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD0FCDCC0CCD0CC00ECF0CFCBCBE9FFFFFFFFFFFFFFFFFFFFFEFFBFFBFEFFFEFFFEFFFEFFEBFFEBFFEFBFEBFFFFBFFFBFFFFFFFFFBFFFFFFFFFFFFFEFBEF0FCBDE9FCBCFBFFEFBEFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBECF00090B09A090DD09CF9CBCFE9FEBFFFBFFBFFFFFFBFFBFFBFFFFFFFFBFFBFFBFFBFFBFFFFFFFFBFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFBFBCF9EDADA0F0ADA9E9ADBEDBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED90DCFCCCCCCDECCACDE9CADCB9EDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFBFFFFBFBFBFBFFFFFFFFFFFFBFEFFBECB0DCEDCEDCEDCEFCE9EDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0EC0009090900909CBC0CED0FCFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFFFFFFFFFFFFFFFFFFBFFBFBEDBFCFAD9E9DAD9E9DADBC9ECBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DEDCCDCCCDCCD0DCBDBDADADADEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE9E9CAC9E0DAC9E0DAC9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0CA900B00B00B00E00C0C0DADADBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEFDEFDEFDEFDFFFFFFFFFFFFFFF000000000000000000000105000000000000A9AD05FE")); - strs.Add(func2(4), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D20540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FDB9BFBFFBFB9FBDBBBFDBF9FBFBFBFBFBFBDBFBDBFBBFBFBFFD0000000000000000000000000000000000000000000000000000000000000000BBDBF9BDBF9BB9BFB9FBFB9FB9BBFBBBBFBBFB9F9B9FB9BF9BF9BFBBFBBFBDBF9FBDBF9F9BDBFBFBF9FBB9BDBB9BBF9BBFBFBFBFBFBFBFBFBFBFBFBFFBFBFBBA00000000000000000000000000000000000000000000000000000000000000009BFB9FBB9BBDBFB9BFB9BFFBDBF9BDBDBBDBBFFBFBFBFFBBFFBBF9F9BDB9BBFBBFBBFBFBFBBFFB9F9BB9FBFBB9FBDBFBFBFBF9FBFBDBF9BFBFBFBFBF9FFBFBD00000000000000000000000000000000000000000000000000000000000000000BFB9FBB9FBDBB9BBFBDBF9BBBFBBFBBB9FBBDBB9BFBF9BBDBB9FBFBBFBFBFF9BDB9FB9BDB9F9FBFBBFBFBDB9FB9BB9BFBF9FBFBDBFBFBFBF9FBFBFBFBFBF9FB000000000000000000000000000000000000000000000000000000000000000009BFFBBDBB9B9FBDBDBBFBBF9FBDF9BDBFBDFBBFBF9BFBFFBFBFBDBFF9BFB9BBFBFB9FBFBBFBBF9BDB9FBBBFBBDBDBF9BDBFBFBFBFBFBFBFBFBFBDBFBFBFBFBF0000000000000000000000000000000000000000000000000000000000000000009BBF9BDBF9B9FBBBDB9F9BF9BBBFBB9BBBBF9BFBFB9BB9FBDBFBB9BFB9FBF9BDBFB9F9F9BDBFBFBBFBDBFB9FBBB9BBFBBBDBFBFBDBF9FBFBF9FBFBFBFBFFB0000000000000000000000000000000000000000000000000000000000000000000BDB9FBB9BBFB9BDBBBFBBFBFBDB9BDBF9F9BFF9FBDBFFBFBBFBDBFB9FBBDBFBBB9BFBBBBFBBFB9BDB9BF9BFB9F9FBF9BFFBFBDBFBFBFBDBFBFBFBFBFFBF9BF0000000000000000000000000000000000000000000000000000000000000000009BBFBB9FBDB9BFBBBDB9F9B9FBBBFBB9FBBF9BBBFBFB9BB9F9BBFB9FBBDBBBDBDBFB9FBDB9FFBFBBFBFBFB9FBBBB9BBF9BFBFBFBFBFBFBFBFBFBFBDFBFBFF90000000000000000000000000000000000000000000000000000000000000000000BF9BDB9BB9FB9F9FBBFBFBFBDF9B9FBBF9BBFBF9B9FBFBFBF9F9FBBDBBF9FBFBF9FBDBBFB9FDB9F9B9F9FBBDBDBF9FBFBDBBFBDBF9FBF9FBFBFBFBFBFBBBE00000000000000000000000000000000000000000000000000000000000000000009BFBBFBDBB9FBBB9F9B9BDBBBBBDB9F9BF9FBDBFBFBB9F9BBFBB9FBBDBBF9B9BBB9BBDB9FBFBBFBFBFBBBDBFBBB9BB9BFBF9BBFBFBFBFBFBDBFBFBFFBDFF90000000000000000000000000000000000000000000000000000000000000000000BDBDB90B9FBB9F9FBBFBFBF9F9FBBFBBFBBFBBF9F9F9FBFBDBDBFB9FBBDBBFBF9FBF9BAF9BFBDB9BDB9BDBFB9BDBBDBFBFBFFFBFBFBFBFBFBFBDBFBFBFB9A00000000000000000000000000000000000000000000000000000000000000000009BBBBBFBF9B9FBBB9F9F9B9FBBB9F9BDB9F9BDBBBBBFBB9FBBBFB9FBBDBBDBB9EBB9FBF9BFFBBFBFBFBFBB9BFBBF9BB9FBDBBBDBFBDBF9FBFBFBFBFBFBFF000000000000000000000000000000000000000000000000000000000000000000000BDBDB9B0BFB9F9FBBBBFBFBDBDBBBFBBFBBFBDBDBDBDBF9F9F9FBBDBBDBBDBF9F9E9B9FA9FDB9F9B9F9FBFB9F9BF9FB9BBFFBFBDBFBFBFBFBFBFBFBFBBF0000000000000000000000000000000000000000000000000000000000000000000009BBBDBDB9BDBBB9F9BDBB9BB9BDB9BBDBDB9BBBBFBBB9BBBFBB9FBBDBB9FB9BBBBBF0B9FBFBBFBBFBFBBDB9FBBF9B9BFFFB9FBFBFBFBFBFBDBFBF9FBDF9A000000000000000000000000000000000000000000000000000000000000000000000BDBBBB9FB9BDBFBBFBBDBF9F9BBFBDBBBBFBDBDB9F9FBDB9BDBB9FBF9FB9F9F9E9BBFA00F9FB9F9FB9FBBFBFDBBBFB9B9BFBBFBF9FBDBFBFBFBFBFBFBB0000000000000000000000000090BCBC9F0A9E000000000000000000000000000000009BF9F0FB9BFB9B9F9BDBB9B9BBF9BBFBDFBDBBB9FBFB9BBF9AF9FAB9AB9FAB0B9FBC0000FB9FFBB9FB9F9BDBB9F9BDBFBFBBF9FBFBFBF9FBF9FBFBFBF9000000000000000000000000DA0F0BCBF0FDF9FBFEB00000000000000000000000000009BB9BB9FB9BFBFBFBBDBF9BF9BBDB9BB9BBF9FBB9B9F9E9FB9B9F9FBDAB9DBFA0000000F0B0BDAF9FBBFBBFBFBFBB9BFBDFBFBFBFBFBFBFBFBF9FBDBE00000000000000000000009ABDFDFFBDFF9FAFDF9FDFFAF00000000000000000000000009F9F9A9FBDBB9BBDBB9BF9BF9FBFBDBF9B9B9FBF9ABB9B9FBFA9B0BBDBEB0000000000F0000090B0BDADB9F9B9F9FB9FBBDBBDBBDBFBFBFBFBFBFBF9000000000000000000009EFFDBFA9FDFB9FDF9FAFFBF9F9E9090000000000000000000000BB0BF9B9BBDBF9BBDB99BB9BB9B9BB0BFBFA9A9BDBCBFA9A9BF9FBCA0000000000000B000000000000B0FBFFFBFB9BFBFBFFBFFBFBFBDBFBFBFBFB0000000000000000009BBFFBCBEBDFFFADFEBBFBDF9F9FFFBFFAC000000000000000000000BDBF9BBFBDB9BBE9B0BFBDBF9F9FBDBF09B9BDBCBBB9B9BDBF0A00000000000000000F00000A00000000009A9BDBFFBF9FBBF9BFBDBFBF9FBFBF9BC0000000000000000BEDF9FDFDBDFBF9FF9BDFDFBFFFFDBDFCBDBCB00000000000000000000B9BBDB9BBFBDB9F9F9B9BB9BBB9AB9BBF9E9A9B0F9FBE9A000000000000000000000F000A0000000000000000B0B9FBFBF9FFBFBFBFBFBFF9FBFBB00000000000000BC9BFFEBFBFDAFDFF9FFDBEBDF9E9FFFBFFDBDBCBDAC00000000000000000F0BBDB9FB9BFB9B9BDBBDBDBDBD9E99A9BDBFBF9A00000000000000000000000000D000000000000000000000000B0FBDBBBF9FBF9FBFBBFBFBD00000000000000BCBFFDBDBDE9BF9FADFBCBDBDFBFFBF0BDF9BEBCBDADB0D0000000000000099BD9BBFB9FB99E9BB9BD9BB0B0BB9BFBF0B00000000000000000000000000000000A000000000000000000000000009BFBFDBBF9FBFBF9FBFBDA0000000000000ADBDFDAFFDFBFFDFBDBADBFBDB9FF9FDFFF9FFD9F9A9F0F0A90000000000000BFBBBF9BFBDBFB9F0FB0BADBDBBDBE0000000000000000000000000000000000000F00000000000A0000000000000000BFBBFFBFBFBFBFBF9FA000000000009C9F0FBFBFDBE9FDAFBDFFDBDBCBFF0FFFBF9FF0FBF0F9E9F9F9E90000000000000B9F9BF9B9BB09B9BBDBF9A9BE9A000000000000000000000000000000000000000F000000000000000000000000000000FB9FBFBFB9FBFBFBF00000000000A9E9F9EDFBFDBF0FDBFADBFFF9FDADF9FDFBFBDF9F9F9F90BCBCBCB0000000000009A9FB9FBBC9F0FBDA0000000000000000000000000000000000000000000000000D0000000000000000000000000000009FBBDBF9FBFBDBBF00000000009BCB9BCFBFBDFBDBFBFFDFBD9E9F9BDBBFFBFDFDBFBCB9E9EBDB9F9AD0F00000000009FBB9FB9FBB0B00000000000000000000000000000000000000000000000000000A0000000000000000000000000000000BFFBFBFBFBFBFF90000000000FCBDEFF9FDFEBDAFDFBDFBDAFBF9ADB0FDBFDBFBF0DBDE9F9D0BCBCBDA09E00000000B9B9FB9F0000000000000000000000000000000000000000000000000000000000F000000000000000000000000000000009BFBDBFBDBFBB000000000009BCFBCBFAF9F9FDBBDEBBCBDBD0BDA9F9BDFBEDADBF0B9F9AFBDB9F0B9F09C00000000FBF9FBA0000000000000000000000000000000000000000000000000000000000F000000000000A000000000000000000000BFBFBFBF9FFE0000000000E9BDFBDFDBFFFBFDFBDFDBDADBF0BD00F0B0DBDB0DBDADAD99E9E9BD0F0F0B0000000099BB9F00000000000000000000000000000000000000000000000000000000000D000000000A00000000000000000000000099FBDBFBFBB000000000909FEBFDAFBFDBDF9BFCBFAFBDBC9BCB9F09CB09A9DA09099A9E9B9F0BF9B9E9E0000000BF9FB000000000000000000000000000000000000000000000000000000000000A00000000000000000000000000000000000BFBFBFBFBD00000000000BCBDAFFFDFAFFAFFDBF9F9C9E9BC90F09FBDBE9DA9BDBFA9F090F09F90FCB90D000000B9BB0000000000000000000000000000000000000000000000000000000000000F0000000000000000000000000000000000000BFFBDBFB0000000000C9FFFDBDBFBDBDF9FAD9F0FBF9E9FBF9FF09A909A9C9A90D0BBDB9F9ADB9B9E9AD000000FBC0000000000000000000000000000000000000000000000000000000000000F000000000000000000000000000000000000009BFBFBFC00000000B0A9BFFEFFDFFFBFF9FBEFBD0F9FBDBDA99F0DBDBDA9F9E9B9C9ADB0F9ADADA9F0AC0000B9A000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000FBFBDBA00000000009FFE9F9FAF9FDBFF9F9F0FBFBDFADADBE9FBCBDBDF9E9BCF9BDBCB9E9BDB9E9BDA00000F000000000000000000000000000000000000000000000000000000000000000E00000000000000A00C090C000000000000000009BFBFBD000000009CFEF9FBFFFDFFBFD9E9E9F9FBDEBDBF9FDBC9FBCBF0BDBDB9BCBCB9F9BC9ADB9CA90000B00000000000000000000C0000000000000000000000000000000000000000000F0C00A000000A0900A000A0000000C0000000000009FBDA000000000B9BFFFCF9FBFBDBAFBDBFFBDFF9DBFDF0BFBFDBFD9FDBDADADB9B0F0BDBF9ADAB9E0000000000000000000000CA000000000000000000000000000000000000000000000F0A000C00AC090C0000A000AC0AC000A0A0000AC000BFBF00000000A0FDBCBFBFFF9FFDBDAF9BDFBCBFBCBBDFD9F9FDBFDBFDBDBDADF9F9F0F0F9F9DE99E0000000000A000000C0A0000000E0000000A0C0000000000000000000000000000009000000A000000A00C9C0C900090A0900C9AC00000E9AFB000000000DAFFFFDFF9FFF0FDBDBFFFBDF9FDBFDBFBFFFFBDFBF9F9F9F9B0F0F9F9F9FCBB9FA900000000000000000000000C0A000CA000C000A00000000000000000000000000000E000A000000A00000A0A0A0C0AC00C0C00000B00A000DBF000000000BFFADBFE9FFDBFBBEBFFCBDFBFFBFDBDBFDBDBDFBFDF0F9FBCBDBDBCB0B0FBBCDAD00000000000000AC0A000C0A000000000CA0000000000000000000000000000000000F0000000000000000000000A000A00A0A0AC00C0C90A09BE00000000FBDFFF9FFBFADBDF9F9FBFBDF9FDFBFFDBFFFFFFFDBDBFDE9FDBCB9F9F9F9FDBBDBE000000000000000000A00000000CA0C00000AC000000000000000000000000000000F00000000000000000000000000000000000A00A00C00C0B000000009EBFCBFBDFDFBCBFFFFBDFFBFFBFDF9FFDF9FFF9FBFFDBF9F9ADBDE9E9E9B0FCBBD9F0000000000000000C000000AC00000A00AC00000000000000000000000000000000B0000000A00000A00000000000000000000000000A00A00C00000000FDFFBFDFFBE9FBF9F9FDBF9F9FDFBFFF9FBFF9FFFDF9FDBF9FDBCB9F9F9F0F9BDDAF9E00000000AC00000000E00C000A0000C0C00A000000000000A00000000000000000C0000000000000000000000000000000000000000000000A00000009BFFADFFBCF9FBFDFBFFBF9FFFFFBFDF9FFDFDFFF9FBFF9FDBCB9F9F9CBDADB9FFBF9E9000000C00000CA0000000A0000C0E00A0A0C000000000A00000000000000000000F0000000000000000000000000000000000000000000000000000000FBDFFBDFBFFBDFBFF9FDFFF9F9FDFBFFDBFFBF9FFFDBDBE9F9FFDBCBF0F9F0F0BC9FBDF0000A0000A00000E0000000E000000C00000000A0000000000000000000000000B0000000000000000000000000000000000000000000000000000000FEFBDFF9F9FFBDF9FFBF9FFFFFBFDF9FBDBDFFF9F9F9FDBDBD9ABF9DBDBCBDBDBFBDBBCBC0000000000000000E00C000A00A000C00A00000C0009000000A000000000000F000000000000000000000000000000000000000000000000000000ADBFFEBFEBFF9FFBFF9FFFF9F9FDFBFFFDFFF9F9FFFFF9F9FDAFDF9FBCBDBDBCBD9FEDFBDA00000000000A0000000A00C0C0C0A0A000000000A00E00A00000000000A0000C0000000000000000000000000000000000000000000000000000009FFDF9FDBDF9FBFFDBFFBDBFFFFFBFDF9FBDBFFFFF9F9FFBCBF9F9FE9F9F0F0F9EBF9FBDAD00000A00CA0C0A0C000000000A00C0000000A000000000C00A000A000000000B000000000000000000000000000000000000000000000000000000BBFAFFBFFFBFFFDBFDBDFFFDBF9FDFBFFDFFDF9F9FFFF9FDBD9F0FDBDBCBDBF9F9F9FBDFBDA0000C00000000000AC0CA0A000A00000000000000000000000C00000000A00F000000000000A000000000000000000000000000000000000000000FFDBDE9FBDBDBFDBFFBF9FFDFFBFFDBFBFBFFFFFFBDFF9FFBFBDBF9FBDBE9FBCF9E9FBDFBDBE000000000C000000000C0C0C000000A00000A00A000A0C0000000A000000F0000000000000000000000000000000000000000000000000000009FBFFFBFBDFFFFFBF9FFFFFBFBDFDBFFDFDFDBFFDFDFBDFBDFDFBDADBCBDBDADBDBFDBDBFDAD00000AC000A00E000A009A0B000A900000000000C000000A00A00000000000000000000000000000000000000000000000000000000000000009EFDE9BFDFFFBF9FDFFFDBDBDFDBFBFDFBFFBFFDBFBFBDFBDB0FBDBDBDBDADBDBDBF9F0FFDBF9E000000A0000000E00CA0C0C0E0C0E00CA0B0C0000000000000000000A000F000000000000000000000000000000000000000000000000000000BFBFEDFBF9FDFFBF9FBFFFFFBFFFDFBFDBFDFBFFDFDFBDEBDF9DAF9F0F9F9EBDBCDBFF0BFF9E9E0A0000000C000000000A0A000A00CA00C0A0A0A0A0A0000000C00000000F0000000000000000000000000000000000000000000000000000000FDBFF9FFFBFBDFFFFDF9FDBDBDBFFDBFDBFDF9FBFF9FBDFBFFBD9E9F0F0F9DBFBFDBDF9FFF9F90C000C00A00A00C0A0C9C0BC0D0A9CA9A0C0D0C9C0D0E0E00A00A000000B0000000000000000000000000000000000000000000000000000009BFE9BFF9FDFFFBDBFFBFFBFFFFFDBFFFFFFBFFFDF9FFDBDF9DFFBDBDBDBDAF0FDBFFBDBDBFF9EB000A000000C00A00CA0A0C0A0AC0A0C0CB0A0A0A0A00009C000C0A00E0C000000000000000000000000000000000000000000000000000000FEF9FDF9FFBFF9FFFDBF9FDF9F9FBFFDFBDFFDBDFBFFDBFF0FBA9CBF0F0F0BDBDBF9FDBCBFDBCBD00000000000000009000D0A90C9AC90A00C0C00C00C0BCA0ACA0BC0D00B000000000000000000000000000000000000000000000000000000BDBFFBFFBDF9FFBDBFDFFBFBFFFFDFFBFFBFFFFBFFDBFFDBF9FDFBD9F9F9BDBDBDFFBFF9DBFFF9E9AC00AC0A00B000A0000A00C0A000AC9E0B0ADA0E9AC000C900C00A0A0F000000000000000000000000000000000000000000000000000009EBCBDF9FFBFF9FFFDBFDBDFDFBDBFBDFFDFDBFDFDBFDBFFDBF9BDBEBCBCBDADADB9FDBFBE9FF9F9E90000000C000C000E00000A000C0000000000090000ACA0AC9A0C00C0F00000000000000000000000000000000000000000000000000000E9FFBFBFF9FDBFF9FBF9BFFBFBDFFDFFFBFFBFDBFBDFBDF9FDAFCBD9DBDBDAD9F9EFBFFDF9BDBFFDBCA0000000000A0000000000000A000A0C0AC0AC0AC9009C00AC0B0E9A00000000000000000000000000000000000000000000000000000A9BF9FFDF9FFBFF9FFFDFFDBFDFFBFBFBDFF9FDBFDDAD0F99E99DBDEBFADBCB9F0BF9FDFB9EDFDF9ADA9C00A00A00000000000A000A00000000000000000AC0000000000000F00000000000000000000000000000000000000000000000000000FDEF9FBFFF9F9FFBDBF9FBDBFBDFDFDFBDBEDBF9FBDBD9AD99E9099C99E9BDADBD9FFBDFF9BABFFDBF009000000A000000A0000000000A000A00000000000A00AC00AC0000F00000000000000000000000000000000000000000000000000090BBDBFFDF9FFFFBDFFDBFDFFFDFFBFBFFDEDBD0DFDFFFFDDAD99DBC9BC9F0DBDADBF9FFBDFFDDBDBFD9FAC00000000000A000000000000000000000A0000000000009000A0000000000000000000000000000000000000000000000000000000ADEBFDBFBFF9F9FFBDBDBFBDBFBDFFDF9F9D9FDBFFFDF9F9D9AD0D9BC9A9DBCB9BCBDBDFFBDBBDBFCBE9DA0000000000000000000000000000000A0000A00000000A0000000F0000000000000000000000000000000000000000000000000009FF9FDBFFDF9FFFFBDFBFFBDFFBDFE9FBD0F9E99F9C9090D0B0D09A0C9C9D00BDADBDBFBDBDBFCDBDBF9DA000A00000000000000000000000000000000000A000A0000000000A000000000000000000000000000000000000000000000000000ADBFBFFDFBFFBDBDFFBDF9FFBDFFBDF0DBD0D9FD09B9FDB9BDFBFBDF9AB00BD09DBDBE9FFFFBDBBDBDBEBDBC0000000A0000000000000000000000000000000000000000A000D0000000000000000000000000000000000000000000000000009ADFDBFBFDF9FFFBDBDBFF9FFBDFF9DF0D0B09BFFDFFBFFFFFFFDFBFFDFF009E909BD9F9BDFFFDEBDFD9F0B0C000000000000000000000000000000000000000000000A00000F000000000000000000000000000000000000000000000000000FFBEBFDFFFBFF9FFFFAD9FFF9FF0DF0900BDFFFFFBFFFFDBFFFFBFFFFBF0F0090DBCBFDFDBF9FB9F0BBF0FDB0000A00000000000000000000000000000000000000000000000A00000000000000000000000000000000000000000000000009BF9F9FDBFF9FF9FF9F9DFAFF9FF9F9090F9FFBFFFFFFFFFBEFFFFFFFFBDFFB0900B09BDB0BFDFBDFDBDEDBDA00A00000000000000000000000000000000000000000000000000D0000000000000000000000000000000000000000000000000ADAFFFBFF9FFDBFBDF9FB9F9FFBC90E9EF0FBFDFFFFFBFFFF9BFFFFFFFFFFFC9E090DBCBFFDBF9FF9ADB9BDA9FC000000000000000000000000000000000000000000000000000A00000000000000000000000000000000000000000000000000BDBDFF9FFBFFDFFBFBDE99F9EDBD90B9FF9FFBBFFFDFBFCF0DB9F9BDBDADBF090C0099099F9FF9FFDBCF0FDA9AC0000A000000000000000000000000000000000000000000000F0000000000000000000000000000000000000000000000000BCBFBF9FFFDFBFBDFDF9BDBBF9F00A9FFF9EFFCF9E9B0D9B9DBC90C90DADBC900A909CADBF0FBDFBDBDB9F9AD9F0A000000000000000000000000000000000000000A00000A0000000000000000000000000000000000000000000000000000BDBFDFDFF9FBFDFDF9F9ADAFC9F090DFFE9E9B990BD90D9E9CB09AD99E909090E9909A99BE9DF9F9F0FA9DADF9E0000000000000000000000000000000000000000000000000000F0000000000000000000000000000000000000000000000000ADBFBFBFFFDBFBFBFBDF9D9B90C00B09F099C9E9DADF0BDDBDFDDBAD9BDADBF9F0F0DBC99FB0BDBDBD9EBDA9E9BC00000000000000000000000000000000000000000000000000E000000000A000000000000000000000000000000000000009FADFFDF9FFFFDF9FDFBDBAD0F99BD0F09FE9BF9F9F9FDFBFDBFBFDFBCF9F9CBDAD9B0DBDA9DFDBCBDBD90BDA9EDA90A0000A00000000000000000000000000000A0000000000009000000000000A0000000000000000000000000000000000CABDFBDBFFFBDBFBFFBF9E9DB9ADADBF9FF9BFDFFFFFFFBFDFBFDF9F9FF9F0FBDADBC9F09A9FB9ADBDA9AF9DA9F9A9C000000000000000000000000000000000000000000A000000E0000000000000000000000000000000000000000000909A9BDFBFFFFF9FFFFDFBDF9F9BCBDBDBE9FF9FFDFBF9FDBDFDFBFDFBFFFDBDADF0F9DA9E9BF9DF0FDBDB9FD99A9E9E9CA0000A00000000000000000000000000000A000000000A0000900000000000000000000000000000000000000000000BFFFFBFDF9F9FFFBDBF9FF9E90FBDBCBDFFDAFDBFBDFFBFFBFBFDFBDE9F9ADBDBDBD0BDB90D0FA9F0B9F0F9BCBD990F0BCB00000000000000000000000000000000000000A000000000E000000000000000000000000000000000000000009ADBF9F9EBFFFBF9FDFBDFF9E9FBD9DADBDB9FBDBFDFFBDFDBDFDFBF9FBDFFFFF0FB0FBFCBCB9BD9F99F9E9F9E9BDADA9AD00CA00000000000000000000000000000000000000000000000B00000000000000000000000000000000000000000ADFFDFEFFDF9FDFFFBFDBF9F9F9C9ABD9F9EF9DFF9FBDFFBFFFBFBDFFFDBF9F9DB9DF9C9BD9DE9A90F0BDBDBDBDBC9BC9CBCB0D00000A0000000000000000000000000000000000A000A00C0000000000000000000000000000000000000000BDFBFFBF9FBFFFFBF9FDBF9F9F9E9B9D9BE9F9FBF9FFDFFBDFDBDFDFFBDBF9FF9FADE90FBDA9A9BDBF9BD9F9E9F0F9BCB0B0BC9A00A0000000000000000000000000000000A000000000000B0000000000000000000000000000000000000009FBFFFFDFFDFBF9FDFFBFD9F9F0F9BDA9AD9F9F9E9FDBFBDFFBFFFBF9FDAD9F09E9DB9BF90BDBD9DAD0F0FBDBDBDBDAD9BC9E00FC00000000000000000000000000000000000000000000000E00000000000000000000000000000000000000ADFDFBFFBFBEFDFFBF9FDBEFF0FBDFCBDF9A90F9F9FBFDBDB9DF9F9FFFBDB9E9F99E9FC90FD09CB0BDB99F9EDBFDBDBDADCB09CB0BC0000000000000000000000000000000000000A000B0000900000000000000000000000000000000000009FFBFBFDFFDFFBFBDFFFFBF9F9F9DBB9F9AD9DB9E9F9E9FFFFFBFFFFF9DFBCBBDADA990B9F9A9F9DBD0DAF9DBBDBCBD9F9BBC9EBC0DA00000000000000000000000000000000000A0000000000E000000000000000000000000000000000000BBFBDFFFFBFFBDFDFFF9F9FDF9FBFFBDFDBDF0B0F9F9F9FBDBDBDBD9F9FFADBDCBF9F9E09C909F0BAD0BBD9FFBDFDBDAF0F9C9A900BA00A000000000000000000000000000000000000000000009000000000000000000000000000000000000DFDFFBDFFFDFFBFFFBFFFFBFBFDBDBDF9BF9BF9D0BDBDF9FBDADF9FB9F9F9FDFBF9F0F9F0B0F09D9DBBD9FBDBDF9BF9F9F9E9AD0F00D000000000000000000000000000000000A0000000A00A00E000000000000000000000000000000000000BFBFDFFBFFBFCFFBFDF9F9FDF9FFFDBFFDFFDFBF9CB0BDBDFFF9AD0DADADFBF9FDFF9F09F0F9FA9A9D0BC9FBDBFFDBF9F9F9F9AD0ADAD00A00000000000000000000000000000000000A0000000B000000000000000000000000000000000009F9FDBFFFDFFFBF9FFFBFFEFBFFDBDBDBDBF9F9F9FB9DF9FBC99FDBFFBDBFBDFFFBF9F0F9E99E99C9F0BDFBFDBFDBFD9EDADADADA0D00A0000000000000000000000000000000000A00000090C00C00000000000000000000000000000000000BFFFBFF9FFFF9FFFF9FFDBDBDBDBFBFFFFDBFFF9FD9E9A9F9FBFFBFDBDFFFDFFFFDFFF9F090FB9E9B0F9F9FDBFDBFDBFF9F9F9F90F00BC00000000000000000000000000000000000000000A00A0B00000000000000000000000000000000000FDBDFFFFFBFFF9FAFFFBFFFFFFFFDFDBDBFDF9FFFBF9F9CBD9F9FDBFFFF9FBFFDBF9F9E9F0F0DE90DB9F9FBFDBC90BDB9F9F0F0E90BC0900000000000000000000000000000000000000A0000900E00000000000000000000000000000000000BFFBF9FFFFF9FEFDFBFDBDBF9F9FBFFFFDBFFFBFDF9F9B9EB9CFBFDFBDBFDF9FFDFF9F9F0D0B99E90F9FFD0900BCBC0D0BCBD9F9E90B0E0E0000000000000000000000000000000A000000000000900000000000000000000000000000000009FBDFDFFBFDAFBDBFFCFFFFFDFFFFFDBFBFFDFFDFFFFFFDF9DA9BDFBFDFDAF9FE9FBDFCBCB0BCBC09F9E90BCBDBDBDBF0BC90FADA9CAC09000000000000000000000000000000000000A000A00A00E0000000000000000000000000000000000FDFFBFBFFDFBDFFFFFBFBF9FBFBDBDBFDFFFFBFFBFF9F9F99ADBDF9FDBEBD9FF9FFDBDBDBC9C90B9F0F9CBDBDBDBFDF9FFD0F09DBCB909E0000000000000000000000000000000000000000000000B0000000000000000000000000000000000BFBDFDFDBF9FFF9EBDFFDFFDFFFFFFFFBDF9FFDFFDFFFFBFFDBCB0F9BDBDBFF9FBDBCBDADB09E9C9AD0F9E9F0FBDFBFFD9FBDE9A0BCCA00000A000000000000000000000000000000000000000000C00000000000000000000000000000000000FFBFBDBDADBFFFFFBFBEBFFBDF9FFBDFBFFFFFFBF9F0FDBDBDBDBCF0FDBDADFDFBDBDBDADA90B0F09BCBDBDBDFBDF9FBE9F0BC9C0B9DAC0BC0000000000000000000000000000000000000000000F0000000000000000000000000000000000BDFDFFFFBDBFFBF9FEDFDFDBFFFFFDFFFDFFF9F9CDADF9EDBCBDADB9F9F0FDBFBDFBFDADBC9E9C909E9F9F9FF9BDFBFF9FF9FDBF0BCA0090000000000000000000000000000000000000000000000A0000000000000000000000000000000009FFBFFBDBDBFFFDEFFFBFBFBFDFBFFBFFFBFB9FCFFBF9BDFBDFFF9F9F0FBFDBF9DF9EDBDBC9A9DA90F9F9FF0F9FFFBDF9FF9FFBDCBC090F0ACA0000000000000000000000000000000000000000000D0000000000000000000000000000000000BDF9FFFCBDFDBFBFBDFFFDFFFFDFDFFBDFCDCBBF9FDFFFBDF9FFFDEBDBDFBFDEFBFDBDADA9D0E9E9BDBE9BDBFDBDFBFF9FF9BCBBDBDE0000000000000000000000000000000000000000000000000A0000000000000000000000000000000000BFFFFDBDBFBFFDFDFAF9EBF9FBFFBFDFF0BBFDF9F9F9F9FBFBDBFFFDBDBCDBF9FDBFDBDBDE9B909E9E9DFDBDBFFBDF9FF9FFDFDE9EBFCB0F000000000000000000000000000000000000000000000F0000000000000000000000000000000000FDBFBFFF9FFFEBEBFDFFFDFFFFFFFFFE9FDF9F9FFFBFFFFDFDFBDBDFEBCBBDBF9FFDADADA90C0F99F9FBFBFFF9FFFBFF9FF0FBDBFDBDF0C00000000000000000000000000000000000000000000000000000000000000000000000000000000BFBFDFFF9BFFFBDFFDFBDBFFBDBDFF9E9FBF9FBF9FBDFDBDBFFBDFFBFFD9F9CBDFFDBF9F909E9B0BE9FBDBDBDBFFDBFDBFF9FBDBFCBCBE00AC00000000000000000000000000000000000000000000F0000000000000000000000000000000009FDFFFF9FC9F9EBDABFEFFBDFFFFBEF9FDF9F9FDBDFFBFFFFBDFFBDFF9EBCFBCBF0FF9F0FDA90C9D9F9FFFFFFFDBFFFFFDBFBDFCFBDAD9E0900000000000000000000000000000000000000000000000000000000000000000000000000000000BFBF9FFBFB0F9EFDF9FBDFFBDFFFD0FBFFFFFBFFBFDF9FBDFBFDFF9FFFDBFDBDFF9FFDB00DA9ADADAF9F9FF9FFF9FDBCBDADBBF9E9FACBC0A00000000000000000000000000000000000000000000F000000000000000000000000000000000FFDFDFFDF9DBC9B0BEFFDEBDFFBFDBFFDFBDB9F9FDFBFFFFFBFFBFBFF9FFFCBFBDBFDADFDBAD0DABDBDFBFF9FF9FFFBFFBFDBCF9E9E9DBC00000000000000000000000000000000000000000000A00A000000000000000000000000000000000BDFBFBFFBCADABCFDF9FBFFFBFFDAFDBFBDFFFFFFBFDFBFDBDFDFDFF9FFBCBDBCBFDBFF0B0D00BDDBDBBCF9FDAFFBDFF9F9ADB9E9F9EBE9009C0000000000000000000000000000000000000000000D000000000000000000000000000000009FBFFFFF9F99A9CB0BFFFFBDFFDBFDBFFDFFBDBDBDFBFFDBFFFBFBF9FFBDFFF0DBDBFDBDBCB00D0BADADDF9EBFDBDFBD0F0FDAD0B9E9F09EC00A0000000000000000000000000000000000000000000E000000000000000000000000000000000FDBDFFFFFFF0A9ED0FBFDFBFBFFADFFFBFBFFFBFFBDFBFDBFDF9FFF9FFBBDFCBCBFDBCF9F0DAADDBDBA9BF9F9FFBDFFBDB0BDAD0F9E9F09A0000000000000000000000000000000000000000000000B000000000000000000000000000000000BFFFBDFFFFAD009ABFDEBFDFDFCDAF9FFDFDBDFDBDFBDBFFDBFF9F9FBDFDBFF9FBDBFFBDADA9DABCBDFFF9FFFFFFEBDFADFC09B0BCBDADAC0000000000000000000000000000000000000000000000C00000000000000000000000000000000BFDBFFFF9FDF09AFADFFBFEFBFBFBFFFFFBFBFFFBFBFFFFFDBF99E9FBCBDBEF0DADFFDBDE9F09E9DFFF9F9EFDBF9DBDF0FDA9BF0FC9FADA900000000000000000000000000000000000000000000000B000000000000000000000000000000009FFFDFFFFFBDE000DA9FFDBDFFFC9F9F9FDFDBDBDFF9FFFFBDBFFBF9DBFFF9BE9FB0FBFBDB09E9EB9F0FBD9FBCFFEF0BD0BC9C9F0BF0DBC000000000000000000000000000000000000000000000000F000000000000000000000000000000000B9FABFFFFFADA0F0DAFFFFFBDBFEFFBF9BBFFBFBDFFFFBDFFCBD9FAF9F9FFDF0DFF9FDF9EFDAD0DAD90CAF9E90909CA9FCB0BCBD0BF0CBC000000000000000A0000000000000000000000000000000E000000000000000000000000000000009FF9FDFFDBFDF0000BF9EFFBFEFC9BDE9EDF9FFDFFBDBDFFADBDBE99DFFFF0F0FFBDFBF9E90000B0F0ADB9C00E0E0009CA90D0BC0F09BF0000000000000000000000000000000000000000000000000900000000000000000000000000000000BD09FBFBFFCB0000BF0FFBDFFDBFBCFBFB9AFFDBFBDFEFCBDBCBC99EB09B9FBDA9CFBFDA00090BCD9FDB0CF0F0900E9CA9C00BD0B09EC0C000000000000000000000000000000000000000000000000E000000000000000000000000000000000FBF09FFDBFBE900C0FBFFFFBFF0DBFDFDFDBDADBDFBDBFDA9F9F0F99FEDE9FE9EBFDFFD09ADADBE9BFFFB0CADE0000AD09A9CAC9CA99A0E00000000000000000A00C00000000000000000000000000F00000000000000000000000000000000BDF9F09BED0D0E00B00FDBEDFBFFE9FBFAF9AF9FFFCBC000C0CBCB0F09B9BDADBDFBFFBFFF9F9E9FFFFFFDA900000000000DA90B09CAC0900000000000000000900A0A0000000000000000000000000B000000000000000000000000000000000FBFCBC09A9A900000BDAFDBED009EBDF9FFD9AD0A0C0A90A0BDF0D0BCF0DAD0FFBDFBFDBDE9FBDADFBFFC0EDAD0AC09ADA00CBCBCB000E00000000000000090C0090000000000000000000000000A0C000000000000000000000000000000000BFCB009AD0000000ADAF9FAD0BFFBDE9FF0BED0BFDB09CAD0DA0DA9E9B9EBCBF9FFFDFBFFBF9EDBFFFDB0F90BCAD09ADAC9CBC09000DA00000000000000000A00E00000A0000000000000000000000B0000000000000000000000000000000000FBC0000000000000000A0FBFCFFCFBFE9FD9BFDFFFFE0000AD009F9FCF9CBDFFFBFBFFDBD9F9BDBDBFEDACBCBDACBC090A909E00E9AC9C000000000000CA00090000000000000000000000C0A00C0F000000000000000000000000000000000009A0000000000000000CBDEBFEBF0F9FFAFE90BFFFF0F00000BCBCF9BCB0FBF9FDFF9FFFFADF9E9F0F9FF0F0CADBCBCAD0E0000F0F9A0A0000000000000909E000000000000000000000A000000A0C00000000000A0000000000000000000000AC000000000000000BDBDAFDE9FFF0FDADF9EF9FBFDFDADADBCBCB9EDAC9FDFFFBFDFF9BDF9BE9F9BDA9CE9E9C0000000090F9F9F0C9C000000000000000E0000A00A00000000000000C00A0CA000B000000000A00000000000000000000000090000000000000009E9EBFFFBFFDADEBFF9E99EDFFEFADF9F0F9F9EDA99FBFBDBDFBF9FDFBFFDBF0F0F9F9BC0A00F0DBCBCF0F9E9EB0A00000000000009A000000000000000000000A0A0D00000C0F0000000000000000000000000000000000000000000000000009FFFFCFF9EBFCBCF0F9EFDBE9DBDAFD0F0E0F09CBE9F9FFFBFDFFBFBDBDBDF9FF9F0BCB9D9F9E9AF9FBF0F9E90C900000000000000C09A00000000A000000000000A0AC0A0A0E000000000000000000000000000000000A0000000000000000A00BCFBFEFDFBFCBCF0E9EADBEBCFDAE9F9F00E9BDFBDF9FDFBF9FDBDFFBFBFF9F0F9F9EFADADBC9AD0DADA09E9A0E000000000000A900000000000000000000000C000A00D00D000000000000000000000000000000000000900000000000009CBFFBFDBFFADBBCBDFBDFDFEDCB9AD9E0C00F0FCB9FFBFBFBDFFFBFFBDFDFDBFBF9E9E999BDADBC9A9BF09F0000090000000000000000000AC00000000000000000AC009E0A0B00000000000000000000000000000000A0000A00000000000000BDADFEFDADFCFFFAFDEBFFFDBFCEDAC90BDBDB9FFF9FDFDFFF9FFDBDBFBFBFDFDF9FB9FEF0F9ADADAC09E0E0DA9E000000000000000000000A00000000000000A090ACA000CE000000000000000000000000000000009E00000000000000000BCBFFBFBFFBFBDBDFCBDEF0FFFCBDADBCBC9A9FFF9FFBFFBDBFFDBFFFFFFFDFBFBFFDFF9F9F9FF9F9F9BC909A0C0000000000000000A000000000A000000000000CAC90C0CA0F00000000000000000000000000000000009E00000000000000009CBCFDEDBDEDBCBDBFBD9F9ADBCBCB0BDBFDF9FFFBDF9FFFFDBFF9F9FBDFBFDFDBFBDFFFFFF0FF9FEDBADAC9A9E9E0000000000CA00000A000000000A0000000000A0A0A900B000000000000000000000000000000000A00000000000000000A0BFFBFBFEFBFFBFBCBCBE9EDADBDBDFDBF9FBFF9FDFFFF9F9FFDFFFFFFFFFFBFFFDFFBDBDBDFF9EF9FCDADBC9E9C0000000000B0000000000A0000A00000000A0000C0900E0E00000000000000000000000000000000AD00BC00000000000000DADAFDFFBDF0FDEDBDFBDBFBDBFBDFBFFFFFFDFFFFFBF9FFFBFBFBF9FFFF9FFFFDBFBDFFFDBF9FF9E9BBF9ACB00A000000000000900000000000A0C9000ACA0000E0A0E0E00F0000000000000000000000000000000000A00000000000000009ADBDFFADFBFFBFBFFBCFFFDFFDFFFFFFDFFDFBF9FBFDFFF9FDFDFDFFFDFFFFDBFFFDFFBDBFDBFCBDBEDC9EDBCBD0000000000000000A00000000000ACAC0009CA009C0009A0F00000000000000000000000000000000B0C0009A00000000000000FB0FFBFE9FFDF9FFBDBFFFBFFDBFFFBFFBFFFFFDFF9FBFBFBFBFBDBFBFFFFFFFBFBDFADBFCBDFADBFBE9E9ACAC000000000000A000000000000000000A0A0000A0ADAC0C090000000000600000000000A00000000000A9A000000000000000A90FFBDEDBFF0FBE9FDFFFBDFFBFFFDFFFFFFDFFBFBFFFDFDFDFDFFFFFFDFBFF9FFFDFBDFDFBDBFDBCBDBF9EF90B00000000000000000000000A0DA0A000C0CA00C00000A0AE00000A000000A000A0000000A000000A9AD00C000000000000009CBDBCFFBFDFFFFDFBFFBDFFFDFFFFFBFDFFFBFDFFDF9FBFBFFBFBDBFDFBFFDFFFDBFBDFBFBDFE9ADF9ED0F090AC0000000000000000000A0000000D0C0A90A0C0A0AC0F0C0F00000000A00000000000A00000000000000A0A000000000000000A9EBFF9EFFBF9FBFFFDFBFDFBFF9FFFFFBDFFFFFFFFFFDFDBDFDFFFFBFF9FBFBFFDFDBF9FDAF9FFCBDFBF0DAC90000000000000000000000F00000A0AC0E0C0A90C9A000B0F0000000000A000000000000000000000E00C90000000000000000009E9BF9FFFFFFFF9FFFFFBFFFFFFDFFFFFFFDBF9FBDBFBFFBFBFBDFFFFFFFFDFBFBFDFF9FDBF9FBEB9E9FA9A0000000000000000000B0C000ACA0009A00A90CA0A0CAC0C0B00A000000000A00000A000A00000000909A0000A000000000000009E9EDFFF0FFF9FFFFBDFFFFDBDFBFFBDFFFBFFFFFFFFDF9FFDFDFFBFDBFDFFFBDFDFBF9FFBFCF9F9DE9FC9C0000000000000000000000A000009C9E0C0F0CA00C0CB09A0AE0000A00AC00000000000000000000A0C0AC9A0000000000000000B0A9FBE9FFF9FFFFFFFFFBDFFFFFFFFFFFBFDFFDBDBDBFBFDBFBFBDFFFFFBF9FFFBFBF9FF0FDB9E9FEBDA9A00000000000000000000C0000A9C0A0A000A00A0CB00A0CAC0CF0000000000A0000A0000A0000000000A00000C09000000000000000D9E9FFBFFFFF9FBDFFFFFBFFBFFBDFFFDFFFBFFFFFDFDBFFDFFFFFFF9FFFFF9FDFDFFDBFDBEF9F9BDA9C0000000000000000A00000AD0000A0C00E9E9E0CB0CA9CA000B0F0000000000000000000000000A000009E9A000A00E00000000000000A9E9EDBDBFFFFFFF9FFFFFDFFDFFBDBFFBFDBDFBFBFFF9FBFFDBF9FFF9FFFFBFBF9FBDBBDBDADE9FDA900000000000000000000A00000C009A900A000B0CA0CA0DACAC0900A00000A0000A0000A000A0000000A000C0B000090009000000000B0F9FBFFFFDBFDFBFFFFDFFFFFFFFFFFF9FDFFFFDFDF9FFFDFDBFFFFFFFF9FFFDFFFFDEDFBDADBFF0A9C0000000000000000000AC90A0A0A0E0CAD0F0E0CAD0A0CA0900AE0000A00000AC000000000000C00000009A9AC000000A00A000000000C9AFE9FBFFFFBFFFFFBFFFBFFBFFDFFFFFFBFFBFFFBFFDBFBFFFFFBDBFFFF9FFF9F9FBB9CBDBDB09D0A0000000000000000000000C00D00000B00A0E00B00A9CB00E0BCF000000AC00000000A0C00F000000A00AC0C900B0A000C00000000000BCBDBFCF9FFFFFDFFDFFFDFFFDFBFFF9FFFFFFDFBDFDBFFFFFFBDFFFFF9FFFFBFFFFBDDFBCBDADF0A900000000000000000000000A0000BCBC0E0C00BC0E0CA00CB0E0AF00000C00000000A00900000A00A000C90A00A0C090090090000000090B0F9FBFFFBDFFBFBFFFBFFBFFFFFBFFFFFFDFFFFFBFDFBDFFDFFFFF9FFFFFFFDFBDFBE9F9FF9B0D0C9A00000000000000000A000000A0000A90B0F00A00B0CA0AC09C0B00A000000A000C0000A0A00C00000000A00A09A0C0A00A000000000000DADADBF9FFBFFFFFFFFFFDFFFDFFFFFBDFBFFFDBFFBFFFFBFFFBFDFFFBDFFFBFDFBDBFDB0BCF0A9A0000000000000000000000000000CAC0E0CA0CAD0E0CB0F00ACA0E000000A0000A00000000000000000A90C90C0000A000000000000000ADA9FBFDFFFFFDFFDFBDFFFFFBFFFDFFFFFFFFFBFFDFFFDBFDFBFDFFFBDFFBFDFFBF9FF9ADFDB0F90C0000000000000000000000A9C090A90B00BC0B00A90A0C00ADA0DF0000000000000000AC000C0A0000000A0A9000B0900009C0000000009A9F0FDBEBF9FFFBFFFFFDBFFFFFFFBDFFFFFFDFBFF9FFFFFFFFFFFBFFBFFDBF9FDFFDBDFA9A09C0B0090000000000000000000000A0E00CAC9E00E0DAC0E9CA0E00C0AF000A0000000000A000000A00CA00C00000A9AC00CB0DA00B0000000000CBDAFFDFFFFBFFFFFFBFFFFFFFBFFFFFFFFFFFDFFFFFFFBFFFFFFFDFFFBFFFFFBDFBEBDF9D09B000000000000000000000000000000B000A00F00A0CB00A09E9ADAD0D0000C0000A0C000000A009000000A0009C00C9A0A00000000000000000B0BF9FBFFBDFFDBFDFFFF9FFDFFFFFFFFFDBFFFBFFF9FDFF9FFFFFBFDFFF9FF9FFBDF9F0B00AC000A00000000000000000000000000C0F0DAC0E9CA00E0CAC00CA00AA000000A0000A00000000E00A000090BCA00B000900000000000000009C90F9EFDF9FFFFFFFBFFFFFFFFFDFFFBFFBFFF9FFDBFFFBFFFFFBDFFFBF9FFF9FFBDFBFDBCF99000900000000000000000000000A09A0A00A00A00AC9E90B00F0A90E0F000A000000000000A00000C0000E00000B0C0A00000B0000000000000A0F0F9FBFFFF9FBFFFFDBFFFFFFFFFFDFFFFFFFFFFFFFFFFFFFDFFBDFFFFF9FFBDFFBDFADF0B00000000000000000000000A000000C09C9E0CBCBC9A00AC0E00E0CA9CF00000000000000A00C000A0000900E00000B0900E90000B0000000000090BCBCBDBFFFFFDFFBFFDBFFBFFFFFFFFDFFFFFFFFFFFFDBFBFFFFFBFDBFF9FFBFDFBD009D9E9000000A000000000000000000000A00A00F0000AC0AC9A09E09A0CA0F000000000A0000C0000A000A00A00900F0F0CA000000000000090000090A09F9FFF9FBDBFBDFFFFFFFFDFBFFFFBFBFDBFF9FFFDFFFDFFF9FFFDBFDBFF9FDBF0F0EB0A00000009000A000000A900F000000000A0CA00E9E0B0DAC0E00BC0E90EA00000A000000A0000A000C00000000A00000B0090000000000A000A0000D9F0BE90FEDFFFFFFFFBFDFFFFFDBFDFFFFFFDBFFBFBFBFFF9FFF9FBFDBFF9FFBF0BFB9C09000A0000009000000000A0000A000000D0B00F0A0C0CA00A90AC0A9CA9F00A0000A0000000000000A0C000E000D0BCBC9C0A0000000000000090A00A0BC9FF9BFADBDBFBDFFFFFBFFFFBFFFDFBFFFFFFDFFF9FFFF9FFFDFBFDBF9FDB0DBCF9AC0000900A0000000E00000000C000090A0E0CA00CBA0A0CBC0E90F0CAC0F00000000000000A00000900000090A0A0000A0A009A0900000000000009090DB09AD0BDBFFDFFFFFFBFDFBDFFDBFBFDFBDF9FBF9FFBDBFF9FBFFDBFFDFBAD0F0B0C900900A0009E00090000A09E0A00C000E900A9CAD0C0D0B00AD0AC0A90B0D00000C0000A000000AC0000A00000090CB0BC9090C000000000000000000ACA0DADAF9EFDBFBDBF9FFFFFFFBFBFDFFFBDFFFFFDFF9FFFDBFFDB9FF9EBDFD0D9D09A00A00D00D000090E0009C0C09000A00A00E9CA00A0A0AAC0E00AC9ACAC0EA000A000A000000000000E0000A00E00A00C0BC0A0A0000A00000000009AD0909A0909CB9BEBDFFFFFF9FBDFFDFFFF9FFFFBF9FBF9FFBDBDBDBEFF9F9DA90B0A0AC00D00A000A0000A00000A09A0ACB009000F00A09E0F0D0C9A90AD0AC900F0F0000000000000E000000000C00000000A9ADAAD0090C0000000000000000A0000F0F0BDEDBDAF9FF9FFFFFBFFBDBFFBDBFDFFDE9FDBDAFDAF9F99E9AF9E9C09C9090A90D0B0000B0C900A00000D000E0E0F00AC9E0000A0A0AC0E00E90ACA00F0000000000000000A0000A0000000009C000D0AC000B000000000000000000F00090F0B9E9F9FF0FFBDBFDF9FFFF9FFEDBF0BF9FBF9FDBF9E9FE9FFD0F09A0000AC90CA00C00000000090D0AD0A000900A0BC0A00E9E0CAD0CA09E00E00BCB0F0000A00000A00000000A0C0A0000A0C000A0AD9A9A00000000000000000009009A0F00DA9BCBD0FBDFEFDBFFF9E9E9F9BC9FD0BD09F0BF0F9F09F09AD00E090A0000A909A0009000A0ACA0A00A0D0A0E9C0C0AD0E9A09A0A0B0F00BCBCBC00EA0000000A0000000000000000000000A0A090F0A0C0000000000000000AD00000AC900FADDE9E9FBDADBDBF9F0F9F9F0BCBCB0BDAFF0FF09E9ADFADBCB0900000D09AD0AC009A0CA90C900C900000AC0000A0BC0A0C0CAC90E0C00AC0000ACB0F00A0000000000A000E000A0000A0900090ADAFC9A000000000000000000A000009EF0900B9B9E90F9BDBCFADBC9ACB9CB0BCBDA909F09DF90DA900090E0000000A000C900000000C9A009A00E900009A0E9E00AC9A0A9ACA90A0E9A0E0F0AC0F000000000000000000000C000000E0000C0090AC9ADACA000000000009009AC00090E0DAC0CA9E9ADACB90F00BF900E9C909E9CBF09FAA0F09CA9F0A9000900090F00A000000090A0C0AC00000E09A0C9000F09AC0F00C0CAD0B0C9A9A0C9A0D00000A0000A00000000A000A000000ADA09ACBDB0C009090000000000AC000090BE909A09A90090F0DB0E909F00CBC90B0F090BC90F0D9F09E09C00D00A0000A0000900000A00A0009090BC000000C0A00E000E0A00ADA9A00E0E0E0C0F0E0DA00000000000CA000A00000000000000000AC90A0E9A9E0AC000000000009000A0C90E0000000F0E90B0C9A9E0C9B09AF0F0F0AD9ADADBE0A009A00B0009C00C90F0000C0A09C90C90A0E000B000B00BC0E900E090DAC00AC0E909A009A0A90AF00A0000A0000000000009E000000A900A09A0E9E9ADE9C90A9000000F00AC0000BFE900000F0009CADABC9CB0BC0E9C0DB00F9A0DB00090D000090CA0000A90E0000A9A0D00000A0C00000000000000B00ACA9ACA00B0E0B00ACAC9EAC9CAC0F00000000000000000000000000000CA9C00CB009E09AFAE9CA0000D000000009000FEC09E00090A9C0D0BE9CB0BC9A9E0CB00C9A0CBCBCA09000E90000BC00B0F009C000000A0900B000BC000000CAC0E90BC009CA0CA9C0AD0A9A00DA0BCB0D0000000000A000A000CA00A000000000A0A90CBE9AE9C9F0B0DA00000000000AC9E9A9000000A000B0AD0DA0F0CBADA9B00DA90D0B09090CA00900009C009AD000F0000B0AD00E0000F000A00A0A900B00E00BCAA0F00E0AD0AC0CBCA0CA00CA0000A000000000000000000000A00A0009C00A090C90BAF0FCA00A00A0000BC09A9FC0A00000C9CBCAD0E9ADADB0D0D0C0B090E0BC0A0E9000000000A0B0E000B000A9C00000000000000000009C0CAC0E09AC009C00F0BC0ACB0B0A9CB00FAF0000000A000000000A0000C0000009CACA9E09CBEB0E9C0F0BDAD00000000000ACBCBC0000B00A00909A9AD09E0DA0A9AD0CA090009C90A000000000D0C09000C9A9CA9AC900A9000A00E009C0A0A090A90E0A0E0BCA0C00E90E0CAC0AC9E00F000000000000A000000000A0000000090009A0000CB0EB0FE0F0FAD00000000090E9E9E9000090F0A0E0C0BE09A0DAD000B0D0E90A0000000000000A009A00DA00CA90C00AC000C000900000A9CBCA0C0E00D0B0C0ADA0E90E09A0DA9CA00F0D00A00000000000000000A000000000A0A0A0C00BCB0F00F09F0F0DA0F0000000009E9E00C00CAC00D090B0C09E0F090ADAC0A0000D00AD00000000090A00DA00900000B09000000A0CA000A000A009E0B0F0A0CA9AC00E90E0BC0F00E09EA00A000000000000000000A0C00000000A0D09C0B0BCA0F00F0AF0E9EBED0A90A00000F0E900A0B0090B0ACA0DA9E0900E0D0090090000000000000090AC0D0DA090CA90AC00CA00A000090009C0F00D0E000C0AC0B00CA9E9CA9AC0A00E90E090FF0000A00000A0000A0000000A0000090ACA9E0C09ADADA00D0BDE9C9AD0C00900000A9EE090CBCAC0C090F0C09E0F090A000B00CB00B0000000000009A0A0000A000C900A0C09000000A0C0A00E0A90ACB0AC9E0E0BCA00AC0CBC9CB0CA9E0E0F00000000000000000000000000000C0900A9A0E090F0F0E0E0B0FACBE9A0C0A000AD0900E9A0090A9E000B0E0900CA9CB0C0CB0000000000000A0000D0D000C000A0A09090AC0E0000D0A09A090CAC9AC09A09C9E00DA0DA9A0AA0CA9CA0DA0D0000000A00000A0000A00A0000A09A00AD0C0900E00DAD09AD0E9CBC9AC90AC00000ACA090D0F0AD009E9C090E0B000000B000000000000000000F0A0A00A9000D09C0E00A900000A00000C0CA0B0A0CA9E0CA0A0BE00F0CAC9C9E9CA0DA00CB00000000000000000000000C0000A00F000B0E0A9AFA9E0AD0E9AF00AC9A09090C0BC9000E0A00DA09E00A00E90C09E000000000000000000000000D0000000A9A0A0900C000B00900A000B0A9C0C0CB0E00B0E90C09E00A90E0A0AA9CA0BCBE0A00000000000000000C000A0009C0000A0C0900C009EDBCA09AD0BC9AC000C0A0000E00009C9E00F09AD0F00090A00000000000000000000A09A00000000C00C0D0CA0A9000C00AC000BC00C0A0B0AC00DAC00E9ACA0CBCAC9E0C9C0AD0E00F0000A000000A0000000A0000000A000BC0B0E0F0A9E00ADADBC0AD0AC9A9E0A0900009E9000A09AC0FE0A009E00000000000000000000000090C0DA000090A09A00A90C00ADA0000000C00A9A0C0CB0ADA00ADA0C0BCB0CA9A00B0A0F0A09E0D000000000000000A0000000000AC0B00090090009009F0AD0E9ADA9CBAC0090CACA00000A0000C09A09C9CA0000000000000000000000A00000000000A00009C00000A900C000BC0B0B0000C00B0A0C0A0CBCA0F0BC0ACBC0CAD0E9CAC9E00BB00000000A00000000A000A000090000C0ACA0E0A0E0E0ADAADADA0DA0D0B0CA000900A000009A09AC9E0A09C0000000000000000000090C0CA09A000C00CA00A09E9C00A9A0AC00000C00A90A0C00E9A0DA009C0AC0AD00A0BC0A0CA90A09E0E000000000000000000000000000E000B0009000D0909ADA9CBCBDA0CB0ACB009000A000C0000C00CBE9C00000A000000000000000000000B09A0C09A090009C0000A0BC0C0909A9E000A0C00CB0E90AD0AD0EA0E90F00AF0E09E9CBCAC9CA9CF0000A00000000A0000000000A0000E0000A0E9A00E0000DA00E0EDA00F00CB0E0AC90C9A0000A0B000A000A000000000000000000000A00000C9A0C9ACA90A09A0D000A9A0E0C0009A0900A00000AC0AC0A90DA0E00E90090E00A00A9A0ACA0D00000000000000000000A00000000000CB0C00C0B00A00A0DA909ADAC00F00C90000A000000009C0F0D000000D000000000000000000C090E9A0C9A0C90CA000C0A0E90C0D00A0000C0E0BC0A0CBC9ACB0CACAC90E09E0E0E9CBCBC0C0F09E0B00000000000000000A000000000A000A000B00B0C09C0B0DAC0FACAD09A00B0A0DA0C0000000000B000A00C00A0000000000000000090B0E90C9A0C900A09C90A90900CB0A0B0CA0E0A9000000A00AC90CB009A0E90E0B0F00A0AC0B0A0CA09E000000000A000000000000000000000000C0AC0A0A000C0A0BA0DA9EE0D00C0CA00000A0000000000F0D0000000000000000000C0BCAD0E9E9AC9A0A009CA0AC00CACB00C0C09009090C0E00AD0CAD0E0ACBCACB0CA9AC00F0F0CB0CBC9AD0EF000000000000000000000A00000000000A00000D000A0000C0DA0F09AF0F0B009ADA00C00A000A0CA0A0F0A000000900000009A0BCB9AD9A9E9AC90C9E000090B0A90CA90B0E0ACACA0A000C00A90A90AD00A90CA9C09ACA000B00E00A0CA00F00000A0000000A000000C0000A0000009000E0A00009CA9A0B0C90FAD0A0ACAF0C000900000000009C0000000000E00C0DAC0E0D000C0A0C00000000A00AD00AC0D0A00CA000090000D000A90AC0E0CADACBCACBCA0AC0BCBCACAD0BC0E90F090000000A0000000A000A0000000000000E900900AC00000C00CBAE0C0ADDF0D00FADA0A000000000A09E0AD0CA0000A0B009A900ADA9A9C9A9C09A0000900A0CB00AC90B0C9ACACB0A00A000000A90BC00A00DA009AD0BC00AC900AC0B00E00E000000000000000000000000000000000000AC0000A0A0A9E9AC9C9AF0A0ADACB0DAC00D000000000000D00A9C900090CA0C00E90000C0A0CA0A0CA900CA0CB000090AC00A009000C000C000CA90E0CB0F0F0A0F0E0AC0A0E90E9E90E0DA09EF0000000000000000000000A00000000A00A000A000000D000E9A0AC00D0F0E9ACA0DADA0AC0CA0000000A0F0A0E0F0E90DA9E90ADADA90DA9C900000E0009000BCAC09AC0DACA00000C000A0000E9AA0E000E900A9C0BC0B0EA0A0E90A0CA00F000A0000000000000A0000000000000000000000000000A0D0E9E9A9E0A009ADADA0DA9C90A0000000A00000D09A0BCADACB0E0D00000E000A0E09CB09E0A0E0009A9E09A0090C0A000B00C090E00C9C0ADA0E0F0E0AC0F0C90D0E00E9E90F0900000000000000000000000000000000000000000000A000A0BC0ADE09CADAC09A0DA0E0A000000AC00C00C0A0E09C09AC90E09A0CBCB090F0090A000E09C090F0AC000AC0AC0A000A000000A000F0A0F0AC90B0C0BC9A00A0E0A90E9A00E00E000000000A000A000000A000000000000000A000000000000000F00BE0B0A0BCAC9ACB0D0F0D0E00000000A9009CA0AC00A0900CB000C0E00C0AD00E0900B0E00D00CA900900090C00C00A0000F0A0DA0C9ACAC0BE0AC0E9CB0F0CB0C0CB0CAF000000000000000000000000000000000A0000000000000000000E909C0F09CB00E90C0A000A09000A9A0900E0000D0A90D00CA00F0A0090A900A0090A0E090F0ACA90C00E00A00A00000C00000C9A0CB0E090AC00D0A90A0C00A0CA9A0CA90F00000A000000000000A000000000000000000000000000000000000ACAF00E00CB00E9AD0E00000E00C00A0000AC9A0D0E0A0A9000090A0000AC0DA00C900E00009000A00000C00000A0000ACA0A0CB00E90EADACA0AD0E9E0AD0F00E0DA0CA900000000000000000000000000000000000000000000000000000A0DA909E09EB0FE9AC0A90E0A009000C00C9000AC00A0BC90C0E00E0D0E9C09A00C0B00F00BC00CA000A000A0000000A0000900DAC0E90E9000B09CACA00BC0A00E90A0DACE000000000000000000000A0000000000000A000000000000000000000E0E9E00C009E0BD0E090C000A0A000A0E0900F09C00E0A90F090A000A00000B00E00000A0A0009C0009000CA000000000E0A09A0CA0CADACACA090DAC9E0CB0CAD0A90FA000000000000000000000000000000000000000000000000000000A00B0E9E9ADA09E0A09ACA90AC9C00B00000E000E0AC909C0000E000A90AC9E00F00BCAC0000B0CA00A0C00A00000000A000D0E00F09E90AD00ADA0E00A00F0CB00AC0E0D000000000000A0000A000000000000000A00000000000000000000000D0090A0CA0DE0F0F0C90CAD0A0BC0CBCB000F00090ACA0A0A000D00C090A00C0000009AC00C0A000000A00000CA0000CA0A09AD0AC0AC0A0F000E90F0DA00A0CBC9A00B000000000000000000000000000000000000000000000000000000000A0A0E9CB0DA090E0F0ADA90AC9CADA000E0F00BC0ACB0D0D0C9A0A0A00AC09A0AC0B0E00A90000000000000000000000090CAC0AC0BC9A9C0A9E90E00A00E9CA00AC9EE0000A000000000000000A00000000000000000000000000000000000000C900AC0A9CAC900BCA0CBC9EB009E9E900AC0AD0000A0A9AC00D0DAD09AC009A0C00900CA000C0A000000A00000000ACB09AC0B0CAC0E0F0C0E00AC9E90A0DAC9A00F00000000A000000000000000000000000000000000000000000000000000A009AD0A09A0E009C0BCA09CF0E000E0D0000ACBC0C0C09ADA0A000A000A0C0B0AC0000000000000A000000000A0000CAC0BC0A09A0900A900F09A00E0DA00AC0F0D000000000000000000000000000000000A00000000000000000000000A000C0AC0ADAC0F09E0A9E0DACA009ADA9A0ADA0090A9A9A0C000C000AC0F00DA0C000A000000A00000000000A00000000A90AC0F0DAC0E0E9E0E0CAC0F00A0CBC9A00B00000000000000000A00000000000000000000000000000000000000000000000BC009A00E009E90A0B0ADAC000CBC00DACA0C00C0A0A00B0E90000A00000900CA0000000000000000000000A9E0CAD0B00A00F0B000A90A90B00F0CB00AC0EE00000000000000000000A00000000000000A000000000000000000000000A00000B0E00CB0BCA0E09C0D0009ADA00BCA000C900A0000D0000000A0000000ACA0000A0000000A000A0000A000000B000AC0E0DA00CACBC0E0E0CAC0A0CAC0A90F000000000000A0000000000000000000000000000000000000000000000000A000090E9AC00BC09E0A0AE90C00090090F00A0E0DA09000AC00C000000CA0000000000000A0000000000000000000E9C0B09A0CB0AD00A0900B00BC9A09AD0E0D00000000000000000000000000000000000000000000000000000000000000000C0AE9C00AC00A000D0D00A0A00E0E0E00F0000000E000000A0000E0000000000000000000000000000000000E0E9A0AC0E0DA0C0A0E9CACAC0E00AC0E00A00B000000000000000000000000000000000A000000000000000000000000000000A00D00A00900B0D0B0A000C90C000900000000A00000A000000000000000000A000000000000C0000000000A00900CAD0A09A0C0B0D00A0B00B00BC0B00AD0FE0000000A00000000A0000000000000000000000000000000000000000000000000A0F009ACA0C0AC0C000A0000B0000ADA000000CA00000000000000000A00000000A000000A00A000A0000000ACA90AC9E0CA9AC0A0E9C0F0CAC0A0CAD0A00F000A0000000000000000A0000000000000000000000000000000000000000000000000E000000000A00A0000A0000E0000CA00000000000A000A0000000000000000000000000000000000000C09CAC9A00B0CA09E090A000A09AC9A00AC9E0D000000000000000000000000000000000000000000000000000000000000000000000A000000A000000000000C000000A0000000000000000000000A000000000000000A0000000000000A000A00A0A0C9E0CAD0E0CAC0F0E9CAC0AC9E00A00A00000000000000000000000000000000000A000000000000000000000000000000000000000000000000000A00A00000C0000000A00000000000000000000000000000000000000000000000090E9C9C0A00B00A00B09A000A00A9C0A09AC9EF00000000000000000000000000000000A000000000000000000000000000000000000000A0000000000000000000A00A00000A00000A000000000000000000A000A00000000A0000000000000E00A0A9E9E0CAC0F0CAC0CAC9E9CA0BCAC0A00F000000000A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A00000000000000000A0000000A00000000000000000000A000000000F0C0A000B09A00A90A909A000A0C009AC9E0D000000000000000A0000A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000000000000000000000A00000000000000000A000A9ACACAC0E0DAC0E0E0E0E0E9E9ACA0A000A00000000000000000A0000000000000000A000000000000000000000000000000000000000000000000A000000000000000000000000000000000000A0000000000000000000000000000000009E0C09090A090A09A090009090000000D0C9EF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0000000000000000000000000A000000000000000000A0000E009ACACAD0E0E0E0CACADACACACBCADA0A0A0F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A00000A00000000000000000000000000000000000000000000A000A000000000000E0090A00A90090A090000A00000A00CBC0D0D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000000000A0000A000A00000000A000000000000000000000000009A00E0E9CAC0E0E0DACACAD0DADAC0DA000A0AA000000000000000000A00000000000000A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000000000A0000000000000000000AC0DA9000A09A0900A000B000A00090A00CA9C0F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0CADAC9E0CACAD0CBC0CAC0E0E0E0E0BCA0AF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090A000A000B000A000A090B090900090000D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ACADACBCADACADACBCADACACACACADACADACA0F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010500000000000020AD05FE")); - strs.Add(func2(5), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D20540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C00000000000000A0000000000000000000000E900000000C9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D000C000000000000000000000000000000000E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000A90000000000000000000000CA0000000E900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0000000C00000000C00000000000000090000000000000000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0000000000A000000000000000000000CA00000000000000000A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C00000000000000000000000000000000909000000000000000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000CA0000C000000000000000000C000000E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000C90000000000000000CA9000000E90900000000000000D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A00000000000000000AC0000000000009000000A0000E0E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900CA0000000000000000B00E900CB0900000000C00000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C000000E000000000000000000CA00F0000DA00000000000000000CACA90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009CA0000000000000000C0000000A90CA9C9090000009000C0C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000C0B0000000000CA000E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0000000000000000000000000000CA09009000000000000E9000000000000000000000000000000000000000000000000000009A0000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000C90000000000000000000000000C000DA09000000000000C9CE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C000000000000C0CA00000000CB0D000000000000000EA9000000000000000000000000000000000000000000000000000A0B000000000000000000000000000000000000000000000000000000000000000000000000000B00000000000A000000000C0000C0000C0D00C0F09CB0B09000000000000DE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D0000000000000CA9E9F0B0F0B9CBCB0D0000000000000000CF0000000000000000000000000000000000000000000000000000A00000000000000000000000000000000000000000000000000000000000000000000000000000C00000000000000000000000CB9C0D0A9C9ADCB9AD0B090000000000000EFA9000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000C0A90000000000A00000000E0DE90CB9AD9CB0DB0F0DBC900000000000000000C000000000000000000000000000000000000000000000000000E00000000000000000000000000000000000000000000000000000000000000000000090000B0000000000000C0000000C9CA90F9AD0DA9AD9AD90F00BCB09000000000000C00000000000000000000000000000000000000000000000000000A9A0000000000B000A00000000000000000000000000000000000000000000000000000000000000000000000009000E0F0BDCB0F9A9A9C90BC9AD0F9C909000000000000000E000000000000000000000000000000000000000000000000000000000000000000A0000000000000000000000000000000000000000000000000000000000000000000000000000C0C90DAD0B0D0C9C9CBCBC9A9CB9CB0E900000000000000E0900000000000000000000000000000000000000000000000000B00B00000000A000900A00000000000000000000000000000000000000000000000000E00000000000000000000A0B0E9A9AD0F0B9A9A90909ADF99CBC99CA900000000000C0C0000000000000000000000000000000000000000000000000B00A0000000000000A0000B0000000000000000000000000000000000000000000000A000900000000C0000000000C0CB0D0D9A99C0D0D9E9E9C900FCBDBE99C09000000000000A0000000000000000000000000000000000000000000000090C00900000000000090000C000000A0000000000000000000000000000000000000000C0900000000000000C0000C09090DA9AC9CA9B0B009090B0F90BC0D9E9B00000000000000D0000000000000000000000000000000000000000009A900A0090A0000000000A0A00000A000000000000000000000000000000000000000000000000E0E000000000000000C000ADADA90DB9A9D0C90F9E0F0D90F0DBFADAC9000000000000CA000000000000000000000000000000000000000900000000DA0000000A0A0B0090000000000A0000E90000000000000000000000000000000000ACB000900000000000C0000AD090090DA9C0D00B9E900990B0E90DBC0DBDBC90000000000DAD000000000000000000000000000000000000C0A000000CB0090000C0F090000A000000A900009A000A900000000000000000000000000000000C90000000000000000000CA9000ADADA9CB9A9BC0090B00E90D9EBC9F9EDADB0900000000CACA0000000000000000000000000000000090A0B0000B0DA000A000ECBA00A0A009000000000A0000000C0000000000000000000000000000000000000000A0000000000000000090D09090B0C9009A90C0D090F0A9C9ACB9ADBCF000000000000D00000000000000000000000000A0B0CB0C000090000000090D00FF0C9E9090A00000000000000000CB00000900000000000000000000000000CB000000C900000000000090CBCB0BCBC9C9B00F0D00B909AD009C9BC9FCDBE9B0900000000EDA00000000000000000000000ADAC90090009000ACB000090E00A00EBEA0ACA9000000A00A009A00000E90000EB000000000000000000000000000000000000000000900E0090009C909A9A00C909A9D00AD009F0BC0ADA9BC9FCB000000000000000000000000000000000EFDFBDADA00A009A9000009A009A90000C9EF9ACA0000A90090000000000ACB0000F000000000000000000000000CA0000000000000E000E9000A9F0B0F00D09DA9AC900A9D0A9E00D0BD9ADE9FE9FC9000000000C0000000000000000009EFFFFEBCB0090090A0009009A000000C0000AEF0E090000A000A000A0000000CB00000CB0000000000000000000000009000000000000009E0000909C09C909A09CA9C900F90CA9C099F0F00ED09E0DBCBB00000000CA000000000000000CEFEFFFFFBDF0DA0000090C0A0000090E09A00000DEBC9A00B0000A90A000000000FE90000A90000000000000000000000000000000000900000090F0BCB0B0B09AD9A09090B900A99090F0009AD9A9E9F9EDE90000000CA90000000000000CFFFFFFFEFDEFA0B090E9000B0090A9000900090000A0EB00A009A9000009000000000FF00000E0000000000000000000000CA000000000A09A9E00000D0909C90BC900C9ADA9CAD09000F90E9F0DA0DAD0FADBDE90000000C000000000000CEFFFFFFFFFFBF9FD00A900A0000000C00A0009E00000000000DAE000A0A9A000000000ECBC90000B00000000000000000000090900000000C0C0000F09B0B0DA09C0B09A900900900BC9F0009000B0DA9DAD0F0E9F0000000000000000000CFFFFFFFFFFFFFFEF0BC9000090900F09000900A09000900000A0E09ACA090000000000000FFB00000CB0000000000000000000E0E0000000009A0000909E909C909A900D090F90E9A09090090BC990C9A9CBCBCDBFDA90000000E000000CFEFFFFFFFFFFFFEFFFF9FA9A09A9C0A0000A090009C0A0000A09A00FA9AC90B0A00000000000EFE9A0000A00A0000000000000000C0900000000000090ADA9E90DA9A9C90F90AC900090C909A09AD000E09E9CBCBCB0EDADB000000C0000CFFFFFFFEFFFFFFFFFFFEDFAC0D09000000900900A0CA000D000000000000CFFEAC00900000000000FFF9000009000A00000000000000ADA9000000000E000909099A909090A90A99B00B009000C09C009A90900F0F09EDF9EDFC000000000EFFFFFFFFFFFFFFFFEFFFFFBFDBB0A00000B000A00900090B0A0A0000A00000ACADB0A0A0000900000C0FFEB0000A0000000000000000000C0E000000000900DA9CBC9C9AC9A90C90C0090090A90B09A90BC0090F0090F09A0F9A9B000000E0CFFFFFFFFFFFFEFFFFFFFFFFFEBC9D00DA90000900A009000009000A0090000000F0E09000000A000000FEFF900B00000000000000000000CA9000000000000B909B09A90990C90B09A90F090C900000000009AC009E0F0FCFDADFCF900000D0FFFFFFFFFFFFFFFFFFFFFEFDF9FFA0B0000090F009C9000A0D0E000900A00000A000A9A000000000000CEFFE9A00000A900000000000000CB00000000000ACBD0F0C9099A90A900900900000A900090900900000ADA090D0B9A9E9E900000CAEFFFFFFFFFFFEFFFFFFFFFFFEBEF00D09A09A000000000A0900A900A00009000900A00000000090000000FFDB00000000A0000000000000000F0000000000990B99B90BC0DAC90B0C0BC909090009000000090909000D0E9EDEDE9E9F000000CFFFFFFFFFFFFFFFFFFFFFFFFFFDBF9A000000900090A00900090000000A0A00000090000C0000E0900000E0B000A09A0D0B0000000000000AC0F00000000CADBCBC0BC99A0990009A90909A009000090090000000000A90B00B0FCBCFB0000CFFFFFFFFFFFFFFFFFFFFFFFFFFFADAD0B0909CA09A09090000A09E0090A0900000A0A00000A90000A00000B000B0000000A00000000000000DE900000000C9B90999909A090A09090900A0009000900000000000009000C0C9EDE9F0F090000EFFFFFFFFFFFFFFFFFFFFFFFEFBFFFB0B00CA0009000000A0DA9C0090A00000A9A00000000A9000B000000000000000000000000000000000CE9A0000000E9BD0F9A0E9AD90D090BC0009090900900000000000000000909A9AD09AE9E9E900CFFFFFFFFFFFFFFFEFFFFFFFFFFEDB9CBC90090900009A009000000B000090A0C00000B000000A000D09A00A00A0000EB00A0EB00000000000CBC09C000099F09B9C99909009A900090B000000000000000000000000000000C0A0FD9E9E9000EFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFA900B000A90B0009009000B0C00A0A009A9A90000A00000000A00000900000CAF0B00CFFF9000000000ACBE000000E99F9CB9E9A909A900F09A0090900090000090000000000000000000DA0AD0F9E90CEFFFFFFFFFFFFFFFFFFFFFFFFFFFBFDBCB000900000C900E00A9000B0090000A00000A0090009A0E909A0B00A090EBE90000FFFFB00000000C0F0900000F9BF9B99090D0B0D0990900900000000009000000000000000000900900D0AD0EDA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADB009A00C9A90A0909000C09000A090A00000009A0000E0F9ACA00000000A0090000EFFFFFF00000000FE9E0009DB9E9DADADA9A9C90B0000090090090900000000000000000000000000C00BC9E9B0DEFFFFFFFFFFFFFFFEFFFFFFFFFFEFBEBF0CB0090B000009A000000BC00000A09090A00A0C0A000F0ECBDADA0A9000B000A0CFFFFFFFFB00000E0F00900CAFDBDB99909C909A90090B0000000000000000000000000000000000009AC00E9ECFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC9B0C0000000090000090B000B00B000A0A000000A9000000B0CA009000A0000A000FFFFFFFFFFFF9000C0FA0009F9F9BCBDA9A90B090DB000909090000009009000000000000000000000009C09A909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBE9B909A9009A0B0090A0090000000B000000009000E900A000A9E0AC0A09A09000EFFFFFFFFFFFFF000AF09000F9FBF9B9A9D090D00B000900000A0909090000000000009090000000000000A9C0DACCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFCBC00A000A9000C0B00900CA09000A000A90000A0A00A00C90A9CA900B00000000FFFFFFFFFFFFFFFB00C90000FFFBD9F09D9A90B0B9090900900909A00000000000090000000000900000E090C0B00FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBD0B09090D009090C0000A090A0A09009000A00000B0DA00AC00ADEFA09E0B00EFFFFFFFFFFFFFFFFF90CA000CF9F9FB9F0BC9AD09C0090A900900000909000900090009009A90900A90090C00B0CAD0CFFFFFFFFFFFFFFFFFEFFFFFFFFFFFBFBA90000A000A00A009A090009009E00A00A90090000A00000B00000EDF0000EFFFFFFFFFFFFFFFFFFFFB0D0009FFFBDBDBD9B090B09B009009A090900000090090009C0090000DA90009009A9C09000B0CFFFFFFFFFFFFFFFFFFFFFFFFFFEFDEDADBCB090B0909090090090A000A90B00A000A00A0009A9000CA9A90AA0FFFFFFFFFFFFFFFFFFFFFFFFF9A000EFBFDBDB09AD9E909009009000900009090B00900DA09090D090000909C9C09CA9E9AD0DAFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFBDA090C000000A00A000A0009009CA00009A0D0000B0ACA000A9C00AC9CBEFFFFFFEFFFFFFFFFFFFFFFFBC090FFFDBBCBDBD0A9090090A90909009090A09009009009A909A9E9099AD0B0A9CA9C00C00ADEFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBC9A00B090B090909090C900A9A09E09A0000A900C009C0000E0BC9A0ACBDFFFFBFFFFFFFFFFFFFFFFFFBC00FFFBFDB909A9909ACB0C90A00090A00909E990A9A90C90BC9090B0C9090D9E09CBCB0BC90DFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB0B009000A000CA000A000A09009E09E00A0A9C0B00A0A0B0009E0A0D0F0AEBEFBCFFFFFFFFFFFFFFFFA90B0CFFFF9BDFBD9E9909009009090BC9090F090AD90D09B9AD0BCBD0DB0DB0F0B9FE9CBCD0BCA0FFFFFFFFFFFFFFFEFFFFFFFFFFFBEFF09A090909C909009009000000C90E9A90900A9C0B0900000A00F0DA000D00CB0EFFFFFFFFFFF9FA90000C0BFFDBFDB9CB090E90090A9090000909A90F990ADA9E9C99F9BD0B0C9B0D0FDE9DEBDA9AC90DEFFFFFFFFFFFFFFFFFFFFFFFFFAFDB0DA90A0000A000A9000A090A9090A9A000A00D0A90C0A09A000E0EA9CBFABCB0B09E9CAD0A900A00000000BCFFBFDBBDB99E990B9090900F909A0F0DB09CBD99C90BDA90D0BD09B0DBF9CBDEBDECBC9ADA0FFFFFFFFFFFFFFFFFFFFFFFFFFDBADB0C0909A909A9000090000000A9C0C9A00A0A09E9A90A0090900D0A0C0DEB0C00A00B0A900000090009000CFFFDBFDA9E990A900A9000900F0990B9CBCB9ADA9BD09DBDBD9ADBCB0D0FBCFFDADBCBC90DACFFFFFFFFFFFFFFFFFFFFFFFFFBFDA009A00C000000D09A009A9090CA90AC909090E00C0E9000A0A00AFCB0E0F9A0FFCB00000A9A90000CFA900CFFBFBDBDB90E9090D0090B09009E0D0A99BC99AD90BDA9090BC90D9D9AD0D0F0FDADF0BCB09ACFFFFFFFFFFFEFFFFFFFFFFFFFAFDB00909A90B0900A0090000E00090A90A0A00090B0B00B0A0000AD09E09A00CFFFFFFBCB0000CA9ACB900000FFFFDFBDBCB99C0B090A9C90B9A99A9DBC9B9E9B0F9B9DBDBDBDB9A9E99F9F9FFADF0FDADAD09EFFFFFFFFFFFFFFFFFFFFFFEDF9ADA90A000000A090900A0909009E0D0A09000A0E09C0F0C909A000AFE9AC90FFFFFFFFFFFFFFB9D0DA000000FFBDBBDB09900A909090900B0C9DA9DB09F9C909D90D9A9ADBC9BC9F99E9E9EDADF0FF0BC909E9FFFFFFFFFFFFFFFFFFFFFFFBFAD0900090090909000A0D00A00B090A0D0A0A9009CA9A00B0E009A9C0BE90A0CBEFFFFFFFFFFFFF0BEF90000CFFFFFDB9DBCB09090A090A9C99B0DB09F090B9F9ADB9F9D909B0D9F9EF9F9F9F9E9FE9EDB0F09ACFFFFFFFFFFFFFFFFFFFFFFF9F0B0AD0A9A0A0000B09009090900E900AD0000A0A0D090C0B0F00CA0C0FEFDA009ADAFFFFFFFADA0CFFF90000FBF9FBDA909090DA99C0990B0F0B09F0BDBD090F990F9A9F90DB0B0D9EBD0FCBCBD0DF9EDB9E0D9AFFFFFFFFFFFFFFFFFFFFBFE9F0D00900909C9A000000A00E00090E900A9E00C0B0A0CA9C00BCBCBFFFFFFFFBC00000CB0BC9A9CFFFF00000FFFFFDBDBCB0F009009B0C90909DBC990909BDB9ADB90D909F00D0DA9990F99F9DAFF0F90FC9F0ACDFFFFFFFFEFFFFFFFFFFFFBF0B0B00090000A09C9A9090909A9E090A0D009A0B0C90A9CA9FCBCBFFEFFFFFFFFFFFFEBCFE9E9EBFFDA9000CFFBDB9A9090900B90B000B0F0BCB0B9E9A9F0B09D99C9A90900900B0D9EDBDE9FCBD0FD0F09B00D9EFFFFFFFFFFFFFFFFFFFF0F0BC900A9A0A90900A0000AC0A09090AD09A9A0D0C9A0BCA0DA09EFDEFFFFFFFFFFFFFFFFFFFFFFBCFFBDA0000FFFBFD90F0B0090C9090909099909D099D09D9DB0B0B900F009A90D0B09BC9BCBBCBF9AF0FADADA09EFFFFFFFFFFFFFFFFFFFFFF90A090009C0A09090909090D00CA900AC00DA0B0C9C09CB0DAC9AFFFFFFFFFFFFFFFFFFFFFBDFF9CFFF99000FFDFBBC909090090A9CB0DA9E9ADA9BCB0B0B909D9D0D9009000C9A9C9E9BCBDDBD0FCDBD09090DA9CFFFFFFFFFFFFFFFFFFFFBDE9DA09C0090900A000A000A0B0A90E909A900D09A0B0F00FADAFCFEFFFFFFFFFFFFFFFFFFFFFF9EBFFF0000CFBFBDB9A90F09A090900909090D90D099D9D9CB9A909A0900090900CB090DBDAF0FF9FADA9E9E9BCF09EFFFFFFFFFFFFFFFFF9EB9A009A0B0A00A9090909A090009C090A0C0E9A0E0D0E00F0D0F0FFFFFFFFFFFFFFFFFFFFFFFFEBDFFF0B0000FFDFB9C0DA9090DB09A90B909A9A9A9E9A9A9B9C99A9090909000009090DADAD9FF9F0DB9E9C9AC90BCFFFFFFFFFFFFFFFFFFFF9E909009000909000A00C0900F00BCA0D0B090C909A090F00FADEFFFFFFFFFFFFFFFFFFFFFFFBDF9ACB90000CFFF9F09B09090B000090D0A00D09C9999D99C09BD09C90000C9090900F0BC9DFFD9E9FF9E90B0D9E9CBCFFFFFFFFFFFFFFFFBF0B0F00B000900A0DA909A900E90900900A9C0A0B0E0DACB0F00F0FEFFFFFFFFFFFFFFFFFFFFFDFFEFBDEF90000FFBF9F09BCB0D099BC0B090D0A90B0E0B0DB99C90B090B9090A9090F90D0FA90FAFDF9AD9E9CB0A9E9CBEFFFFFFFFFFFFFFFFFFF90B009E0A90D00000000B000A09E0AD00A9C9C090A09C00F09EFFFFFFFFFFFFFFFFFFFFFFFFADBD0B090000EFFFDA9BC9999A9A00990909090909999D9B090B9F9DB900D099CBDA90F9F9DFF9FDBDEDB090B0D9E9EBD0FFFFFFFFFFFFFFFFFBDAF00900900A00B09A090009AD0000909E90A09ACBC9CB0F0FEFFFFFFFFFFFFFFFFFFFFFFFFFF9E9E9C00000DFB9B99C90F0AD90D09A09A09A9E9E90F0B0D9BC909A9CBDB9BCB90DBDF9E9FBCFDBCBB90BCBCB0E9CBD0FFFFFFFFFFFFFFFFFBCF900BCA90A900900009A009E000E90CA000C9AC900B0A0F00F9EFFFFFFFFFFFFFFFFFFFFFFFFFFBDA09A0000EFFF9CA9A90990090900D009C90909A999D9BC9BDBD9F9909C99C9F9CB0DBDEDBF0FF9DAD09F0C99BCADADEFFFFFFFFFFFFFFFFBA9E9090090090A90B0009A009A990B09C9A0C90E9C0D090F00EDFFFFFFFFFFFFFFFFFFFFFFFFFFCBDB009000DFBDBBD99F9E9B090B90B09A90B0909CA9B09BD099A99E9DB9DA9F0F9DBEDBDFDFF9FE990F09F9EADBCBCB9FFFFFFFFFFFFFFFFFDA9A0090A9CA900C09A009000C00E000A009A0A90A9A0F00F0FBEFFFFFFFFFFFFFFFFFFFFFFFFBFF0F090000EFF90DA9E9099C90B0C9090909D0BC9B9D0DBCBDBD9DB99A9CB9D090DAD9FCFADE9F99DA90DADA9DADBDBCFEFFFFFFFFFFFFFFF0F9C90B0A9009009A9009C0A9A900909AD0F00C90E9C0F00F0FDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFF900000CFF9ADBD990BDA9B0D09B09E90B0090B0909A99909BCB900909000090909CADF9F9F0BCA9DA9BDBDADACBCB0FFFFFFFFFFFFFFF9FB0B0BC0900B00B000090A09C00B0AC000000B0E900B00E90F0EFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDE900000FFBDA9ADAD9AD09B0B00909AD09B0909CB99DADBC9909090000990000000909C000D0990090DA9CBC9FDBCF09EFFFFFFFFFFFFFEDAD00900F00B0CB090A09000BC0D09ADA9AC090E9C0F09E00F9EFFFFFFFFFFFFFFFFFFFFFFFFFFFEBFF90000FFBDF9DB9AD9BD0D09BCB090B0D000DB00F099009000000909C0AD0BC909C0A909000009A0F9FA99F0F0F9F0F9EFFFFFFFFFFFFBF9A9A0B009009000A90009A90B00A00000C9AC090A900E99F0EFFFFFFFFFFFFFFFFFFFFFFFFFFFF99E9A090CFBCB9FB0D9BC9A9B9C990DA99DA9B900990900090090D09C9C999909009A99C9E9A900000D009D0F0F0F9E9F0FDFFFFFFFFFFFBF9E9C0900B009A9090C0B000C00009C90F09A00B0E9C0F09E0EFFFFFFFFFFFFFFFFFFFFFFFFFFFF9EF0909000F9DBDA9DBBC9B9D0A9A09A9C9A900009000000909B0B0909A9B0F0F9F9FD9E9BDAD0B090DB0BF0F0F9F9EDBCFFFFFFFFFFFFFFFCB090B0A900B000A09A90CB0B09E0A0A00000D0C900A90BC0F9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BE90B900AFF9F9BC99BD0B9D09BC99A9909909000909BCB09D9BDBD9D0909909E9AF9FCBDB0D0DAD09C9B9DADADFADBCFDFFFFFFFFFFFBFBDA90D00B0CA90D000090000A09D09C9A9E0A9A0F0C0E0B0E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD99FD099C9BCBDADBDADBD0B99E99E99E90000000009C990F0BC909A9A9E90E909D9CF9F0FDB0A90BF09EDAF9FDADF0F9FFFFFFFFFFFFFFADADA0A90C9090A09A90A9090DA00A000C00900C900B09C0F0EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9B9B909FDBDBDB0BF9B0BC0B90B90B9090D0A909E0B0F99999B9C90D090900BCBCBDADFCB0D9DED09E9BD9E9EDBEDBCBDFFFFFFFFFFFFDBB09C90A9A9A909A00A90AC009009C9A90B0CA9A0F0CE9E9ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBD09CFBDBDADBD9FCBD9BD0F90F9090A909C00990D09AD0AD0B09000009D09CBDADBCB9E9ACB9B099EDAF9F9EDBCBDBFFFFFFFFFFFBFBC9A9A0900000A0900D0009A9AC00A0CA0C0900D009A9A0DE9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDB99B0BDB9EBDBDBE9B09A9A99E909CB090909A9009A9090D909090090900ADADAD9ECBDE9D9BD0C9EF9BD0DAFDBEDE9FFDFFFFFFFFFFCBAD009B0A9E90D009A009A00009F090909A0ADA0BC0D0DA0ADFEFFFFFFFFFFFFFFFFFFFFFFFFFFBFB9F9F999FFFBDB9E9F9F9F9D0DA99B9B9090DA90909AD0BDA909E99A90000909090DADBDA9DA0FCB90990F0FBFD0BCBF9E9FFFFFFFFFFFFBDBAB00C9C090A0BC090A0909CA000E0AC00D000D09A0A0D0F0EFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DB9F9F9CFBDFBDA9F0F9F0B0B99F0D09090009C909E9090990B0900D0909000C9E9AD0DADF0D9090090F99F9C9EFDFD0FDFF9FFFFFFFFFFFF0D09B0A9A0B0900B009C0A0A900A90909A00E9A0E0D0F0F0FBDFFFFFFFFFFFFFFFFFFFFFFFFFFBDB9F9FB9FBDFBDBDF9F9FBD9F9CB09B9F9A0900B0A9090B0DAD0990B0090090DB090DCBCBD0B9CA90BCB9CFADBFBDADAFF0F9FEFFFFFFFFB0B9A9E009009C00A900B00A9C9009C00CA0D0900D09A0F00F0DEFFFFFFFFFFFFFFFFFFFFFFFFFF9DBDBDB9DBDFFBDBCB9BDAF9A90B99F0D0909909009D0909C9090900D0900C90000D0F0BDAD0BCA990C90C9B9DBCD0FDBDADFB0DFFFFFFFFFFFCBD09CB0BCA9A90A9C0090000F0A90B090A0E9A0E0D00F0BE0FEFFFFFFFFFFFFFFFFFFFFFFFFBA9F9FBDB9BDFBFF9F9F0F9DF9F9CB09B9B0900F0900009E09A90B0DB0909A909090A90DCBDADD9DA9909B9C9E9FBFDBEFFDBCFF0DFFFFFFFFFBF0BA0900090090D0A900A90B000000C0AC9090C909ACB0C0DADBFFFFFFFFFFFFFFFFFFFFFFFF9D990D9BDBDFFFDBF9F0F9FB9F9B99F90D0DB99090090B0990D09090090909090909D0F0BD0DB0B09CA90D0B9DBCDFBCF9CBEF909FFFFFFFFFBFDBC90A9E9A0B0A0900A900C00B00F0A90900E0B00E090E9FADEFFFFFFFFFFFFFFFFFFFFFFFF9B0B0FBBF99BFFFBF9E9F9FB0F9AD9E9F99B90CA9009009C90B09F9099090D090BD0F0F99C0FF0F9D099C90BCDADFBEDF9FBFD9FBDEFFFFFFFFFCBA09AD0900D0C09A09000A90BC900900ACB0900F09CAD0A0DADEFFFFFFFFFFFFFFFFFFFFFFFF9909DBD9BFFFFFF9F9F9FBDF9F9BDB99AD0B9990990B009A9C900090009A9B9D0B99D9EDB9099090B009A9D9BDBFDF9FFCF0FADF9DFFFFFFFFFBD9F00B0A9B0B0B09CA9090000009A09C900CAD009E09AD0F0FAFFFFFFFFFFFFFFFFFFFFFFFFB90909FBD90DFFFFF9F9F0DBFF9F0BDAD9B9C9A9D009090009099909099C90DA9D9E9ADBFDAD0F9E90900DA9E9FD9FFF0FF9FDB0FBFFFFFFFFBFBEB0B009C000090CA900E090F0B00C90A0CB090ADA09E0ADAD0DEFFFFFFFFFFFFFFFFFFFFFFF90DBDB9090DBFFF9FF0F9FBDB9FBDB9F9BD9B9D9A9B0909090B000B0DADB9F9DB0F9FFDFDFDFB909090F909D9F0FFF9FDF9EDADFF9CFFFFFFFFFF9BC9CB0B0F0B0B0909090A000000B0E90B00AC9009E90DA9EBEFFFFFFFFFFFFFFFFFFFFFFFB9DB909090B0FFFFFF9FDBFDBDFF9F9F9BDB0D9A999C90C909090DB9DB9BDBDBB9DBDBDBFFFFBD0DA90990DF0BDFFFDFFFBEDBF9F9DBFFFFFFFFF9BCA9A900909C0000A0A000909AD0009C009C90E0F00ADA0DBCFFFFFFFFFFFFFFFFFFFFFFFF90999909090DFFFFFBF9BDFBFF99F9F9BD0DBBD9F0909990B000909DBD9F9DB9DFBDBDFFDFFFDFB990DACBB9FDBDFFFDFDFDBDE9EFBDFFFFFFFFBFEB9000E9A0A0B0F09090B0CA0009E00A9A0A090009E90DAE0F0FFFFFFFFFFFFFFFFFFFFFFFB9CBCB090909FFFFFDFFFBDF9FFBDF9F9BB9D9B09DBDA9A909D909A99BD9FBDB99DBDBDFFFDFFF90DA999D0DADFFDFFFBFFBDBDB9FD0FFFFFFFFE9BCBDB9009C900900AC000909CB000909C9C9CA0F0E09EAD0F0FFFFFFFFFFFFFFFFFFFFFFFF99B99990909FFFFFFBF9FDBFF9FDBFDB9DDBBD9F9A999D09D0A09C9DBD0BD9F9F9BDBDBDFFFFDBDA99CBCBDBDBFDFFFFFDEDFEF0DFB9FFFFFFFFBFF9A00CB9A9A9E0A9090B00A000009AC0A0A0B0D0009E090F0FFEFFFFFFFFFFFFFFFFFFFFFB9C9DB90090F9FFFFFFDFFBDF9F9BF9BDF9B9D9B9D9BC9A99A999B09A9B9DBF9F9BDADFDFFDBDBD090DB9F9F9FDFFFFFDFFBFDB9DBF9CFFFFFFFFFF0BC90B00000090909A00009090BAC0B09C90C0A90F00F0F0F0FFFFFFFFFFFFFFFFFFFFFFF999FB909900DBDFFFFFBDBDBFFBFF9FDB9F9F9BD9AD9B99C9090D099D0DB9C9F9F99DB9FFFFFEDBDBF0FDBDBCFFDFDFFFDFDBFDEBDFB9DFFFFFFFF9F09AD0ADA9E9A0A0C009E000E00909C0A00B009E00F00F0F0FEFFFFFFFFFFFFFFFFFFFFFBF909DBD0990FBFFFFFFFFFFF9F9FDB9FDB9F9F9BD9BD9E9B9DB9A9CB9B9CB9F9F9F9BDFDFDFDBDAD9DB9F0FDBDFBFFDFBFFFDAF9E9FFBCFFFFFFBFFAF09A90090009C90A90090B00900A00909AC0F090F09ECA9E9FFFFFFFFFFFFFFFFFFFFFFF999FB909009CBDFFFFFFFFF9FF9FBDF9BDF9F9BD9BD9A99C9A9D99B9C9DB9DBDB9DBDB9FFFBFFFDBEBDEDBDBDBDFDFFFDFDFFFDF9FF999FFFFFFFF0F9CB00F9A9A90A0090A000009A00D0BCAC00900CA00E0B9E9EFEFFFFFFFFFFFFFFFFFFFFB9ADBD9B9090FFFFFFFFF9F9FF9FF9F9BDB9B9BD9F90B9DB9B9DA9E9DBDB9FBDB9FB99DFDFDFDFDBF9DF9BDBDFDFFFFBDFFFBD9F0FFFB0FDFFFFFFBFB0B0E9000C90A90B0009009A0000A00090B0ACB0DAD0D0E0F0FFFFFFFFFFFFFFFFFFFFFF9D99FBD9A9090FFFFFFFFFFFDBDB9F9BD9BDDBDBB0DBDB9D0DA99990B9BD9C99FD9DBFBDFFFFFFFFDFF9FCBDE9FBDBDFFDFDFFEBFDFFD99FFFFFFFFF0F0900B0B0A9C0000000A009C9090DA000C9090A09A9ADAD0FCFFFFFFFFFFFFFFFFFFFFFB90F9FB9D09009BFFFFFFFFBFFFDB9FDBDB9BD9D9B999CB9B9DBCBD9D9CBB9FB9BF9D9F9FDBDFFF9FDADBF9F9F0DFFF9FFFBDBD9EFFFBDADFFFFFFF9F0F0B9C00900B0F00B0900C00A00A00D0B00CAC9CAC0DA9ADAFFFFFFFFFFFFFFFFFFFFFF9999DBDB9B909CFFFFFFFFFFDB9BDF9BE9DBDB9B9DBDB99D09B0990B0B9D9F9DBD9BBD9FDFFFF9FFFBDBD9F9BDBF9F9FF9FFEFFFDFFFF99FFFFFFF0FBA90C0B0F0A900009000090A9000D090AC0B0090A90FA9EDADEFFFFFFFFFFFFFFFFFFFF99E9FBFBD9909A9FFFFFFFFFDBFFDB9BD99B999F0DB099BCB9F99F9F9D9F9BD9BDBF9D9F9FFFDFFDDADBDFAD0F0F9FDFFDFFDFDADAFFF99EDFFFFFFFF09CB0B09009C90B000000A000000A0E9090CB0AD0CB00D0ADEFFFFFFFFFFFFFFFFFFFFFB9999DBDBF9F99C9FFFFFFFFFFF9BDBDBDBDBDB9B99DAD99D90F09090B99F0BBDBD9F9BDFFDFBDBFBDBF09DBD9F9CBE9FFFFFBFFFF9FFF09FFFFFFFBDFA90900CB0A0A0000A09000909090900CA900D0A9ACBCAF0B0FFFFFFFFFFFFFFFFFFFFFF99E99FBDBF9BF9FFFFFFFFFBDFF9F9BDB99DAD9DB999A9B0B99F9BDBDAD9D9DA9F9BD9BDFFDFFDEDBD9F0B0A90FBDFF9FDFDFDBDFFF9F909FFFFFFFADAB0E9A00D09090900000900CA00C0B0B00A9A9C0C9CBC0FCFEFFFFFFFFFFFFFFFFFFFFB9099F9DB9DBD9B9DFFFFFFFFFBFDB9DB9F0B99B09CB99D09D0B09C99099B9BD9F9F99FDFFFFF9F9BDA909C9DAD9CFBDFFBFFFFFF0FCF9F90FFFFFFBFBD0C9090B0A0E0A00900A00A0000B00C09C90C0A0B0B0DB0FAFFFFFFFFFFFFFFFFFFFFF9D90F9FBFDBB9F0FBFFFFFFFDBFDBBDB0D9BD9F9D9B9CB0B9A9C909B0F9BCBD9B99F9F9BFF9F0FA9D00D0B09A90ADBCF0DFDBCF9009FB090FEFFFFFFE90B9A0E0090909C00000000909000B090A0E9AD0D0E9EA0F0FDFFFFFFFFFFFFFFFFFFFFBB99099F9B9DF9F09000FFFFFFFBFDBD9BD0B090B0DA9090C9090B0C99C999B9F9F9B9DFDFFBD990099AD09C9E9DADF9FBFFFFFFB0EDFF909FFFFFF9F9E00090B0AC000090090090000090C0AD09000A9A90C9EDADAEFFFFFFFFFFFFFFFFFFFFF909AD9BDB9B9B9F09000FFFBDFDBF9BD0B99DB9090909C909A09C9000B09E909F9FDB9FFFDFBCBDA09009A9090BDADEDE9FDF9FC90FFFF90DFFFFBFEB9E9E09C909A9A00A0000000E000F09000A0D0D0C0FA090F0DFFFFFFFFFFFFFFFFFFFFFFF99D9ADBDBDFBD90009DFFFFFBBF9FB9B9C9A0DB0909A909009090B0909C99F99F9BDBDFFF9990090009090BCBDADBDBDF0FFFFB0E9FFFFFFFFFFFF9BC9090A000A00090000000A90900000ACBC9A0A09A90DAE9EBEFFFFFFFFFFFFFFFFFFFFFB90909090F9B99A0BCBEFFFFFDFDBD9C9CB999909AD090A9090000090090B09BF9BDBDFF9B0F009090909E9C9CADBCBEDADFBCF0D90BFFFFFFFFFFBFCA9A0A90BC90D0000900090000090B09000090DAC9ECBC9ACFFFFFFFFFFFFFFFFFFFFFFFF99090BDB9F9F00D000DFFFFFFBB9BB9B90BC9A909A90990D09090909A090F9C9BDBDBDFFD90090000000009A9D0FBC9ADAFDFFB0EFDBDFFFFFFFFDA9B0C900C0A000A0900000000A00AC0CA90B0E009A09A0F0F9A9EFFFFFFFFFFFFFFFFFFFFFFB9BDDBDB990900F0F0FF9FBFDBD9C90099B0DBD09DA0D0900B0000090090B9F9F9F9FFBFB9ADB90D0BD9BC90A90DBD90DEBEDF9EFFFFFFFFFFFBFF0F0B0DA9090B090A0009000009009A90C0C090BC0DAC9AD0EDEFFFFFFFFFFFFFFFFFFFFFFFFFDBB9B9F00009000FFFFFFFBDBA9B9000C9B09B0099A0B0D090909C900909BDBDBDFDF90D9000909000000F0DE9CA0CBDFDFB0CFFFFFFFFFFFFEBF0900A00AC000C0090000A0D0000000B0B09AC009AC9AD0AF0FFFFFFFFFFFFFFFFFFFFFFFFFFB9DBD900000A00F9FFFF9FDB9D9D09009B0D900900090909090009A99E9FDB9F9FFFBC9A09090A00000000DA9A090BCFBEFC0FFFFFFFFFFFFF9F090E90D090B09A90000009000A09A9C000A09ADAC90BC0F90F0FFFFFFFFFFFFFFFFFFFFFFFFFFFB90009000C90CFFFFFFFBD0B0B90900090A9000000CA90000900900909B9FBDBDF9B0DB000009000000CAD09000CBCDFFB9EFFFFFFFFFFFFFADA900A0A000C000C0A9000000900C0B0D09C0009ADACB00E09E9EFFFFFFFFFFFFFFFFFFFFFFFFFF090000090000FFFFFFFFBD9F0BD090000900000000DEB900090090BD0FD9DBDFFF9B00900900000000ACB00C09CFBE9FF0CFFFFFFFFFFFFBDBCA9090DA90B00A9000000000000B000A0E0BCBC00090F090E9EFFFFFFFFFFFFFFFFFFFFFFFFFF90000000000F0FFFF9F9FB9A99C9B0900000000000DA9000900090AC9B9BBF9FBDF9C900090000000000900090CBD0DEF00FFFFFFFFFFFFBDEB090E00000A009000900900B000000AD09090009ACB0E090E90FADFFFFFFFFFFFFFFFFFFFFFFFFB000900000000FFFFFFFF9F9D0BB0D000900000000000009009000999ADFD9FFDFB09A0900009000000000090E9FCBF0F90CFFFFFFFFFFFFFB09CA90B09C90CA00A00000000E09C9000A00E9AC90C909E09AD0FFEFFFFFFFFFFFFFFFFFFFFFFF90000000009C9EFFFFBDFF90B90D9B0900900000000009000000909E9F9BBF9FBFDBD90090000000900009ACBDF0F0CFDA9EFFFFFFFFFFFBCBDA9000C00A009000900A000009000A90D0900090A90AC09AC0AD0FFFFFFFFFFFFFFFFFFFFFFFFF900000000000A9FFFFDFBFBD0F0BCBDBD000090000090000B009009090F9D9F9F9F9A9D0A990090000D0C099EFBF9F0EF90CFFFFFFFFFFFFFDADA9CB0B0900A0D0009000090000B0CA0ACA90E0D0BC9AC090DADADFFFFFFFFFFFFFFFFFFFFFFFB000900900000CFFFFBFDFFB909090909B99DA0909A0C9A9009A09A0BD9FBFDBFF9E90A90CA9D00909A9BF0FDBC9E0DF9A0CFFFFFFFFFFFFBE900000000CA9000A0000090A0000C0090909C009A0000009ACA0FFFFFFFFFFFFFFFFFFFFFFFFFF9000000000900FFFFBDFFBD9CB0CB0F9E9CB099B0D09B0900900909D09AD9DBDF9B990909090A09ADADAD0DA9E9E0DEBE900FFFFFFFFFFFBE90E9A90D0A90C00090000000C0B090B00AC00A9A00F09ADA0909FADFFFFFFFFFFFFFFFFFFFFFFFF90000000000000FFFFFFFFFB900909009A90BCBCB0B0090900900900F9FBAF9B9F0F0F000009090909090B0D00009ADF900CEFFFFFFFFFFFBDB00CA0A900000B00009000000000009090BC90D000AC0090E00CFAFFFFFFFFFFFFFFFFFFFFFFFFB000000000CA90CFFFFBFFFFF9B00A9009009090909090009009009A090D99F9E9F99099A90000000000000090DAC9EEF000FFFFFFFFFFFDFADB009000CB0B0000A00000090000B0CA00000A0AD090B00C90FADFFFFFFFFFFFFFFFFFFFFFFFFF90000090009000FFFFFFDFF9F9C90900900900000000000000000BC9DBDA9E9E9FDBDB0D0090000000000000A0009EDF9000EFFFFFFFFFFFADA0DA0C0B000000D0900090A000000009C90B09C900AC0CA9ADADBFFFFFFFFFFFFFFFFFFFFFFFFFB000000000000E9FFFFFFFFFFB90D0000000000000000000909C9090B099F9BDBDB0BC9A99C0900000000C90C9ADEDFB0000FFFFFFFFFFFBFDA9090A90090C90A000000000A909CB00A00C0A00AD09A900CBEFEFFFFFFFFFFFFFFFFFFFFFFFFF900000000000900FFFFFBFFFF9FB09909A90090900000090C0B0BCBD9FAD0FDBDADBD9F9F0B909C90900900F0FCFFFFF9000EFFFFFFFFFFF9A9CA0D000E0A0A00000000090000000909CB09CB00A0C0A9E9C9FFFFFFFFFFFFFFFFFFFFFFFFFFF9000000000000900FFFFFFFFFF9F9AD9C90900A009090009BC9F990BC9DB9BCBF9BCBF9E9F0F9EBE9CBCADADFFFFFFFFA900DFFFFFFFFFFFEDA900A09090090090B0900000000090E00A00000C9C9A9C00EAFEFFFFFFFFFFFFFFFFFFFFFFFFFF900000000009AC0BDFFFFFFFFFBDBDB0B0F0BD909CB09F9E9FBCBDBDBFBCFDBFDFDBDBF9BF9FF9F9FBDBDFFFFFFFFFF90000EFFFFFFFFFFFBF9CB090CA00C00A00000000000900A0909009E90B0A00C0BCBDFFFFFFFFFFFFFFFFFFFFFFFFFFFB00000000000C090D0FFFFBFFFFDBDFBDBD9BC90F9BCBDBDBDB9F9BDADBDBDBF9B9BDBDFDFDFF9FFFDFFFFFDFFFFFFFDE900CFFFFFFFFFFFBC9A0000A9000B00D0000000009A000900A0DA00E00D0F0B0CBCEBFFFFFFFFFFFFFFFFFFFFFFFFFFF900000000009A90A9FFFFFFFFFBFBBDBDBF9BF9BCB9BF9E9F9F9EDBDBDBF9F9FFDFFBFBFBF9FFF9FFFFFDFFFFFFFFBFB0000FFFFFFFFFFFFFAD0F0D000B009A00C9000900000000C9C0090909A000009ACBDEFFFFFFFFFFFFFFFFFFFFFFFFFFB000000000000C09CA9BFFDBFFFFDF9F9BDBDDBFDBDFDADBDBCB9BDBF9FDBF9F9FB9FDFDBDFFDBDF9FFFFFFFFFFFFFDFFB000EFFFFFFFFFFBDAB000A90C00C00090A09000000000B000B0C0A00C9A9E9E09EAFFFFFFFFFFFFFFFFFFFFFFFFFFFF9000000000909A090FDFFFFFFFFBFBDBF9FBBDBBDB9BDB9BDBDBDBDF9FBDFFFF9FF9F9FFFBDBFFBFFFDFFFFFFFFFFFF9C90CFFFFFFFFFFFFF9CB0900A90B0090A000000000090000B000A90DA9AC00009E9DFEFFFFFFFFFFFFFFFFFFFFFFFFFB000000000000AC90FCBF9FFDFF9F9DBF9F9FDB9DB9FDB9FDBDBDF9F9FBDFBDBDBF9FBFF9FDFF9FDFDFFFFFFFFFFFDFBCB000FFFFFFFFFFBEBCB00CAC900000E0009000000B00009009C90C000C909E9E00EADFFFFFFFFFFFFFFFFFFFFFFFFFFF90090000000009E09ADFFFBFFFF9FBF9F9F9BDBF9F9BDF9B9ADB9FBDF9FBDBDBDBF9F9FFBF9FFFBFBFFFFFFFFFFFFEDBD00CFFFFFFFFFFFDB9CB00900A0CB09090000090000000AC00A00B0B000E0009E9DAEFFFFFFFFFFFFFFFFFFFFFFFFFFF900000000000D09C09ADBDFFFFFBD9F9F9BFDBD9F9F9BDF9FDBDBDBF9F9F9FBDBD9F9FDBDFFDBFDFDFFFFFFFFFFFFFFFAD000FFFFFFFFFFFEB0C9A0009000000A00A900000000009A909000C0B090F0000E9DAFFFFFFFFFFFFFFFFFFFFFFFFFF000000000900000B0F9FFFBDBF9FBB9F9F9BBDBF9B9FDB9DB9F9F9F9FBCBF9FBDBFBDBBDFBDBF9FBFFFFFFFFFFFFDFFFB000EFFFFFFFFFFBF9CB0C90BC0B00AC09000000000900900000E90A9C0E000ADADAEFFFFFFFFFFFFFFFFFFFFFFFFFFF90000000000B00F0D9E9FBDFFFFB9DDBF9FDF9BDBDF9B9FB9F9F9F9FF9DBDF9F9F9DBFDFBDBFDFFFDFFFFFFFFFFFFFFD0900FFFFFFFFFFFDBCB009A00000C90900000000090000CA0CB000D00A909AD00DADBFFFFFFFFFFFFFFFFFFFFFFFFFFF90000000000C0090ADBF9FFBF9F9FBBD9F9B9FDB9B9F9F99F9F9BDBF9FBF9BF9F9FBD9FBDBF9FBDBFFDFFFFFFFFFFFFFF000CFFFFFFFFFBF0F09A0C90B09A00A000009000A000A90900090A9C00AC0A9E0AEDEFFFFFFFFFFFFFFFFFFFFFFFFFFB900E00000009E0BCBC9F9FDFFBF9DBBDBFDB9BDFDBDB9FF9F9FDBDDBD9FF9DBDBDBFBDBFDFBDFFDBFFFFFFFFFFFFFFF0F000EBFFFFFFFFFF0BC90A00C0009000B000000000000000090A000A9C909C009C9EFFFFFFFFFFFFFFFFFFFFFFFFFFF900090000009009C9FBFFBFBF9F9FBD9F9B9FF9B9BDBDBF9F9F9BDBBDBF9FFBDBDBDBDBDBBFDBBDBFDFFFFFFFFFFFFFF9000ADEFFFFFFFFF9BCA0090E09AC0C9000900009009000B00E0C90D00A0E0A0F0FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0000000900E09E9EBDF9FDFDFBF9DBB9BDF99BDBDB9B9DF9F9BDBBD9F9F9B9F9F9F9BDBDFDBFDFF9FFFFFFFFFFFFFFE0000DFFFFFFFFFBCBC909E00900090A0000000000000000C909000A0B0D090D0009DEFFFFFFFFFFFFFFFFFFFFFFFFFFFB000C0000009E90BDFBFFBFBFBD9FB9DFDB9FF9FDB9F9F9B9BDBF9FBF9FBFDFBDBF9FDBDB9BDBF9FFFFFFFFFFFFFFFF99000EF9EFFFFFFFBF0B000B00B00A090E900000000000B00A000B000C0A0E0ADACA0FEFFFFFFFFFFFFFFFFFFFFFFFFFFFB000D0000000F0DADF9FDFDFFBF9FB9B9FB9F9B9F9FB9F9F9F99FBDBDBDBF9FBDBF9FBDFF9FDBF9FDFFFFFFFFFFFFFF00000EFDFFFFFFF9F0DA90C00C09000000A90009009000090C0900D09090909009F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFF9000A00000CB0F0FBFFBFBFBDF9F9FBDF9F9BDBFDB99F9F9F9FBDBF9F9DBDBDBFD9FBDBF9F9FFDFFFFFFFFFFFFFFFF0B000CFBEFFFFFFBEFB00CA90B00AC9A900000000000A000009A000A0A0E00E0E9E0EFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9000090000000DBFDF9FDFDFFBF9F9DB9BDBDBF99BDFB9B9F9BDBD9FBDBFBDFBDBFF9FF9FFFF9F9FFFFFFFFFFFFFFB9000DBF9EFFFFFFFF90CB090000090000000000000000090B0000F090D090909000FDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0000000000D0BCFBFFBFBFFBD9F9FBDBDBFBD9FBDB9DF9F9BDBDBBDBFF9DF9FBDBDF9BF9F9FFFFDFFFFFFFFFFFFFC00000EF0DFFFFFBF0FB00A00AD0A00A00A9009000000900C000D0000A00A0E0E9E0AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9000000090A9CBDF9FFDFBDFBF9F9FBDBD9FBF9F9FBB9F9FDBDBDF9D9BFB9F9FBDBFFDFFFFDBDBFFFFFFFFFFFFFDB900000CBEFFFFFFFF0F9D090000D0900D00000000900000009A000B0D0D0D09000DCEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF009C0000000000FFFFBFFFFBDBF9F9DBDBF9F9F9F9F9F9F9BDBD9BFBFDBDFBFDBFDBDBF9F9FFFFDFFFFFFFFFFFFB000000FF0FFFFFFFF9F0A00CA90A00AC90000000000000009A00090C000A00A00E9EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB900000000009EDBDBFDFFFBDBF9F9FBFBF9BDB9F9F9F9BDBF9E9FF9F9BDBDBDBFDBFFDBFDBF9FDFFFFFFFFFFFFD000000FE9FCFFFFFF9EF0DA900C090090A00B0000000090000009C0B00A90B09E900EDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00A0000000009A9FDBFDBDFFF9F9FBD9F9FDBDBDB9F9BDBF9F9FA9F9FF9FBDFBDBFDBFDFBDFFBFFFFFFFFFFFFFB00000C0FEBFFFFFFFFB9B00A09A00AC0009000900000000000D00A0009C0C0C000F09AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9090000000000CBADBFFBDBDFBF9FBF9FB9FBDBF9BDFBD9F9F9DBDB9FF9FBDFBDBBDBF9FBDFFDFFFFFFFFFFFF0900000F0DFEFFFFFFFEDAD09C090009A00000000000000000B009000000B09A0BC00EDFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00C000000000909DBDBDFBFBDF9F9F9F9FFBDBDBFDB9FBF9DBFBDBDF9FF9DBBDFFDFF9FFDFBDBFFFFFFFFFFF900000000BEFFFFFFFFFB9E9A00A0CB0009CA90000900900000000009ADA000A09C00BCBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB00000000000000DA9F0FBDBDB9FBF9FBFDB9F9F9DB9F9F9FBF99F9FBFB9FBFDFB9FB9FF9FBDFFFDFFFFFFFBD00000000FEDBFFFFFFFBDE900090900000000C0000000009000009E0000909C9C00B0CBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9000000000009ADA9DBDBDBFFBDBF9F9BFF9FBFB9F9F9BDBDBF9F9F9DF9F9FBDFBDFF9FFDBF9FFFFFFFFCF00000000D0FFFFFFFFFFFA9AC9AC0A009E9A900A900000000000900900000E0A09A00CBCBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB00900B000000009C9ADB9E99E9FDBF9FDB9F9F9FDBF9FDBDBDBDBDBFBDFBF9FBDFBF9F9BFDFF9FDADFFFFB90000000ACFBEFFFFFFBFDF9A00900D000000A900000000000000A000B0009000C0D0B0ACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB00E000000000000BC90F9FF9DBBD9FBBDFBF9F9B9FB9BDB9F9FBF9DBFBD9F9FBDF9FBFDBF9FFFFFFF0F9000000000CFBCFFFFFFFFFBAC9C9A00A0A900C00000000090090009000C0BC00D0B00A0CDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90000C900000090900BC90B99FBDFBF9DB9F9BDBDF9DBDBDF9FBD9FBF9DBFBFBDB9F9FDBF9FFE9F9F0F9090000000ADADEFFFFFFFBF0DB0A0C09090C00B000090000000000000A90000B0A00A9C9EAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0090000000000000909AD9CB9CB9D9FBDBDBDBDB9FBDBDB9BFDBFBDDBF9FDBDBFEBFDBD9E9F9F0F090000000000C9EF9FFFFFFFFFFFAC90090AC000B0009A00000000000000900A900090D0C0A09CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90C000000000000000090A9CB9FBAD9FBDADBADBF0F9F9FF99BC9FBBDBF9ADF9BD9DBEBF9E9F0F0F090000000000CBEEFFFFFFFFF9F9BCB0A090A900C0A000000000090009AC000C00C00A090D0EBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0009009000000000900090B0D09DB099B9BD9BD9F9F9F99FFDBF9CFBD9FDBBFDBFB9D90F09CB090000000000000FC9FFFFFFFFFFFBE900C900000A90900090000000000000009000B0A090CA00FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9000CA0000000000009009090BDB0BCBC9D0BD0BDB9F0BFB09B90B990B09AD09AD0DA0F09CA0000000000000CCEFBFEFFFFFFFFF9E90E900CA0D0000A000000009000000009000B0009C0A90DA9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0000C0000000000000000000000909090AD00BDA9E9F009DBC0F9CBC9CBDB0F00B0900000909000000000000BFBCFFFFFFFFFFFFBE90A0B0900BC090C9A0000000000000000A0000C009C0A0C0FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9000900900000000000000900900900A909A90090909F0B00B90B009A000900900009009000000000000000CEFDEFFFFFFFFFFFEDBE9C00000000A000000900000090009A009C009A0A0090CBEFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFF90000000000000000900000900000900009090000000900900000900900000009000000000000000000000FB0FFFFFFFFFFFFBFBC9A090ACB009000A000000000000000000009AC090DA0E9EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB000C00000000000000009000009090009000000900090090009090090090090000000000000000000009CEBCFFFFFFFFFFFFFFDE9A90AC9000A0C090900000000000000009A000000000900FEFFFFFFFFFFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFF009A00000000000000000000000009009009000090000000000000000000000000000000000000000E0FFFFEFFFFFFFFFFFFFBBF0C9000009009A00000000000000000900000900F0ACADA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A0C0000000000000000009009000000000000000000000000000000000000000000000000000000C0F09CFFFFFFFFFFFFFFFFD0B0A09A0AC0A000A090090000090000A00C9A009009000CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF900900000000000000000000009000000000000000000000000000000000000000000000000000000CEFEFFFFFFFFFFFFFFF9EBC9C0C09009000D0000000000000000009000C0A00C0BCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000ACFFFFFFFFFFFFFFFFFFFFFEBD0A9000000009A0000000000000000090A000090C0B000CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC00000000000000000000000000000000000000000000000000000000000000000000000000CFFFFFFFFFFFFFFFFFFFFFBDBA90A9A00B0AC0000A90000000900000000009A009000CB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDAC9000000000000000000000000000000000000000000000000000000000000000000000CFFFFFFFFFFFFFFFFFFFFFFFFDAD0C009C00900009000000000000000009000000AC90B0CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000CFFFFFFFFFFFFFFFFFFFFFFFFBAF0B009A00000B0000000000000000090000000C900A0C0FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFBCD9000000090E000C00900000000000000000E09A00900BCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9A000000000000000000000000000000000000000000000000000000000000000000EFFFFFFFFFFFFFFFFFFFFFFFFFFBAE9A9E000A009009A0000000000900000B0090000A0C000CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCD00000000000000000000000000000000000000000000000000000000000000000CFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB0C0090C09000A0000A000009000000000000009C0A90E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA0B00000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF9AD0B00A0900E000090090000000000009000009000900C9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D9C000000000000000000000000000000000000000000000000000000000000CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEDA900000000090000000000000000000000900A000A90A0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A9E090000000000000000000000000000000000000000000000000000000EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDB9CA09C900B000AD0A00000000009000000A0000C9000C9C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF0090C00000000000000000000000000000000000000000000000000000EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFB90CA00AC0000000000900000000000090000900A0C0A00FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E90A9A09000000000000000000000000000000000000000000000000CFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFBDADA9000000090000900000000000000000000009009000FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9CAD00D00A90000000000000000000000000000000000000000000CFFFFFFFFFFFFFFFFFFFFFFFBEFFFFFFFFFFBFDAD000090090AC0900000000000000000000090A0000A09E0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDA9009A0A900D0E000000000000C00000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0B9000E0000000A0000000000000000009000000D00000D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9E9E0D0C0F0A9009C90000C90CA000C0000000000000000C00DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FC0E9A00000900000900000000090000900000900A00C0A0EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA900B0B9A0D0E0F0A0CBCBADA90C90000CBC9000000000CBFDAFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFB9B0000900000900000000000000000000000000000909C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9CAD0C0C0F0B090B0DBE9FDA9BCBEFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFCFFFFFFFFFFBFFB0DAC09000A000A0000000000000000000000090009000A00E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDA09A9A9A900C9E0C9A0DAB0BC0F9FFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFBFFB09000000900000900000000000000000090000000000009E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DBC00C0DADA9A9A90DA0DEBDB9A9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEFFFFFFFFFFDBDE9E9A090000090000000000000000000000000000090000C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA09ADA9A009C0C90E09EB9E9E9DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFBFEB9A900000000000000000000000000000000000000000090BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC09E0090C0F0A0B0E90F0DEDBF9EBFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFF0FFBFFFFFBFFEFB9E900000000000000000000000000000000000090000000C0CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F0090E9A909C9C900F0FFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFF9FBDBC9E09000090000900000000000000000000000000000000A9ACBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9E0E900DACA9A0ADA9E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCFFFFF9FFFFBFB09A009000000000000000000000000000000000000090000DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD09090E9A909C9C900CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFF9FFFFFFFFFFFFFFFFFFFFFFFFFBFFFFBDFFEBF9E9E9E9000000000000000000000000000000000000000000000FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADA0E090C00E0A0ADAF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FEFFBEFFFFFFFFFFFFFFFFFFFBFCFBFFFBFBDFFBF9A900009900000000000000000000000000000000000000DADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB90909ACB0B0909C909CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E90DADFBFFFFFFFFFFFFFFFFFFFDFBCF0FBEDFBE9E9AD00000000000000000000000000000000000000000000000ADFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E0C900C0DACA9E0A9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEB0DADF0FBFFFFFFFFFFFFFFFFEBFBFFFDBBEDBF9F9A9090000000000000000000000000000000000000000000ADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B09A0ADA9A090009C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9CA9A0F0DEBEFFFFFFFFFFFFBFDFCBFBFFDBBDBE9AD0A00000000000000000000000000000000000000000000D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD00E90D0000D0E0BCAF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDA0A90CBCBEBDFFFFFFFFFFFFFFFBEBFDFADBFCBE9BDA0900000000000000000000000000000000000000000000ADADBFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9E900A0A9E9A90D090DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9CB009009E9ADBFFFFFFFFF9EDBDAF9FADBBF9E90900000000000000000000000000000000000000000000000BCBDBDEBFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFF09A9C09C000CA0ACA0ACDAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9E90DA0BC9ACBEDBEBFBFFDFFBF0F9AFDBFCBCB9E9A90900000000000000000000000000000000000000000090C0BCBFBDBF9FFFBFFDFFFFFFFFFFFFFFFFFFFFFFBFFFFFBDB0F0C0A9A0BCB09C909C9ABFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9FDA9E09C000C909ADBDEFEBFBCF0F0FD9AD0BDB9E9AD000000000000000000000000000000000000000000000009ADAF0DAD0BCB0F9EBF9FBEDFBFFFFFBFFBFFFFFFFFBFBFEBC90B09C0D000C0A00E9ACDEDBFFFBFAFEBFFFEFFFBFFFFFBFDBEDA9E99A90B09ADADADE9FBDFCB0B90F0AF0BF0BCB090A0000000000000000000000000000000000000000000000000909A09ADA9E9E9E0FADBDADAD0F0F0F0F9CBC9E9CBC9090A00E0B0A0F0B0DA90009A9AC9E9CBD99E9ADB0F0F0F0B0F0BCB0F09A0C000C000000A9A0DAB09C0E90BD9AD0FCBC9E90900000000000000000000000000000000000000000000000000090000000000900000A009A09A09AD0A09A00B00BCB0C9C90C09C90C0900CBCA0D09A09A00ACB0F0ACB0F0F0F0F0F0BCB0F0D0B0D0B0D0BC90C9E9C0F0B090E0AD0B0B09B090000000000000000000000000000000000000000000000000000000009009000900900900900000900000900900000000B0A0A9A0A0A9A0ADA0090A0009009000000090000000000000000000A000A000A000A09A00A900000A9090BCBCBC0F0A9000000000000000000000000000000000000000000000000000000000000000000000000009000000900000000900BC009C90C90C90C090009C0090000000900090009009009009009009009009009009009000009009009000E0C09A90B0090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009E0ACB0E9ACA9E0E9E0A90000000000000000000000000000000000000000000000000009000000000090B0BC9E9CB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090009009000900090000000000000000000000000000000000000000000000000000000000000000000090B09A9090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDFADFBCFBDEBDFADFBCFBDFBEDBF00000000000000000000010500000000000076AD05FE")); - strs.Add(func2(6), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D16540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF9A9FBCBFFD0000000000000C0BCF9BDF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FCF0EFDE9A00000000000000BCB0FCA0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A9A9F9EBFC0000000000000AD0BCF0BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0DACBE9F0A000000000000090BCB0BCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0F0DA0FD000000000000000ADADE90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC909A9F0A000000000000000000B0EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00A0C0000000000000000000BCBC9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0DA9E9000000000000000000009BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000B00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF900B0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000009AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000A0009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000A0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000BF9ED0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000900A0A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF090FFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000B0E909000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000009A0A00000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90090F0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000A0BC0900B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBC009090000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000090A9A0A00000009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE909A0DA9B0900DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000009A090000009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF090B09909009A90BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A0000000000000BE9A000000009A9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD09A09090A9090909009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0090000000000A009E9E000000000AA90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00909D09A9909A090090009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA0F0A000B000000090A09A9A9000000009AF0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09A9A09A900090900B00B0009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE000F009A0000000000000ACB0A00A00009AD0A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0B0D09900909A00009009090900BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000900F00A000000000000090B0E9E900009A0BA90B0ACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9090909B0090B00900B0090900A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0A9A0A0F0000000000000000A009A9A0A000009F0BC090900FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90B090B000B0009009009000A09909009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB0B000000F09A000000000000000000090CB000A0ADABA0A00009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0909A90990090000000009A09000909009BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0B0A0FA9A90F0A0900000000A90000A00A00B0000090A0C9ADA9A000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0909F0909A0090A909A090000900B000A9000FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A090F0B00E00AF090E0000000000A00000000B0000000A909A0000000A9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFF0909A090B0D0B0090900900B0900900B9900B09FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A90BCAA9E9A09A0F00B0B0A900000000090000000A00000000A0B0B000BCBAA90FFFFFFFFFFFFFFFFFFFFFFFFF009F099A909A90BC00A09A90C9A9AC90000090900BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA090AC0B0DA0ADA000F0A0DAF9EBCB00000000000000900000000090E09A0090DA00009FFFFFFFFFFFFFFFFFFFFF09B09B099E909AC09A900000B000909A9C90B09CB090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE90DA009A00A00F0A9AF0F000A90F0B00000000A00000000A0000000B0A9A0000ABA900900FBFFFFFFFFFFFFFFFFFF09B09B09AD09E09000000B00900B0A9A90B0909A909090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A9A0A000A0DADAB0ADAC0AF0009AFAF0A00000000000000A09000009A00F00A00B0D00A00A9B0FFFFFFFFFFFFFFFFFF0B0DB0DA9B0B0900B009000900900D09CA9A900090B0DA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00A90CB090090A00000F0A0B0F00000090F0A00000000A00009A00000000BB0B00900A0BC00000F0B00BFFFFFFFFFFFFF0999A99A9DAD00A90090A090A00A09A0B090DA9B9A90B90909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF009A9EBBF00000ADABADA00B00AF00A09A00009A0000A900900000B00000A00DACB00009A0B0A09A0F0B0000FFFFFFFFFFE9BE99AF9A909A90090A09000900900900B0B09E099090B0B90BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00A000B0F0FFA00A000C0A9A0CAD0F0900000B00000000000000000BCA9A009AFA900000000BA90900BA000000BFFFFFFFFF9BC90BD9ADA9A900B009000B000900900909C9A9BCA9F09909B09FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00A9000A9FBFFF0009CA9ABC0CBA9A0F0A0000000B0090A000A00A00B0A90090A9090A00A000B9E9A00E900000B0F0FFFFFFFA9F9BBF0B09090DA900900090009A09A9ADA90B090B9B099A9F09BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC00000000ADFFFFF00000A90E00AB0000AF00000000000A00090009000000BCA0A00A0A000900FADA9E0A090A9000090BFFFFFFFDB0BC90BCB9E9A909B90B0B0909009009090B00B0F09E9AD909B0909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000A90000009AFFFFFF00000A000B00A9EB0F0000000000000000A00000000B0B9000B09000A0A90BADA909A0BCA00000B0BFFFFFFBF9FBAD9B0B909A9C0B0909A09A9CB9A90B09B0D90B09B9A9B09B9B90FFFFFFFFFFFFFFFFFFFFFFFFFD0000A000000A0009BFFFFF000A9CA9A0F0E00CAF00B0000000000000000A000000BCA00900A000909EBDBA9A0009A09000A000FFFFFF9F9A90DB0F09A9F9AB99A9B0D9A90B09D0B09AD9A0BC9ADADBC9AD09A9BDFFFFFFFFFFFFFFFFFFFFF000A0090000A090000AFFFFFF00090A90CA009ABA9F0000000A000000A0000000000BDA9000AB0B00A0A90A0000000A09A00000B0BFFFFFBCBF9FB0B09F9A9AD99E9F090B0DB09A0B0FA99A9B90B9099A9B99BE999AFFFFFFFFFFFFFFFFFFF0000090000900000000BDFFFFF0000AC0A0A90A0E0C0F00A9A0000900000009A0900000A00A0B000000000A9000000A90F0000000009FFFF9FB90B09F99B09DB9BEB99ADBB09B09BDB9999DA90DA99EB0F9F0B099B0F90FFFFFFFFFFFFFFFFF0000A000A000A00000000BFFFFFE0000B0CB00E9A90BAF09009A090A00A09A000A0A000B0B0000BFA9A0B090009A00000A0BCA090A000FFFFE9EBD0B09AD0BA9AD99EB9B90DB09F09A9AFA9A9B9A9E090B0B9F0F099B9B9BFFFFFFFFFFFFFFFE0009000000A0090A00A000BFFFFFA0000B00F0000A000F000A0A9AE90B00009A0900000000000B0A9A9A00A0A000009009FA900000009FFFF9B99ABDB09A99DB9A9A99E9AB0BDA9BBDBD99BBD0B909B9F090A9B9B9E9ADA99FFFFFFFFFFFFFF000A000A00900000000090FFFFFF9009A00A00AB0E09E0F0A09090A90A009A000000009000000B0F9B0F00F0900000000FAA90A9A09000FFFCB0FAD900F99B0A909099A99D9990B9D0BB0BBC90BDA9B090B9F9BDADA90B9B9EBFFFFFFFFFFFF0A900000900000A00000000BFFFFFE0000CAD0BC0090A00F0000A0AD0B0B0A0FA00A0000A00A000B0BEB0BB0CA000000A9AD9A00000A000BFFBDB990B9B0A9C9909A9B0D0B0ADA9DA9BC9BC9B0B00900F0BC9A90B9B9B9DBDBBDBFFFFFFFFFFF000A09A0000A0000090A00ADFFFFF9000A90A0A0FA0A0A0F09A09A9AB0A09A90B0900A000B009000B0B0BCBB0000000000BAF0F0B0000A00F0B0FB0BC0999A9A9E090D0B099099A99A9B90B09F9B9B99099B09F90F0BCB09AD9B9BFFFFFFFFFFC0000000A00000000A00009ABFFFFF00000B009000F0C90F0A0000000F0BADABCBAF000F9ADA00A009A9AB0FA00000A00BDF090000B0900B9F9F90F9B9A9E9B0999A909090A9009099090B99A909E9A9B0B0B09AF09F9F9B9BBCBDBFFFFFFFF00A90A00900090000000090ADFFFFFE0000E0A0E0B00A0A0FA9CB00B0B09A90BCB9E909B9ADA9A090BAB0F0F090000090BEBA00A09A00A0B0F9A9AB9090DA9909B0A90B009090099A9E99B09E9A9B90DB09DB9DB999BB0B0BCBDB9B0FFFFFFFC9A00E90A000A00A0B000A000BFFFFF0000B00C09A0CA900AF9AB0B00B0BADAF0B0F0FAACAFB0A90A0090B0B9A090A000ADBC9A09A009A9BDB0F9F9CB0A9A9B0BD09990909A009A00909B0DB99B9C9A9B09A900B0F0BC9DBD9B9B9FBDBFFFFFF0A9A90A0000000000000900A9FFFFFFF0000A0B0A00A00E90F09ADADA0C90B0BB00A9090B9ADBDABCB0AB0B0A9E0009A00A9A00000B0000EBDB9A9B9990909090B9ADA909090009090909B09A90B9B0909A9B99B99B0B0B0BE9E9F0BB9BFFFFFAC0CA09E9A000000000A000000FFFFDA0000D00ACB09A00A0F00A9A009A0ADBC00000A0000F0A000B0A90B0ADA9ABDA0090009000000A0F9FBCBDB0BE9BCB0F9B9099090A00090000A90909BD9BDA9DB0F90DA90FA9F9BDB99BB9BBDF0FFFFF00B0B0F000000000B000000000BFFFFFF000A0A0090E009A00F009009A0009A00B0A9000A0B0A90BB09B0A0090B0BDA0D0A00A0A00B0090B0B0B9A9F99009099AD0B9A9A909090009090B09B09A9A99A099A9A9DB999B0B09EBC9DBDBB9BFFFE0F0A0A0A00009000000000000BFFFFFF0009009CB0A000A09EF000A00000000B00000A09000000A0CBA00900A00BFADBA00009E9B00A0A9FBDBDBDB0B0B9A9A999B9C9090909A909A0090B0DB99B9B099A90999A90BE9DBDB99BAB0B9FADFFF000AD0D090A000A0000B0009A00FFFFFFA000E0A00E00B0C0A0F0000000900B00A0B0F9A00000000B00DBA0B000009BE9F0B0B09EBF0900B9CB9A9A9BD90909DAB0DBB9BDB9F9DB99D9B090B09E9CBDB0F0BDA9A9B999BA9A9E9D9F9FB99BFFDB0B0A0A000000000000000A00009FFFFDF0000B0A90B0CA9A9AF0000000000000090FBADA00A00000BBA09A00000A0F9A0A000BFBDFA00BDBB9F9F9F0B0F0B0B9DB909ADB9E9B09F0B999B99B99B99A9B990909D90F0B09BDB9A9A9A9BEBFFFE00CBCB00A0900000A0000000009AFFFFFA00000C0AACA0000C0F0009A00A0000090BBADB0B000009AD009A0000B0DB0000900BFFFFADA9F0F0DA9B9A99909C990B9ADBDB9F9BDBF9B9E9F9CB90B09A9909A9A99A9B9BD9F9A909BDBDBDB9FFF00AB0A0000000A00900A0000000AFFFFFE0000B0A9E90090A0BAF000000000B000A0ADBEFBC0900A00BAFA900000A00A00000BDBFFFDA9A9B9BB9BCBDABA909A9F0B9B99BDB9F9F9F9F9B0B9C9BDB9DA9F09090B9ADA9A9A99BDB09A9A9FBFF09AD0E90F0BCA900000009A000009BFFFFFD0000D0A00A0AC9AC0F000000900000000B0BB9ABA0000000900A0B0009A09000000ADBFFFFDBDA9CBDB9B99D00B09099C90F9F0F9B999BDBDBDBB9B0B0BB9A9B0B0F099B9F9B9F0B09F09F9B9BFFAC0A9AE00A0BCACA0A0B00000A00ADFFFFFA0000A9CB09A00A0B0F0000000000000900B0DAF09A0090B0A0900000B0000000000BFFFFBFA9B9B9B0BDABB0B909A0B0B9F9B09990090099BDB9D9F99F909D909C909B0B9B9E90BD9B09B09E9FF090B0E909ADBCA9090000CB0A09000BFFFFFD00A00AA00E09A0000F000A900A0000000B0BAB9FA000000000A000000000000000BDFFFFEF9F0F0F0BDA9D090000090909090990BC9A090009BDBB09B0B9B0A9A9A9B0F9E90B9B90B09B0DB9BE0ACA0E9A0E0A0A90A00000A0000000BEFFFFA00009E90CB00E00FABF0000000009000A90A90FB0FB000000900000B000000A00000BFFFFBDA9B9B9B9B99A9A900900000090C0A90B990F0B9090D9F9D90D0990909A9B9B9FB99C9B9BC9B0BCB90009A9E0B09AD0A0CA09A0900B00A09FFFFFF0000A00BA00B09A000F000000000A00000B0A90FBF0FA000A0000000A9A0000900000DBFFDBDA9E9ADB0FB90DA9A000000009B90F90E9A9BCB909099A9A9B0A90B099CB9A99BEB9A9C9B0999BCB0B00CA9E0AC0A9C9000000A00000000BFFFFFF0009A0CA9E0AE0BE0F0090A0900000090A9A0BBCBF00900000000B0000090000000BFFFFFB9BDB9DB0B909A909090000000000B00B909099BE90B00909009000090A99F9BAD99F9B9B09F0B0B9A0CB0BCB0D0B00A0A0000000000000ADFFFFF0000ACB09A0B09A00BF000000009000A0A9090BCBF0B00000000B000900000000009FFFFF09E9A9AB0BD0B0909000090B09A909099000090BC90B09000009009090B99B09F99BBA90B0DB090B9C09A0BCBE9AA0DA0909A000000000009FFFFFE0000090EACB0CA0DA0F000000A00009009A0A90B0B00A0A090000090A000A000000A9FFFFFB9BDBD990B9DA9A9A9A9090BC90909009099A90B009000000000000A909ADBB0BB0D99F9B099B9C9B0A9ADADAF9CBADA0E09A0000A00000AFFFFFF000B0AB09AC0A90A0AF000009000A0009A9B0A000DA900900A0000A0000000000009EBFFF9E9A90B0F90B0909C9090B099B9A9A990B909009090A909090000000909A990F90FBA9A909B0BCB9A9B0CBAFBCAFBCBADA9AC009009000009BFFFFFF0000C0A09A90A0090F000B0000900A000A09A9A9A9ACB0AD00B0F0900090000A0009FFFDB9BDBB9B90B9B09A9A90B09F0B9D990BC90F09909099900B00A0009009E90B99BB999BDBBD09B99A9C9A90DADBDACBFCB0FA9A00A00000000FFFFFF00000B0CA000E0BCA0F00000A90A0090A9B9E9C9E09090C90BC0900A00000090000BFFFBA9F0B0D090BD090B0999A90B09E9BB0B9B9B99B09A9F9A9B909000B00B090F9ABC99AF0B090B9F9AD9BADAEBFEBEBF9EB0F0C0000000A00B0FBFFFF00009A00B0F0A900A00F0A0090A009A009A0A90A90B0F0A9A009A0BC090A0A00090A9BFFFDB9BD9B9F90B0BC9B0F09E90B99AD9F9E9F9FBDBBDB0B9D009009009090B90B99B0F99B99BBDB0B9B099ADBCBFDBCFEDFE9AB000A9A090000BFFFFFF00000F00A000A0B09AF009A00900000A0909A90A900090090B0900B00090900A0900AFFFBDA9B09A9A99B9B0990B09BD0A99A9B99B0B9A9DB9BDBA9B0A900900B090B99E99B0B09AD09A9BDB0B0F9ABFCBEFBFBFADAD0F000000A00000FFFFFFF000A0BC0ADA000E00F0000000A909A90ABA0009009A0000000A0B00A0000A090A0BDFFF9A9F0FB999F0909B9A99B090BD0BDB0DA9D00DBA9E909D0099CB0A9A9DA90DA9BA99F9BDBBD9BCB0F9B09FDEBFFBCFDEDADAA0000000000A09BFFFFF000A000A90A09EB00AF00009A090A090A9009A000A000009A0B09009090A0090A909FBF0B9F9B90DAB09B9A9E9CBC9AB90B0909A90A99B0D99B9B0B9B0B099909A909A990D9A9A9A990B0B9B9BC9BFEBFF0FFBEBAF0F09A00A0000900FFFFFF000090FA90A90A000B0F00B00CB0B0B0ADA0B0900900900A099C000000A0090A0000BEFFBDB0B0B9B999BC999B9B9BBD0F90B0B90909A009B0B0BCB90C9090F0B909B99A9B0B9B9F9A9BDB9BDA99B0BFFFFFFEFFDF0B0E000009A00000BFFFFFF0000A000E00E0B0E00FB000B0BCF9ADB0B00A0A009A00900A9B0B00B009000090009BDF9A9F9F9F0BDA9B0F090BC99B9A9F99CB0B0090B09B0D090B9B0B0B0B0F90DA99A990F090BDA9A9F0BDABCB0DBEFFF9FAF0F0B9A09000000A000BFFFFFA0009A0B0B0900B0B0F09A909FBBCB00B09B09090A90B00900000000000A000A000A9FABDB9A9A9B9A9F9B9B9F9BBEBDB9A9A909C0B0C90F09B0B9CB0BDBD99F9A9A9BC99A99BBB90B99B9B9B99B9BAFDBEBFEDBE9ACAC00A00000000BDFFFFF000A0AD0A0A0AC000AF9F09EBE9DA90B00A000B0A90B00B0A90B00B00B0009000A99FB9DB0BDBDB0DB990B09A90BD99ABC90D00B09090B090B0BD0B9F99A9BA909B99099E99A9C90B9DABCBCBCB0DADFBEDFE9BE0BCB09A00000A9000FFFFFF00000D00AC09A9AADA9FA9A0B9BFA90B0F09A90009AD090009000000000000A09000FBCBB9F9B0B9BBDAFB99F99B0BFBD9B9A9A900B00900B0D909F9F9EBDA9DB9B0DA9B09AD99B9F90B99B9B9B99B0B0FFBCBFE9F0ADA0000900000B0BFFFFFF0000A0B0B0E0090A00FBE9B0F9ADA00B0B00A09009A9A9000B09A90B00B0000A00B9FBDA9ADB9F0DB999BFA9A9C990BBD0900909009A90909A9B0BB0B9B9FA90B09A909B99A9A9A9BB0F0BDBA9F0BD0F0FFBCBDADA9ADA00A0A00A0000FFFFFFB0009AC00B0A0E09A0F0900F0BCB09E0000B00A00909009A900000A000009090090BF9B9F9B9F9BB9FBAD99B99B9A9900B0090A090900A09A90DB9DBDBDB99BBD9B99BD0B09BD9B90DB9B9B0F9A9B0BAFBCFBFAFA9E9A090000900000BFFFFFE000A00B0A009A90AC0F0B0B0B0909A090B000000B0DA090090B0B0909A9A0A0A00BF9B9FB9BE9BF9FAD9BABD0B009D0B900000900A009090090B9FAB9ABA9BC90B09A90BDB9A9AD0BB0B9E9F99F9E9ADBCFAF0F09E9AD0A00000A09A0BFFFFF900000F0AD00E00A0BAF00000000A090A00B009000B09A0B0A900000A000000909ADBBCBB0F99BF0BB9BF9D9BD99B9A9909000009909000090090099DBD9D099BB9BD99B99AD9B99BD9BDB9B9AB0B9B9AFFBDAF9EB0E9A000A9A00000BDFFFFFE0009A00A0AB00AD000F0090009000A0900000A0009AD9909DA909A09A9A0B00A09BDB9F9FBFBDBDBDBDBBB0B9A90990BDB09000A0909A900000900B09B0B9A909D0B0BDA99B0DBA9A9A9BCB9DBDA9E9DAFCBDAF0F9ADADA900009A000ABFFFFF900A0F09000A90A0B0F00A090A09090A000000090A90A0B0A90A0090000900B00BEFBF9B9B9FBFBFBFB0F9F9A9F9A0B9A99A9F999A990000A99BDB09A09099B9B0B9B9A9BE9BB9DB9F9B0B9AB9B9F9B0B9BFAF0F0ADA9A00A00A0000ADFFFFFE000000A0EB0DA09AC0F0900000000000000A09A0A90B09009A009A0A09A00B009F9B09BFBCFBDB9F9F9F9B9BDB90999F9FA9B90BC90B09A990B09099099B0F9E9B9F9F9FB99BD0BB0B9E9BDBDA9F0B0BD0F0BDA9ADABCA0B09A90A9A9BFFFFF9000BCA9A900A00A00AF0009009000A09009000909A09A00B009A0909A09B009A9BBDBF09FB9FBFFBFBFBF9EB90B9B0BFB99D0B9B9B99F99BDBD9B90A9BC9B99B0F9B90B9DBE9BF9DBDB9B9A9B9B9B9F9BB9BCBADA9E9AD00A00000000FFFFFFE000090E00EA90F00B0F00A00000B09000A00B0A9ADA09A00B009A00A9A00B000B0DB9BFB9FBBDB9F9F9F9F9FB9F0D909FFAB9BC9B0FA9B0B0BBF0BD909B09A9B9B9EBDBAB9BF9BB99A9BDB9F0F9E9A9BDBF9BC9ACB0F9ABC9A00A00000FFFFFF0000A90B090E00BC0AF0900900A0000A09000090B09A09A90B0A09B009A90B0BDB9AF9B9FBDFBFFBFBFBFBB9FB9B9A9FB9F9FDBBDB99F9F9FBDBF9A9909BDBDBDBF9BB9F9FB9E9FABDBCB9FB9B0B9F9FADBBDBE9A0F0AD00A09009A09BFFFFFB000A00A0EA090A0A90F00090A9090A9090A90B0B09A09AD0B0B09A00BA9A0009B0BF9B9FBDB9BF9F9F9F9BDF09F0B99BDF9FFBBDBFBFBFBFBDFB9909A9B9B9B0BB9FBDF9FB9F9BBD9BB9B0B09F9BDA9B9B9F9A9ADB0ADA0A000A0000AFFFFFFC0009CBCB009AACB00AF0B0A9909A900000000090A09A09AB0B09A09B0D00B0BF9F9BDAF9FBBFDBFBFBFBFFBBFBBDBCB9BBFBBDFBF9F9F9F9FB9FF0B99BDBCBF9F9F9FBBBDBFBDBDBBC9F9F9FB0B0B9F9F9F9FBDA0E9FA90090000A090FFFFFFB000A0A00B0E09A0AD0F9099EBB09A9B9A90090A9DA09A090B0B09A00A0B00909B9FBBDBB9F9BF9FBDBDB9BFDBDBB9B9E9FFDFBF9FBFFBFFB9FB9090BDA9BBDBBBFBFBDFBF9FBFBBDBB9AB9B9B9F9A9B90B9A9B0F9A09EAD0A0A0900A09FFFFFF00009A9E0B0A09E0AAF0B9A9B0BF9000000A0A90A90A90A9CB0B09A90909A0BF0F9F9BDBEBFB9FBDBFBFFF9BFBDBF9F9B9BFBDBFF9FBFBDFF9DB9B99B9F9FBDBDBDBDBBF9FBDBDFADBF9DBE9F9B9DBCBBBDBDBF0ADAF09A00090A0900BFFFFFC000A0CA0BCADA00B00F90B9B9BB0BA9B0909090A9B090A9AB09A9A900A0A09F99BB9FFBF99F9FBDBBDBDB9FFD9FADBBFBFDFFBFDBFFDFDBB9AB9E9DABFBFBDBFBFBFFBDFBF9FBFB9B9B9BB9B0BCBAB9BD09B9B9E90B0DA0090A00000BFFFFFFA0009CB0F0A9A9EB0CBFA9AFBBCBB09000A000A0900A0909099A9A90B09090A9B9F0F9BDBBFBF9BF9FBFBFF9BBFB9BBDBDBB9FDBFFBFBFBF9FBDB9BBDF9B9FBF9F9FBDBF9FFBF9BDBDBDBE9F9F9B990F9BBBDAF9BCADAA900A00090A09FFFFFFD000A0A00BCACA0CBA0F9090B9B90B0B0900B090A9090A0B0AA9A9A90B0B090BDA9FBFBFDBF9FBDBF9A9B9BFDB9FF9FBCBDFBFBFFBDFFBF9FBDBFBDBB9FFBF9FBFF9FBFBFB9FBFBBDBA9B9B9A9B0BF9B09DA99BCBB0BD0E900000A0000AFFFFFE00009CBCA9A90B009AF0A9A90B0B0000A09000090B0A900B999A9E9B0B00A9F09FB9F9BBF9BBDBB0F9F9E9BB9FB9FF9BFBBDBFDBFFBDBDBF9BF9FBDBFB9F9BF9FBFBDBDBDFBDBDFBDBF9F9F9F9F90BDB0B9FBDB9CACAF00000B00000B9FFFFFB0000A0A09E0AC0AF00F09000A00000000000000A000900B90AA9B0BA9B0B9B9B9B9FBF9F9BFDBB9DB9B099B0FB9FB9BF9BDBFBFFBFFFFBF9BFDBBDBFBDBFBF9FBBDBFFFBF9BF9BB9BF9B0BB9B9A9BDB099FB0B99AB9B00A0000000900FFFFFF0009AD00DA0090A900FFA0900090000000900009009A00B00B99A9BB9EB9A0F90FBFBDBBFBDBBBDAB9A9B9AD9A9EBDAF9FBFBDFBFDBF9BDBBDBBDFB0BDBDB9FFBDFBDB9BDBBDBBFDBF9BFBD9BCB9A9B9F0B9BD90F90E0F0090000000A9FFFFFFC00000B0A09E0B0E0A0F9A0A90000000900090A09B09A90B00A90B0BA90B9B0B909FBBFDBFBFCBBDB9F0DB9A9999B9F9B9D0FBBDBFFFFFBDBFDBB9FBDBBBFB9FBBDBFFFBBDFBDBBBDBF99BBE9B9F9E9A9F9FBBB90BDB0A00A000000000BFFFFFBA000AC09A00AC09A90FA9900000B00A000A0090A00B00B0B09AB9BB9BA00BDB9BFBDF9BF9F9BF9B9A99B0990F0B0B9BDBBB9F9FFBF9B9FBF9BF9FB9B9F9BDA9F9B9B9BDFBBDBDF9BF9EBD9BBDA99B9FB9A99C99B9A0F0F000000B0009FFFFFFC000A9A9E09A90B00CAF90A00B0B009000090B0B09B00B0009ABDBE9A099B099CBF9FBBF9FBBD9F0F99B099A9090D9BE9A99FBFFBDFBFFBF9AF9EB9F9F0BCB9B9ADBDAFB9BDBBB9BF9BB9BFBD9B9BE9B909009BE9A9F0B00000B000A9AFFFFFF00090C0A09AC0A0E0B0FA09A00009A000B0A00B09A00B0A9A009A9BADBA00B09B9BFBFDBE9BDBBB9B0B09E909A90B099F9FB9F9BFBF9B9F9FB9B9F9BA9B9B9BCB9A9B9BDBFBDBDBF9BF9FB99AB9E99F9FB09B099F9A0F00A9A000A90A9FFFFFFA000A9E90E09AD0B000F9A0900B009A00000B00B0BBA09000B0A9A9B00B0BD909F9F9BF9BFBBDADBDBDB90B0909090B0B90BDBFF9FBFFB9B9DBF9BD9B0D909B9BDB9F9FB9BDBFBDBFDBB9FBF9F9BB0BB09F099A99F9B0F0000B0B0EB0A9FFFFDF0000A0A90AA0A00BE0F0900A90B0009009000B0B0090A0B0009ADA0B0090B09ABFBFF9F9909A9B0B0000909A90B09090B99BB9BFBDB9FADBB0B9A9AD9B0BD090B9AB9BDBFBBDBBF9BF9F9B9B9BDBDBC9B090009A90F0B0B0000ADB0DBFFFFFFA00009E9E0D09CBC00BF00A090A90B00A0000B0009A0A90000B0A9A90A9AB0909F9BF9AB9A090909009A900000000B09B9FAD9FF9FFBF99BB9DB0DB90B0900B9F09BDAFBDBFDBBFDBF9BBE9BFBCB0B99B090A999F9B0B0E00A0A9A0FAFFFFFFF000B0EB0B0A0AB0A0B0F9009A99E009090A00009A09000000000900A9000D9009BFDBFBDB9F000000000A00000090000D099BA9BFB9F9BF9DAB0B9009090B9909BDB9B9BBDBBFDBBBDBF9BF909B9B0F00B00900B9BCBCA9000900DBE90FFFFFFC00009EBCB0BC0A9AC0FA9000A909A00000000A09A00000000000B00A9A9AB09A0BF9BDB090B00000009000000000009A9A99F9F9FFBF9BA99D90B9A900000A909B0BDBCBBDBBBDFBBF9F9BFBFB9F9B9009009009B9A9E0A9000A00BEBBFFFFFB000AD9EB0E0B0CA0B0F000A9CA9A09A900090000000000000000000000090909DB9FFF0FB9090000000000000000000990DA9BBFB9B9BC9B0B0000009A90909A90F9BB9BDBFDFBBDBDBBFDB9B0F09F090009099F9A9E9A00A0000B000FFFFFFC0009AE0BE9A0A90F0AF00090A90090000000000000000000000000B000000000BBFFB9B9909A900000000000000000B009B9BBDB9F0F09B0B9000090000000000B9B0DBFBF9BBBDBFBBF9B9F9F9BB000009090B09F0BC00000000009BFFFFFB000A0E9BC000F00A000F09A0000000A000000000000000000000A90000B0000009EB9F0FADB90B0909A00000000000909B090D9ADB9B9B09D0090000B0000000900009A9909BF9FB9F9F9BE9BB0B0DB90090B0999A9E0B0B00000000A0FFFFFF00009A0A0A9A0AC9ADAF0000A90A9009A00000000000000000000000B0000000099DBFB9BB0F90B0B090D99A90900900009A9A9B9AD09DB0B90A000000000000000000000B090B9EBBFBF9BF9BDB9B09B9A90B0F990BDAC000009A0009BFFFFFF0000D0CB000900A000F0090000000000090000000000000000000A00000000000FB9BDBD0B9A999090B000900A09A090909990D099B0B09009090000000000000000009A99B9FB9F9BDBBDBBCB9A9FBC99F999B09B0A90A0000000000FFFFFF000A0A0A00E0A0A00A0F000090A00A00000000000000000000000090000000000BB9E9FA9BF09DA09A909A90090900909A9AD0B9B9A0909009090090000000000000090099ADBB9BFBDBBDBBDB9ADB099B090FB099E0BCB0000000000BFFFFFE000900B00B00CA9CB09F000A000090000000000000000000000000000000000000DBBF99F09B0B9B0DA90900B00009000909A9900099B09A9A9A9009090909A9A9A9909B0B90BCBDB9BDBBF9A9E90B9A90B9B9090B9E9AC90A0000000BFFFFFDA000E00AC00B000A0A0F0A90009000090000000000000000000000000000000009AD9FA90B0DB0D0B090B099090B00B0909090B9BDA9090909090B00A9A9A9D09090CB09D0B9B9BBFFBBCB9BDB9B90BDB090FB0090B0E9A00000000000BFFFFFD0000BC0B0A0B0B0C9AF00000A00000000000000000000000000000000000000009BB090009A9B0B90B090A000909009A9B09B090909A90090009090909C90B9A9A9B09A9B9E9BC9B9ADBDBF9AD0AD0909AD900999E9A9CB0000A0000BDFFFFFA00B00A90AD0E00A9A0F00009000A0000000000000000000000000000000000000BE9F0000000000000000090B009A900909BC90B9B9C9A90A90B00909A9A900909909B9B0B9BDBBFBDBBBB09B0B990B9099B0909A9A9EA000B000A90FFFFFF000000F0ACB0A09ADA0FF090A0000900000000000000000000000000A000000000099B9F00000000000000000009A090B9CB09B9F909A909009090090B0909A9B0F0B9AD0BD9F0BF9BDB9DBDBE9900A90A9B00000B9ADA09A000009000BFFFFFF0000A09A9A0B0A0A0B0F00000090000A09000000000000000000000900000000000F9B0B000000000000000000090B90B99B09A9BD09B0B090A090A909A909A99990B9B99AB9F9BE9BFBA9B99A9A9009009900099E90FBC09A00A00B00BFFFFFF0009ACB0F9CBCB0F0BF000900A00009000000000000000000000000000000000009ADBD00000000000000000000BD0B90BCB9B90B9B090D0B0900900909E990B0BF9E9AD99A9BF9FB9BDBDA00000000000A099DA00A00B0000900000BFFFFFE0009E0B0E0A0A00E0ACF000009009000000000000000000000000900000000000009B9A9A000000000000000009090B9EB9B9D09F9BCB09A90900B00B0A909CB9F0909A909ADBD9BBDADB9A90000000000009B0B00BCBF0A00000B00BDFFFFFB00000B0F9A9E90B0B0BF090A000000000000000000009000000000A00000000000000F9F9C000000000000900A0F9B0B99F9AB9A9A999F90B00B00900090B0B0B0B0B090B09B9ABF9B9B9B900000000000000090000B00D009A000000BFFFFFF000A9E00ACA00AC0AC0F0A090A90A9A90A900000009000000000000000000000000009A9AB90900000000A009909AD9EB9AD9BDB9DB0B0B90900000000000090090000000009F9F9E9BCBCB00000000000000000090AFA0B0000000000FFFFFCB00009E9A90AD0A90B0F009000000000000000900000000000000000000000000000099F99ADA9A9F0F0B99B0F9B9BB99F9BBDA9B9A9F99E9A9000000000000000000000009A9B9BB9F9B90000000000000000009A0D09E000000B000BFFFFFF0000A0A00A0CA00E00AF00A0090090009000000000000000000000000000000000009A9A9E9B9F9F0B99BDAFDB9ADA9DBA9BC9B9E9BDB0B909000000000000000000000009FBDBCBDBB090000000000000000000AC9ABE0000000000BCFFFFFA0000090CBC0B09A00BCF0900000A009A090090A00000A900A009009000000000000009F9B9BDA9E9BDAF9BF9A9FB9DBAD9F9BBDB9F9B9F0B9F0990000000000000000909A9A9B9B9B0D9A000000000000000000009AD00B0000000000BFFFFFF000B0E9A0A00A0CB00AF00090A900A000A00000900000000090000A0000000000000009ADA9BDBBF9BDBE9BF9F9FBBDBB9BF9BADB9F0B9BDA9BA9A900900900000000009DBDBCBF9F9A9000000000000000000000A0ABC0B0000000000FFFFFDB00000A009AC0A00E90F00A000000909A900A00000900000900A00000000000000000A99B9B0B9DABFB9FBF9BFB0F9F9F0F9BDFBBCBBDBDB9F0DB9F0B00000090000B9FAB9B9B99A9A900000000000000000000009E9CB000000A0000BFFFFFE0000F00DA009A00A00AF0000A90A00A0000009000A0090B000090090000000000000090BC9E9F0BBDB9F9BDAFB9F9FA9BF9BCBB9DBBDB0B9FB9BBCB9D09ADA90009B9EB99E9F9BE99000000000000000000000009A00B0E0000000009FFFFFFB000A000A0C0A0DA90E0F090900909000909000A090000009A00000A00000000000000090B9909BD9BDABF9BF9DBFB9FBF9FBB9FBBF9BF9FB09FADBDABBF9B90FBDB0F99FB9B9E990000000000000000000000000ADA9E09A000000000BFFFFFC00090E90A9A0A00A09AF00A00A0000BCA0A000000090A00009A0900000000000000009A90B0B09A90B9DAF9BBBDBDB9B9F0F9B9CB9E9BBDBBF9BB9BDBD9FBFB9B0F9BFB0BDAB9B0B000000000000000000000000000A9AC00000000000FFFFFFB000A00E00C90AC0A00F0009000A000090909000A000900000000000000000000000000000090B09F9FB9BF9F0B9ABDBDBB9BDBB9F9BDBA9F9BD9FBF9AFBCBDAF9BBDB0F9B9F9E900000000000000000000000000BAD0F0B000000000BFFFFFE000009A09A0A090B0CAF090000900B0B0A00A0B0900A00A90000000000000000000000000000009B0B09BDB0B9FB9DB0BB99E9ADBBBDBB9F9BDBFA99BFBDBDBF9FBDA9F9BCB9A900000000000000000000000000F0C0B0A00000000A9FFFFFF9000BCA00A0000CA00B0F0A0A0A000000909000000B090000A0000A0000000000000000000000000099BF9ADBDB9C9A9B09CB99B99C9A9DB9FBA9BDBFB9DBBBB9BA9BF9B9B99F90900000000000000000000000000B0B0E9000A000000BFFFFFE0000900BCACA9A0E00AF00909009A9ADA000900000000900000000000000000000000000000000000090B9B9A9A99909F9B0B09A9B99BADB0DBF9B9BFBBDBD9F9DB9BDBCBB0B9A00000000000000000000000000A0F0B0AC0000000000FFFFFF900A0AC000900090BC0F00000A90000009A0A09A9A9A0A0090009000000000000000000000000000009FBCB09090A0B090099F99B0BC99B9BB9B9FBC9DAB9AB9BBBCBB9B9DBDA90000000000000000000000000B0F00AD0B000000000FFFFFFE000009A0B0A0E0A000AF00B0A90000B0B009090000C0909A00A00000000000000000000009A0000009A909000000090909BDA90B0D9B9BADBDB0FB9BBBB9FBDAF9DBBDADBA9A9000000000000000000000000000F00BDAA000000000B9FFFFF9000BCA00CA009AC00A9F0009000A900009A000A00A9A0A0000000000000000000000000000090900009B000000000000B09099BD9AB9AD9B0BDBBCBF9F9FB9BB9ABF9B9B9DB9000000000000000000000000000B0B00A9C0000000000FFFFFFE0000000B00DA00B0BCAF900A9E000A9AC090B09090090DA900000A00000000000000000000000A90000000000000009009A9A90B99BDBB9FB9BDB9B9F9B9F9F9F9B9E9F9AB0F9B0000000000000000000000000CA0F0CA9A000000000AFFFFFF000A9AC0A000A000000F0090009000009A0000A000A0A000A0900900000000000000000000009009A900000009000000090990B0BCB09CB99E9B9FBDABDA9A9B9BDB9B0BD990000000000000000000000000000B0F09A9E00000000009FFFFFB0000C09A09A0D0E0A9AF0A00B00A9009A00B0B09A90909A09000000000000000000000000090A090000000000000000900B9CB999909BB90B9B0F90B9DBB9FBF0FB9BDB9A9A900000000000000000000000000BCB0AA9E09A0000000BFFFFFFC00B0B0A0E00A0A090E0F0090000009A0000000000000A09C0A0000B000000000000000000000090B000000000000000A009A990F0B9F909BDBDB9BBDBBBDB9B9BB0F9AD0909A000000000000000000000000000BCB0DA9AC90000A000FFFFFFA00000C009E00090A000F90A00A90A00B0BC9A9E909A900A90009A0000000000000000000000000900000000A0009A00900090A99B0B0BDB0B0BDADBBDB0BFBCBDB9BB9A9A0090000000000000000000000000000BCA09E9A00B0009A9BFFFFFF000A0B0A00BCAA0CB0AF00909000090C000000000A00E900A9000000000000000000000000000900090909A9000090000090B99A9D9B9A9F9B9B9B9CB9F999B9B9F9CB9090000000000000000000000000000000E9BCA9E9EB0E9AC00FFFFFFF0009CAC9AF0A9CB0AC9F0A00A0B09A00B00B0B0B009090A0900009A00000000000000000000090A00A0000000000000000A90DA9A9A9E9B9BCB9FBDBBF9BBEB9E9B0B90B0000000000000000000000000000000B9ACA9E9A9CA90F0BFFFFFFF00000A9BEF0AFCBE9E9AF09AC00C000B00900000090A0A090000B000000000000000000000000009009000009090000000909B099DB99BD9E9BDBA9BF99AD9BDB9E9B9AD909000000000000000000000000000000E9A9E9E9EBDAF0BCBFFFFFFF00ADAECB0FDABE9E9AFF000B09A09009A0B09E90009090A90A00000B00000000000000000000000090B090B09E900900000099A9A9E90BB9B9AD9F0BF9FBF9BF9BE9D9A9A000000000000000000000000000000B0F00A9ADACBCBCA9CBFFFFDA000099EFFAFDADAFEDAF09000009A0909000A00A9000000009000B0000000000000000000000000000000090B09A00000009A090909B990BCB9BB9BDBB9B9AD9B99B0B9090000000000000000000000000000000F0BCBCBE9FADA9FAFFFFFFFF0000AE9F0F9EFBF0BFFF0A0A9A9009A0E0A900900A00A9CA0009000C000000000000000000000000090009A000900000000009A09A9ADAF99BDBCBDBE9F0BF9BADB090000000000000000000000000000000000BCBCB0AF9FADAFFE9FFFFFFF000B0F9FAFFAF0FCBFE0F909C000B0009090C0A0A00090A09C00A00B00000000000000000000000000000009090A90000000000900909999ADB0B99BF9B9F99A990090A9000000000000000000000000000000000B0A0BDAF0FBF9E9F0FFFFFFE0000EBCF0FDFFBFEDBFF0B0B0F009A00B00B00C09000000A090000000000000000000000000000000000000009000000000000000000A099A9DB0B0BDA9ABD9E9B0A900000000000000000000000000000000000CBDACB9EBCF0FBEBFFFFFFFB000B0FBFFBEBCF0FADFF0000000B009000000B000A0009000A00900B000000000000000000000000000000000000000000000000000090A090B0F9F9B9D990B90909000000000000000000000000000000000000BA09A0CBCBAFBCF0FBFFFFFC0000BCFEBCFFFBFFFFAF00B00B00000000B0000B00900A0090000A0000000000000000000000000000000000000000000000000000000009A0909A900B09A900A000000000000000000000000000000000000009E09E0FBE9ADE9E9ADFFFFFF000A9EBF9FFBCBEF0F0FF00090000090A9000B0000000000A0000000000000000000000000000000000000000000000000000000000000000090B090B90B09A909000000000000000000000000000000000000000BCA0B009E9A9EBCBAFFFFFFA000CBCFAF0FFFDBFFFFF900000090A00000000000000909000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0B00CBE0ACBE9E00DBFFFFFD009A0BCDAF0FAFCBE9EF0CB0B09AC900009090BC900A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0CBA09ADADEBCB0AFFFFFFA0000BEBAE9EBDEBE9EBFAB9EDAB09A9B0B0FAF0B0BF90B09A9F0ADAF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F09A00DAF0BFADA00FFFFFFF0000F0CBC9E9FEBF0FADFDFFFBDFFBFCB09FBDBFDFF0FFCB0DADF9FF9F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0A09ABDAFE9FA0A0BFFFFFF00000ABCAEBEF9E0F0FAFBFFFFFBDFBFFFADFFFFBFFFBDBFBFBFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ADADA0C0ADBFEDE90D0FFFFFFF00A9CA90BCBEF9EAF0FFFFFFFFFFFFFFBDBFFFFFFFFFFFDBCFFFFFFFFE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0B00F0BFAFCBFA0EABFFFFFF00000A9EADAFDAADADAFFFDFFFFFEBFDBDAFFFFFFFFFFFFAFFBFFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BCAC0B00BCFFFFE9FADFFFFFFF0009CBCA9E9FAEDA0FAFFBEBFFBDBDFAF09FBFFFDFFF9F9F9BDFFFFBFBF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9BC0A9EBDEBE9EADADFFFFFF000A0A0F0BEDE9A9FADFF9BC9F0F0B9F0B00DADAF0FBE9E9A9A9FADFCFDA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0A090E9EBFCBE9EBEBFFFFFFF0009CA0FCBEBE0E0FAFF00B00A90000900B09A90B0090B0D00B09A9A9A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0F0BACB0BCBADAE9E9FFFFFFF0000A0BCABFCF0F0FADFF00000000A9000000000000000000A9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0B0BC090ADABCEBDA9EFFFFFFCA0090BCAFDEBABCBADFAF0900090000A000900900009A0090909A0900A090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E09A0BDACE9A0ACABFFFFFFF000ACAFDBEBDEDACFAFFF000B00090000900A00A09A0090A00A00000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F00B0BC9E0A9B0E9E9AD0BFFFFFFF00090AAFDEBAFFAFDAFF0A0000A000900A009000000000000909000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009A9ACBCAA0BCACB0E0ACAFEFFFFFF0000A0FDAFBCF0ADBEFFF090909009000009000000000000900A00A0000A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009E0E0B0A90D0B0F0F0BCBF9FFFFFFB000ADBFADFCFBEFFE9E0F0000A00000A0000000900900B000A0909090090900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A09AD0F00A0ACB0A9ACB0EBFFFFFFF00000E0FEAFACBDAFFBFF09A900B0B00900000A0000A00000900A000A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA09A00BC0B09ADACBACBCA9FFFFFFE009A9F9FDBFBEFDADEBF0000090000000A900000A00000000090909000A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B09E00F00A900ACA9AC0B09EFFFFFFE90000EAEFAE0E9EBFEBCF000B000000000000900000000900B0A00A009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0CA09A0A9000E9A9E00B00E9BFFFFF9000ACB9F9ADB9FAFCB9EF00000B0090A00000000900900A000090909A0009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB09A0C90ACA900CA0B0CA00ADFFFFFF0009A0E0ACACACA9ACA0F0090009A00000090A000000A00000000A9090900A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0DAE0CB0A09000A9090CA009A9AFFFFFEF0009A9E9A9A9ADA9ADAF00A0900000090A00090A0000000900B090000A00000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009A90B00090A00A00ACA090A000FFFFFFF000A0CA0ACACACA0E0A0F0009A0009000000000000A009000A0000A0B090A900A0BC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0EACA0A00E000900B00000AC00ADBFFFF90000CB09E90A9A9E9E0FF0900009A00A00900900909000A00090909000090000009FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009AD00A90000000C00B0000A09FFFFFFE000B0ACA0ADACACA0B00F00B09A000900000A00A000000000000A0090B0000B09A0BFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0F00A0D00A9A00A0A0000A0090A0FFFFFF9A0090BCB0A9A0BCA0FAF000000909009A00009000A09000900090A0000B0000009FFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9090AF00A00000009009000090000FFFFFFF000CACA0AC0E0F0A9E00F9009A90A0A00009000009000C000A900009A9000900A9ADFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000009A00A0AF00B00BC0A000000A0000A0A9FBFFFF0000A0B09E9A09A0BCA0FFADBE9AD909F9B0F9ADB0E9AB0BBC9ADA9AD0F9B0CBC90FBFFFFFA00000000000000000000000000000000000000000000000000000000000000000000000000A000A009ADAD0BACB00A9090A0A0000A00000FFFFFFF000900EA00B0E9E0ADA0FB0F9FFAFBCBCFDAFDADB9FDFF0FBE9FFF9ABF0F9A9BFADFFFFFFDB00000000000000000000000000000000000000000000000000000000000000000000A0000000ADACA00BAFC9A0E90A0E0090A9A0D0A90A9FFFFFF90A0E90DA0CB0A9E9ADAFFFFFF9FDAFBFBFFDBFBEFFBFDFFDFFF9FEDF0FBE9FE9FBFFFFFF0E0B000000000A000000000000000000000000000000000000000000000000000000A00000009E9A0B0FACB0BE9E9AE9A09A0E90CB0A9CA9FFFFFFE00009A0A0B00E9E0BCADFFFFFFFFBFDFFFFFFFFDFFFFFFBFFFFFFFBFBFFDFBDBFFFFFFFF0FBDE0000000000000000000000000000000000000000000000000000000000A9000000000A0BE0A9CBCBCB0FE9E9AF90F0ADA90EBACBCA9EFFFFFFB0000ACB0F0EA9A0BCA9AF9FBFFFFFBFFFFDBFFFBF9FFFFFFFBFFFFDFFFBF9EFFFDBFFFFFF00A9FAC00000000000000000000000000000000000000000000000000000A9CA0A0090A9C9E90F0FAFADA9EB9EB0F0AE9F0A9EFBCFBEBFEBFFFFFFC000B0BCA0A90E9E0A9E0FFFDFBFFDFFDBFFFFFFFFFFFFFFFFFFFFFBF9FFFF9FBBEFFFFFFFFBCACBA000000000000000000000000000000000000000000000000000000AA900BCA09AA0AEB0BCBCFAFE9EF0FE0F9A0A9E90AFBCF9E9F0FFFFFFFB000CA9E9EA9A0BC0A9AFFBFFFFFBFBFFFFFFFFDFBFFFFFFFFFFFBFFFFFFBFBCF9BFFFFFF0CB0BCF00000000000000000000000000000000000000000000000000000F0DACBCA9EAC9E900F0FBFADA9E9AFA9B0E9E9E0AF9EFBEFFAFFFFFFFFE0000B0CBA9CBCBCBADACFBFFFFFFFFFFFFBFFFFBFFFFFFFFBFFFFFFDFBFFFDBFBFFFFFFF0FB0ACB0AC00000000000000000000000000000000000000000000000000FA0A0B0A9E909AB0EFBEBCE9E9EBEDA9CACB0B0A9F9EDBCBDAFCBFFFFFF9009E0FBEDEBEAE9ADA0BFFDBFFFFF9FBFFFFFFFFFFFFFFFFFFFFFFFBFFFFFBCBDBDFFFFFF00F0B0F0BA000000000000000000000000000000000000000000000000B0BCBE0F9E0BEAD0FB0F0FBBFBEBDFADAA9A0E09CA0ABAFBFADBBFBFFFFFE0000B0E9A9E9BDAE9AF0FFFF9FFFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFFFFFBF00F0F0E9CB0000000000000000000000000000000000000000000000BCBCB09E0A9E09ABE0EBCBEDE9E9EA0FADAC9A9A0B0F0CBCBCBEDEFFFFFFFF00A0CB0FAF0ECBDBEDAFFFBFFFBFFBFBFFFFFFFBFFFFFFFFFFFFFFFFBDFBFBDBCFFFFFFFFCBF0F0FBEBCB0C000000000000000000000000000000000000000000BCBE0EBE9E9E9BE9E9FBCAF9AFEBE9FFADA9A00000000BADBEBE9AB0FFFFFFB0000B0F0F0FBBEACBADAFFFFFFFFBDFFFFDFBFFFFFFFFFFFFFFFBFBFFFFDFDABFBFFFFFFF0B0FBEBCF0F0FA900000000000000000000000000000000000000ACBCBCA9BC9A9EB0E0F0FACBFDAFF9F0FAE9EBCBC0B0CA9A9CBE0F0FADFFFFFFFC000B0E0B0E9ACA9FADADFFF9FBDFFFBFBFBFFDFFFFFFFFFDBFFFFFDFFFBFBFFDBDFFFFF9E9EF0FDFBFBFF9EDAD0000000000000000000000000000000000A90B0A9ADACBEDABCBDBEBCBF0FAFDAFAFBDBFADA0B00A900EAFADBCBADABFFFFFFB00009ABCA9ACB9EA9EB0FFFFFFFFBFFDFFFFBFBFFFFFFFFFFFFFFFFFBFFFFFBFBFBFFFFFFA90FAFBCFCBEFBEBEFBE90000A000000000000000000A9009AC0AF0F0EDA9A9A9EDAEADAFBCAF0FAFFCBCAE9EDADA0F00AB09ADFAFBCB0F0FFFFFFF00A0C0A9E0B00E9CB0FAFFFFBFBFDF9FBFFFFFFFFBFFFFBFFFFDBFBFFDFFBFDFF9FFFFFFEDAF9F9EBFBFDADBDF0E9EBE9E9000A000A009A00090AC0AA00B0D0A0B0A9EFCAF0BDBDADADBF9EBDA9FEFBDEBAFADA0AF0CBE9EBDACBEA9FBFFFFFE009CBADA9ACAF0AB0E00FFFFDFFFFAFFFF9FF9FFFFFFFFFFFFBFFDFFFFBDFFBF0FFFFFFF9BADAFEFFCFCBFFEFAFBFDADAF0E9E09009CAC09A0A090A9C9AC00A09E0F0E9ABDAFAEAFADAF0EBDAFFE9BCAF0FC9ADAF09BE9EBCBEB9E9FEFFFFFF9000A0CBCAD0B00F0E90BFFFBFF9FBFBF9FFBFFFFFFFFBDFFFFFFFBFFFFFFFFFFFBBFFFFFE0DAF9F0FBFBEDADBDF0BEFBCBDBE9FADA0A99A09000A900A009A09E00B0B9ADFEBCDBDADADAF9FADBCBFEBDAF0BACB09EAE0BCBFE9FEBEBFFFFFFFE0000FBCB0AACAF0EBCA0FFFFFFFFDFDFFBFFFBFFFFFFFFBFFFFFFFFBFFFFBFDBFDFFFFFFBF09EBFF0FDEBFFAFAFFCBEDBEBCBE9EBCBCAE9EACBC0E0B09A00000B00E0E0B00BAA0F0FAF0AF0FAFBE9E0F9EBCB0FEADB0F0BCBFEADFBCBFFFFFFB00B00EBCF09ADAF90BCAFFFFFFBFBFBFFDF9FFFFFFFFFFFFFFFFDBFFFFFFFFBFFBFFFFFDF0BFBCFAFBEBDADFDF0FBF9EF9EBDBADA9A9F9E9F9A9B0BC0A000A0000F0B0BCAF0DADAA9E9F9EAF9EF9EBDAE9E9AF0BDA0DA9EBE9BDBEDFFFFFFFFC000CB0EB0FADADAEBCA9FFFFFFFDFFFFBFBFFFFFFFFFFFFFFFBFFFFFFFFFFDFF9FBFFFFFA0F0CFBDFEDFEFBEBEBFADAF9EBCBEDADACF0EBF0EDAE0F0BC0B090A9A000A00900A90A9CB0AE0BDAF0FADAADB0EF0BCAADA0E9ADFEFEBFAFFFFFFFB00A9ADB0FADAFADBCA9EFFFFFFFBF9FFDFFFFFFFFFFFFFFFFFFFBFDFFFFFBFFBEDFFFFFF0F0FB0FADBE9FBCFDBCFDADFADBFCBBCBDBAF9FCFB0F9F0F0BC00A00C90A9C9A0A90A9C0A0E90F0E9FACB0E9AEF9AFCBC9A9A9EFEBFBFCFF0FFFFFFC000ACA0F0FADADAE9AF0FFFFFFFFFFFBFBDBFFFFFFFFFBFFFFFFFFBFFFFFFFBDBFBFFFFFF0B0FBEDADBE9FBEBEBEBFADBEDABCE9EAD9EBABCFBCB0F0F0B090B0ACBCA0A9C0AC0A0B090A00B0ADB0E90F9ACF0B0BAC0ACB0B9EDEBFAFFFFFFFFB0090BCBEBCBEBE9EBCAFFFFFFFFFFBFFFFBFFBFFFFFFFFFFFFFFDFFFFFFFDFFFFDFFFFFF9E9EDADBFEBDACDBCBDBCBDADABDE9BE9BAF0FDEBF0FADAF0BCACAC9A9A90BCA0B0B09000E090BC09A0F0A0ACBA9E0E0CB0DA0FFEFBFDEF0FBFFFFFE000A0BCBCBE9E9E9CBDAFFFFFFFBDFDBF9FDBFFFFFFFFFFFFFFBFBFFBFFFFBFBFBFFFFF9EB0FBFFFEBCBEBBAF9EAF9EBEBDEBBEDACF0F9EBF0FADAF0BCB09A9ADADAFC9ADAC0F0E0B09A00ABE0F0A0DA9AD0A9A0B0A0BDE0FBEDAF9FFFFFFFF00A0C9EBCBE9E9EBEABEBFFFFFFFFBFBDEBFBDFFFFFFBFFFFFFFFFFFFFFBFFFFFDFFFFFFE90FEDFEBDFBE9FCF0E9F0EB0FDABDE9ADB0FBE9F0F0F0BCBCBCA0DACADAF0BEDA9AB0A9ACA00E90090A9CA00E00F00D0009E0ABF9CBEB0FAFFFFFFF9009AB0FADAFAE9E9FCFCFFFFFFFFDBFBFDBFBFDBFFFDFFFFFFFFBF9FFFFFFF9FBFBFFFFFFA9FBFDFFFDFFAF9FBE9F0DA0ADABCFAADB0CBEBFAF0F0BCB0BCB09B0F09E9ABCBC9E9E90BCB0A9E0F0A90A90B00A0A0F0A09C0AAF00FACB0FFFFFFE0000CBCBE9CB0F0EBABFFFFFFFFFBE9FBFF9FBFFFFBFFBFFFFFFFDFFBDFFBFFFE9FFFFFF0DADEFBEFAFBDFFEFFDEFBADBDAD0B0D9ACBBDBCBDBCBE9BF0F00F0E9AFA9EDABCBADA9EBCB0E9E9AB0F0A90A00B09000009A0BC90AD00B0FFFFFFFF000A9EBCBEBCFAFBCFCAFFFFFBDBFDBFDF9EBDFFBDFFFFFFFBF9FBFBFFBFFFFF9FFFFFFE9A9FBFFFFFFEFEFBDEBF0FCB0EA9EBCBAE9BCBEBCBEBCBCE0F00B0A9ADADE9A9CBCF0BE9CA9E9A9AF0F0BC0BC9E00A0A000000000A000B0CBFFFFFF000BCAB0F0ADABCBCFAB9FFFFFFFFBFFFBFBDBFBFFFFBFFFFFFFFFFFDFFFFFFDBFBFFFFF9E0FEFCFFDFFFFFFFFFFFFBFFF9FFADAC09ACB0BDADA9E9BBDA9AC9EBCBCB0F0FADA9AD0BA9E9ADAD0FAD0BCA0A9AD0D00B0A0900090A000A9FFFFFF00009C9E9ADAFCBEB0FCAFFFFFFFDF9FFDFFFBDFDBFFFFFFFFFFFDBFBFFFFFFFFFDBFFFFF9A9BFBFAFADFF9EFBDEFDEBCBF0FDBFBF0F9EDAF9ADA9ECBE9E9A09A9EBCB0F0F0F0FAF0F0BCB0FAF0FAF0BCBDA0A0A900C0000A00090090AFFFFFFF000A0A0ACA9ABCBCB0BCFFFFFFBFBFFBFBDBDBFBFFFFFFFFFFFBFFFFFFFFFFBF9FFFFFFCBC0F0FFFFFFAFFFFEFBFFFFFFEFFAFCBCB0A9A9E0F0BCBBCBCBC0F0F0F0BCBE9AF0BCB0F0BCB0F0BCBDADACBCA9E9E9EB0B0B0A90A00A0009FFFFFFA00A9CB0DA9CBCBCBCBCBFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFB00BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF0F0BCBCB00B0B0F0BCBCB0F0BCB0F0BCB0F0BCBFADA9A9A9E9A9A00000000000000000BFFFFFF00000A00A00A00A0A0A0A000000000000000000000105000000000000D4AD05FE")); - strs.Add(func2(7), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D16540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FEDECDACFEFCEADE0ECECBCE0CEFEFECFFEFCFEEEDEFEFEFCDEBCEFFEFCFEDEFCFEFECFDEFFC000C0A0C0CE0EDFE0FCE9FDFCBF9F9FCFCEFCF0FC000000EFCE0CE0CE0FCBE0F0EDECACBCAECACEF0FCE0FCCACE9E0FEEDE0E0E0EEDACEC0CEDEFCACAECE0CAEDEECFCACFCEDEFE0EDEFECFCFEDFFEFFFCFEEECEEFCE0EFEDFEDEFFEDFEFEFE900000C9E9CADEFE0FCBDFCBDBD0FCF9F9FFDEFFCAF0000C0CADCAC0E9ECACCFCECACADECEDEFCF0EECACECAEDE0ECECEDACFCFCEDEACF0FEF0EEFACEDCADEFED0ECBCADEEEFAEEDEFEEFCFEEFEFEEFEFEFEDACBCF0EFEDE0FEFEFECFEEFEFFF00C0CE0EC0EDEFACFCBDBCBDFE9FDB9E9E90EFFCAC0CA00C0EFCACCECEC0ECACE0FCEDECBCAC0E0ED0CEDEBCDE0FCF0E9EEFEE0E9E0DE0ECACEFDFCCCAFCEECFEEFCECECE9ECFCFEFCE9EEFEDEDEFDEFFFEDEDECEEFEDFEFEFEFFCFFEFDEFDEFF00000DE9ECEFEDE9EDADFDAF9F09EDF99CF9EFFFCAC0900CC0EC0E9CACE9CF0EC0F0E0ECFCFECFCEEBCACCEACECACECECFCBCFCECEECFCEDEDEEFEBCECBC0FCFCAF0F0ECEDEEFCFEFEFEDEFEFEFEFFEEFFEACEFCFCEEFFCFEFCFEEFEEFFEFFEFB0C0E0F00DEBCE9E9FDADBDCF0F99ADEB90D0FEFFDECA000ACDAC0ECDACE0EC9ECECFCFE0ECBECADCECEBCCE9ECECADEACECFACBEC9EE0FCEADEF0CEFECEFEEBEFCECEDACAEDEAFCEDECFEDACFEFEEDFEDFCE9EE0EDFEEFEDEFEFDEDFEFFEFFF00000C0CFEFCDAD9E9EDBCFBDF9CBD99C9F0FCFDEFBCC000CCACFC0EACCACCACCACAC0E0FCECCBCEADACCE9ECE9E9ECEDEFEDEFCCBECDEEBEDEFFCAC0CEFEFDECCCAC0EECEDECFCFFEFFEFEFFEDEFFFEFEAEDEECFEFEEFFFFEBEDEEFEFFCFEFCF000CAEEDEBCBC9E9CBDADBDE9A9C9CE9E09D0FEFCFE9A00CACF00E0CCADCADEADEDEEDECE0FEECFCECFE0ECE0ECECF0ECADEECFEECFAEDEDEFEFFCBCAC0CEEFEBEDEF0CBCAEFEFEEF0EDEDECFEFEFEFDEDCAEDACFEFFDEFEFCFEFFFEEFFEDEFFBC00CDFAFCBDAD9CBD0FDCBFDF90A99C9FCBCBCEFCFED000CACECCEDACE0E0CCACAC0EDAFCAC9E0E9E0DECACFCACACEDEFEE9E0F9EECFEEFEEDFFFEFCBC0C0CECEACEFECECCECEFDEFEEFEFEFEFDEFEFEEFCCECEFFCFEFEDEEDEECFFDEFFFEFEFBC0EEDCBC9C9E9D0FDAF9CBDAD9C0BD090D0D90EE9EFE900CBCBC0EC0CECE0ECECFE0ECECFECEFCECEACEDE0ECFCE0ECE9EEDEEEDEF0FCFFFAFFEDFEFEFBCAD0CCE0EDF0FACFFEEFCFCFCEDEDEFEFFEF0EEF0EFDEFEFEDEFFEFFFEFEFEFEDEFFC00CB0BC9E9E9E9F09D9EDDADBC90C0FCF0F0E0DCEDEF000CCEC0E0CE0C9CECBCACCFCBCBC0F0CACADCE9CACC9E0FCFADECFECFCEBCEEFEB00FEFEEDFCFCEDEECA9CCEEECCFECEDEFEFAEFEFEFEFFEDFEDACEFFEFFFEFFEFCEFCEFEFEFCFEFFEFFCE0FC9E9E9CDBC9E9E9FADF09A90B9090D099CAFEEDA900EF0E0CE0CACE0DECFCBEECECEECEECDECE0CECFAEECE0ECEEFACBCEFCEDFFB000FFCFFEEFEEFEE9FCEF0C0CFE0EFFEFEDEDE0FEFEFFEFE0ECEDEFEFEFEDFEDEFFEFFEFCFFEFFFCFEFF0D09E9D0F9ACBD0F9E9DE9F99C9C0DAD0BC09C0CFEF00CECFCE0C0ECACEACACEED0EDAC0F0DAE0E9EACACC0CBCECFEDEDEEFACFFEF0C0E0FEFECFFCFDEDEEEFCEEBCE0EDEEDEEFEFEFECFCFEFFFFECBCEFEFFFEFEFEFECFFEFCFFEDEEFEFEFCAF0F0DADBCF9DADBC9F0F9E9E0909A0DAD09E00E0CFEB00CFAD0E0C0CC0DEDEF0EEFCACECCECCECECCCFCACECCACBCF0EEDECFCEFFEB000EFFEDFECBEEBEFDECBEDEE9C0ECFEFDEFEDEDEEFEFEDECFECEFCFEFCFCFEDEFFEDFEFFEFFFFFCFEDAD0D0F0DAD90F0D0DBC0F09F09DA00D0090F0909CEFED000FEDEC0CACACECACECED0CACDACACAC0F0E0E0ECACACFCEEEFE9E0FEFFBC90E0F0FEFEEFFEEDEDAEEFEDEEDEFE0CE0FEEDEFEEFCFEFFEFFACEFFFEFEFFEFEFEFEFEEFFEFEFEFEFBCADAD0F0DE9DADF9E9F0DBD9FC9F09C909F0D0900CEFF0CACFEF0E0E0C0CE9ECF0F0ECACEACEDACCE0ECE0EC0CCE0E0FCBCFCEFEFFACA0E0E00FCFCFCEDFEFEDEDECE9EFEDEF0ECEFFEFCADEFEFEFFECF0FEFEFDEFEFCFEFCFEFFFEDEFCFEDECFC0D0F0DBC9E9E0D9F0DBC9E99F0F0BC0000B0C9000CEFFCFE9EF0C0C0E0CEDACECF0EDACCCACCE0EC00CC9EDEBCFCFEFCE0EFDE9E9000000A0FFEFAFEEDECFEFAFEFEDEFACFE9E0CEFEFDECEDEDEFFECEFDEFEFEFCFEFCEFEDEFEFFEFEFFEFCA9CBC9F0F9F9F9F0F0F0DBC9E0D90D09B0D0C90A900FCEFFEFECCFE0E0CE0ECFCACAC0ECA0FCAC0C0ECEBEECACCE0ECCACFFDEFFFA0A00A0000FEFCFCF0EF0ECEDEDEEFECFFECFEFCACFEEEBEFEFFEF0FEFEFDFEDEFEDEFFEFFFEFDEFCFCEFCB0C9CF0DF9EF0FCBDBD9F0D0F9F9E9A9C0D009A90C000EDEFCFCBE0C0CCACEF0E0DECCE0CCEC0C0EFE0C0CC0BC0E0CCBEFFEFEFEA00000000000FFFEEEFEFCEFE9EEFEDECBCECFEDE9C0EFFDEDEFFEFCEFCFEFEEFEFCFEFFEDFEEFFEEFEFEFCF0F9EB9DEBCF9DF9F0F0F0F0F9C9E9C9CA90A900C0900CEBCFEBEEDE0CA0CE9CE0EE0E00CCAC0E0EC0C0E0E0ECEECFFEFEDEFCFF0900000000000FCFFFDEDEEFCEEDE0FEFFEEFEFEFEFFFCCEEEFEFEFFEFEFCFEFFEDEFEFCFEFEFDFEFFCFEDE0909C9DEBDDB0FADE9FDBDBD99E9E9F0F99C900D0900000CEEFDEDECAC0CE0CEACC0CC0ECA0C0ECE0CACECEDEDEDAFE0FCFEFEF00A00A000000000FACFEFEFE9EF9ECEFCEEDEDEDACFCEEFAF0DEEDEFEDEFFEEDFCFEFFCFEFEFEDEFEFCFEDEFBCBCADADDEBCDFDDBDE9E9E9EDAD0D09D0F0B0D00A0090000DCEFECBEDAC0CFC0CACE0EC0ECEEC0C0CACBCBCE0E0EDEDEFECFCFEB00A000000000A0FCF0FFEFCFECEFE9CEDAEFEFEFFEFFDEFCECADEFFEFEFCFFEEFFFEFEFFEDFEFFEFEFEFFE009C99FDBE9DBF0FADF9FDF9F9BDF9ADADB0D0DA90D090000CEAFCADECEC0CACACC0C0E00E0C0C0EADEDECCECADECEEFEFCFFEBA0A0A0000000000C0FE900EFFFECFFEDEFAEDEDEDEDECFEEFFEF0CEEFEFFCFEFEFFFEEDEFCEFEEFFEFDEFCFE09FCBCFCBD9FFEDFFDFBEDF9EF9ED09CBC90D0F09C000000000EDCEFE9E90EEDAC0AC0ECDECC0E9EFCCACADACBCECFADEDEFEAE0000000A000000000AF0F0000FEFFECFAECFCEEFEEFEFFCFFEFFEFF0CCFEFFEDEFCFEDFEFEFFCFFFCFFEFEF0C9C09CBDBDEFE9FBDFBDFDBEDBCFDBDE9D9ADBD0F09090C00000CEBCFCECEC0C0C0CCECF0E0CADCE0CBEDECECECEDAEDEBEDAFC9A0A0A0000A00B00A90BE0A000CFEFFFCFEFCFDECF0EFEFFEDEFCFEDEACCFFEFEFFFEFEFEDEFEFEFEFEFEDEEF9A9CBDEDEDBDFFDFEDFE9FDBFDBDADB9E9CDADAD0F0CA90900000CE0EF0F0FCACACA0CA0C0E0EE0FECCAE0F0E9E0ECFECEEFCAA0C9000A0000000A00A0F09000000DFEFEFCAFEAFEEFEDEFEFEFEFEFEFD0EFEFEDEFEFEFCEFFCFEFEFEFCFEFD00D0FCBDBFBDFBCFFBFFFFFFDEBDF9FCF9FA9D0DAD0990000000000CFE0FCECAC0C0CCACCACECD0EC0FEDCFCEDECFCBC0FFCEA9C0A0A00000000A009A0AF0A000000FEFFEDEFFCFCF0FCFEFDEFFCFCFEFFEFFFCFEFEFCFEFFEEFEFCFFCFEFA90E9CBCBDEFDEFFFFFFDFBDFBCFBDE9E9F9F0DDADBD09F0009000000CE0CFCEAD0CACACACCADE9E0EDACE0CEACE0E0E0ECFECA9000BC0000000000000A090FF0C0090009EFFFECEFEFEFEEFEFEFCFEFEDFEEFFEEFFFEDFEDEFEDFEFFEDEFEFCFC09E9FDFF9FFDFEDFFFFFFFDFBFDBDBDF0F0DB09E9CBC0AD0C090000ACFEE0FCE0C0CCCCADE0CECE0ECBCFACCBCCFCECFEF0B0A0A00A900000000000000A0FEB09A00A0000AFFFECFCFCFFEDEFEFEFEFEFDEFFDEFEFFEEFEFCFEFDEFFEFEDEF0BC90F0F0FFDFBFFFFFFFFFFFFDFADFCBDF9FBCFD9E9DBD9090000000C0C9EF0E9E0CAF0FCACE0F0EDACE0CE9ECAE0CFE9EACA0900AC0A000000000000A000FEDA000090000ECFEDEFAEFECFEEDEFEDFEFEEFEFEFEFDEFDEFFFEFEFFEFEDEFE09C9EFCFDFFEBFFDFFFDFFDFFBCBFDBDBDADAD0B9AC9AD00F0E90000000E0ECECFCC0ECCACACDACCEC0CE0EC0ECADCEFE9E90000A0900A00B0A0A00A0A00000F9A000900000000EFFFEDEDEFFEFFEDEFEDEFFFFCFFFEFEFEFEFEFEFFEDEFEF090D0F9DBFFFFDFDEFFFFFFFFFDFFFDBDEDADBD9FC0D9FDADF9090090000CC0E0FCACACFCACEDCAC0E00CE0CC0ECADEEBCB0A0A9000000A09A000000000000000BE90900A00000000EEFFEFEFEFFCEFEF0EEFCFEFFEDEFEFFEFFEFDEFEFEFCFE9CBCBCFEFDF0FFFFFFFFFFFFBFFBF9FEB9BDBC9E99F9E90F09AD0D000000CACFCADEFCAC0DE0CACEC0ECE0EF0E9ECECFDA000000AD00E000A0A0A000A0E0F0B00F0A00A090000000000CFEDFEFCFFFCFEFDEFEFFEFFEFFFCFFEFFEFFEFFFEFEDA0D0F9FDFAFFFFFFFFDFFFFFDFFDFF9FDEDADBF9E90F9ED9FC90B0B000000C0CFCAC0FCACACFEC00EC0E0D0CECECFFBE0F0A000E0AF009A000000A00000A00000F90009000000000000ACFEEDEFEFEFEDEEFCFFEDFEFFEEFFEFFEFEFFCFEFED00DADCFCBFDFFDFFFFFFFFFDFFFFFFDEF9F9F9C9E9E9D09AD0BDE9C09000000EE0EDEFCADECE0C0EC0AC0ECEC0FEB00C0FA0000ADFC9EBE0A0B0A000000000A0A000090000000000000000EFFFEFFEDFEFEF0FEFFFEFFEFFFEFFEDFFFEFEFDE90DADBFFFFFFFFFFFDFFFFFFFFFFF9FBF9F9E9E9E999DA9ED9BC09909000000EC0CFCACADE0C0C0EC0ECCF0E0EFE90000A00000AC0A0A00009A0A000A0000000009F000000000000000000000EFFFEFEEFFEDEEFEFEFEFFEDEFEFFEEFEFEDEE00E9DEDEBDFFFFFFFFFFFFFFFFFFDFFDFDF0F9F9F9ECF09C9BCDBDBCBC900000C0FE0ECFCE0CE0E0CAC0DACECFE900000000000000A000E0F0A0000A0000000000A0AB000000000000000000000ACFFFFFCEFEDECFFFFFEFFEFFFEFFFEDFFEDF9C9E9FBDFFFDFFFDFFFFFFFFFFBFFBEFBFFDBDAD09990F0BC0B0DAD909A900000C0ECBCAFCAC0CCE0CEECECFFCB0000000000000000000000A0BA0000AC000000000D00000000000000000000000ACFEFEFFFFEFEFEFEFFFEFFEFDEFEFEFEFE00DADFCFFFFFFFFFFFFFFFFFFFFFFDFDFFCBFEF9FF9EDB9CD9F0F90BCBC9000000EC9CECFC0C0E0E0ED0CEFB00000000A0A000000000000A0E90000A0AC0A00000000A0000000000000000000000000EFFFFEFEDEFFFEFFFEFFEFFEFFFFFEDA90DADEFFFFFFFFFFFFFFFFFFFFFDFFFFBFDBFDF9F99E900DA9A0D90FD9C9000000CC0EEDACACAC0F0CCAEFB000000000C0000000000000000000A00A0009A0000A00A09A000000000000000000000000000EFFFFFEFEFFFEFFEFFEFFEFEFEFE90DADFDBFDFFDFFFFFFFFFFFFFFFFFF9FDFFF9F9EDEF9F9F09C9DACF9A0BCB900000ADC0ECF0CCACCCAFCF0000000000A0A000A000000000A00A00A090ACA0000000000E9000000000000C0B0A00000000000EFFEFFFFFEFFFEFEFDEFFEFFDEF00D0FAFDFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFFF9F9F0F09F0BC99B0D9C99C09000C0E0DADECACCACECFA90000000000C090A0000000000000000900AC90CBCA000A900BE000000000E009A0000000000000000EFFEFEFFFEFFFFFEFFEFEFEF00DAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFF09FF9F9F99E99C9E9C9ADBCA99000000C0ECEBC0CACFAF00000000000000AC000000A00000000A0A00000A000090A90000F09000A0A0E9CB00000000000000000C9EFFFFFEFFFFEFEFFEFFFEF09E9EDFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FDF9FFF0F0FC9E99E9A9C9AD909D9E00000E0EC0FC0DEEDAD0000000000000A000A0E0000000000000000A00000A00A0000000FCA00000000A00A0000000000000000A0000EFFFEFEFFFFEFFEFEDF000DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFF9F9FBDB9F9F090D0BC9BCBDA099000C0C0CEACEE9E90000000000000000A0AC000A000000000000A00A0A0000000000000AF0000000A00A000000000000000000000000CFFFFFFEFEFEFFFFEA9CBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDAFF9E9DADA909F9E9C9BC9909DBCB0000C0CBCDE9E9000000000000000000000A0A000000A000A000000000A0E0000900000FE9A000000000000000000A00000000C0A0000FEFEFEFFFFFEFEFF900DFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFFBFF9FE9FB99F9F09090B0C9ACBCB0909000ACACEA0A0000000000000000000A0AA00000A0A000A0000000A00AC090A00000000FA00000A0A0A00000000A000A0000A0A0C0000CFFFFFFFEFEFFFFC0CFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FDF9F99F9C9E0D09ADAD0D9AD9D90DAD0000C0CCAD0000000000000000000000000000A000000000000000000000A0900000000FF00000000000A0A0000000000000000A000A00CFFEFEFFFFFEFCB9ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFBFBDB0F90BC990BC9090B00900BCBD9B000C0E0FCA000A000000A0000000000A0A0A00000A0A0A00A000000000A00A00A000000FEB0000000000000000000A00000000C0A0C0000CFFFFEFEFFFEF00CFFFFFFFFFFFFDFFFFFFFFFFFFFFFFDFFDFDAF9F9E9DBCBC9BCBC9DBC9BC090AD09000C0CE0E000009A00000A0A000000000000000000000000000A000000000000000000FBC00000000000A0000000000A00000A00CA0009EFEFFFFFFEFFE90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBF99EDADBE99DB9C9DBDAD9A090C9D0F000C00E0DA9A00FAC9A0000000A000000A00A000A000A0A00000000000000000000A000FEB0000000000000000A000000000000C0B00E00CFFFFFEFEFFE90FFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFBDBC9EFDBDF9DBDADE9FBC9F9FC99E900A990C0ACCFA000CFAC9AC90A00A00000000000000000000000A00000000000000000A0C0AF000000000000000A000000A00000000AC0E00A00EFFEFFFFEFCE9CFFFFFFFFFFFFFFFFDFFFFFFFFFFDBDBDF9FF9FADF0FF0F9B9F0DFE9E99F090BC9C0000CAC0CA00A0CBE90A0CA000000000000A00000000000000A00000000000000000A00FFB000000000000000000A00000000000A00E0CA09CFFFEFFFFF90FFFFFFFFFFFFFFFFFBFFFFFFFF9FFFF0BCF0FFDFBFF9FFFCFDBFBDBDFF9F9E9090B090C0CEB00A00A000A009ACB0A0A0000000000A0000000000000A00A0000A00000000A0B00000000000000000A000C0A000000000CA9CA9CA0EFFFFEFEB0EFFFFFFFFFFFFFFFDFFFFFDFBDFFF90FFDBFFFDBFDFDFF9FBFBCDFFFFBCF9F9DBC90D0C00F9000000000009A000000000000A00000000000000000000000000000A00000A00F0000000000000000000A0A0000000A000A0EA0CADADFFEFFFFC9CFFFFFFFFFFFFFFFFFFFDFFFFFAF0FFFDBFFDBFFFFBFBDFFDFDFBE9FDFF9EBDA90BCB0B0EC0000000000000000A000B000A00000000000000000000000A00A00A0000A00000AD000000A00000000000000A000000C0A00C00DA0000CFFFFEFB0FFFFFFFFFFFFFFFFFFFFFFBFF9FDFBDBFFDFFFFDFFDFFFFFFFBFDFFBF9FFDDB9F9D09C9CCB00000A0000E0ACB000A000E9000A0000000A000000A000A00E90A000000000000FADA00A000A00000000000000A0A0000DA00ACACB0000CFEFFFE9CFFFFFFFFFFFFFFFFBFFFFFDBFFBDFFFFFFFFFFFFFFFDFFFFFDFBDFDFF9FBFDE9A9F09A9A9000000000A0E9ACB0000A00A000000000A0000A00000000000E00000A000A0000FFA00000000000000000000A9C0000A0A00A000000A000FFFFED0EFFFFFFFFFFFFFFFFFDFBFBFFDBDFFDFFFFFFFFFFFFFFFFDFBFFFFBFF9E9F0F9FDB0DAD0D000A00000A0CBCE90A00A00A00A00A00A00000000000CA000CA00A0A0000000000FA00000A0000000000000A0C00AC0A00000000A0A00000EFFEFB0DFFFFFFFFFFFFFFFFFFFDFDFFFFFFBFFFFFFFFFFFFFFFFFBFDFFDFDF9FFFDBDBF9ADB99CB00000A00000ACA9A00000000000CA00A00000A00000A00000A000000000A000000FF90A00000000000000000A0A00A00C000000000000009CFFFFC00FFFFFFFFFFFFFFFFFFFFFFF9FFFFFFFFFFFFFFFFFFFFFFFFFDFBFBFFDBDBDBC9FDB0DA90D00A000000000AC0A00A00A000A00F0000A000000A00000A0000A0000000000000FCA000000000000A000000000A00A0A0A000000000A000A0DEFFBCFFFFFFFFFFFFFFFFFBDBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFDFDBFDBCF9FF0F9F0DB09A9000000A0000A000000000A00E00A0A000A00A000A00C0000000000000000000AB0000A000000000000A00000000000C000000000000A000EFFED0FFFFFFFFFFFFFFFFDFFFDFFFFFFFFFFFFFFFFFFFFFFFFFDFFFDFFFBFDBFF9F99F9F99BC9F000A0A0A00A0000A00000AC00A00A0000E000A000000A000A0000000000000000F00A00000000A0E0A00000000000A0A0A0000000CB00000CDEFF0EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9FDBE9DBDADBCBCBCB909DA000000E000A0000A0ACA9A0A000A0A0A0A000A00000A0000000000000000000E0CA0000000C0AC9A000000000000000000A90A0C0F009A0FEFE9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9FDFF9F9DBF0F9F9BDB99DADA09000A0A00A0000000000EA000A0000000000A00000A0000000A00000A000000B9A0CB00000A0E9A000A0A00000000A000A000090B000A00ACFFFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFBF9F9FBD9F9FBCFDADAF099DAD0A00000ACB0A0A00A0000A0000A0A0A00A000000000A00A000000000000000E000AC0A000000A000A0000000000A0000000000A00A0000CBCFEBCFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFDFFFBDF9F9F0DAF9F9CB9BDBD9BDA990B0000A000000000000A0A0A0A0000000A000A00000000000000E0A00000000B00AC0B00000A000A000000000000000A00900A000000000ACAFFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9FDF9E9F99F999C9B9FCBF9ADA9C9E900A000A0A0A00A00000000000A0A0A00000000A000000000000A000000000E0000AC0B0A000A00C0E0A000000000000000000000000A00ADCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFF9FBDBD9E99F0F9FDCB9D0BDBD9B09D09C00000000A0000A00A0A0A000000A00000A00A000000000A000A00000009A0000AC000000000A900000000000A0000000000A00000000A0EFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9FBD9F09D0B0B9DEBDDADAD0F0B0A0B0A000000A0A000000000A00A000000000000000000A0000A000000000E0000000A000000A00CACA0000000C00000A000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFDBF9F999F9DB99D9D0B9DABDBDB999C9D000000A000000000000A0000000000000A0A000000000000000A000000090000A0000A0000000A009000000E0B00000CA00000A0000000A0EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD9D90DF0B909DA90BD0F9D9E9F09E9F0A00000000A0A0000000000000000000000C0A0000000000A0A000000000E0A0000A000000A0AC0F0ECB0A0000EB000A0C00A0000000000009CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBDBF9FDB9D9F9F999D09F09EB9F9F090099000000000000000000000000000000000A90000000A0000000A00A0000B0000A00A000A00A0A000ACE9000A0C0E9C09A0C0A0A0A90A00000AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFDFFDFF9FDBDF9D9FCB99C9F99DADB9F9F90F0A0A00A00000A00A000000000000000000E0A000000000000000000000CA00000000A00000000EADA9E00000A000A0AC0B0C00C00000000ACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFDBD9F9FDB9F0B999CB909CB9DBCF9090F090000000A0A000000000A0000000000A0000000A0000A00A0A0A000000B0000000000000A0A0A000E00A000000A00D00AC00B0A0A000A9E0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFDB9BDBF9F9B0D99D090990BDB9EBDF90F9F090A0A00A00000A0A000000000000000000E0ADA0000A0000000000A0000E0000000000000000A0A0A0A00A0000000A0AD00E0C00900A0000AEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFBFDBFDFD9D9FFFDFBE9B90DB0D09C99CB9FF9099E90000000A0A00000A00000A00000000000000000000000000E0A0000009A0000A0000000000000A000A0000000000000A09A0F00A000A009CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFDFFDB99FFFFFFFBDFFDEFB0D90909E9BDADBF9E99E90A0A000000A0A0000000000000000A00ACA0000000A000A00D0A00A0E9000A00000A00000A0A00A000A0A00000000A0DAC000E00E900A0AFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9FDFFDFFFBDBDFFFFFFFFFFFFFBDF9FB0009090DBDBF9E9F090000000A00A00000000000A00000000000000A00A00000A0CA0A00000B0000000000C90A000000A0A0A000000000A000A00B0E90E00CAD0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD9DEFFFFFFFFFFF9FFF9EB9E9900009DBC9F9F990DADA0000000A000A00000A00000000A00ACA0A000000000000A0E00CA00E00A0000A0A0A000000A000000A0A0A0000000B0B0000CB09EB0ACBFFFFFFFFFFFFFFFFFFFFFFFFFFBF9F9FBDF9DAFBFFFBFFFBDFFFBDB9B9C99CB00000099E9E9F0F90900000A0000A000000000000000000000C0000000A0A00000CADA90A0DB00000000CADA0A0000A0A0A00000000A000A0A0A000ACAC9CB0ACFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEFDFFBF9DFDBFFFDBFFBFB990D0D0900909000000B9F9FDB0F9F0A0A000A000A0000A00A00ACA000000A0CAC0A0000000000ACACA000EACA00000000000000A0900000A0A0A0A090A00000000000A0A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB9FF9009EFBDFF9BD90D9CBD9B9B909F0909090090D0F9B9D090900000000A000A0000000000000A0A000A00B0000000000A000AC9A0F00000A0000A0A000000A00A0A000A00000A00000000A00B09000F0FFFFFFFFFFFFFFFFFFFFFFFFFFF9BDF909090F99FF9F9DBDBDBDB9C9D0BD090D09A99000B90FDA9ADA90A00A0000A000000A000A0A0A0C00000CAC09A00A0000000A00A00EBE0E09A0A0000A000000000000A0000A0A0000A000000000A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFBFDB0F900009F9F9F9FBDBDBDBDFBF9FDB9DB9BD9D0D99CBD9BD9C9CA000000A000A000A000A00C0000A0000A000E0CA000A0CA00000000FCB00E009000000000A00A00E009E9A0000A9A090A0000B000B00ACFFFFFFFFFFFFFFFFFFFFFFFFFFFB9DB99BD9DBDF9FDF9FFFFFF9F9DBF99E9E9C9ADA9A0909AD9B0B9900A0000000000000000000A0A000A0A000A00EADA0C0A00F0000000FBCEB0F0A0A00000A000900F0BE00A00A0B0000A000B0000900000FFFFFFFFFFFFFFFFFFFFFFFFFFFF9DB9CBDBFFFFFFFFFFFFFDBDF0FBD0FBDB9FB9DB9D9990F99E9D9E9B0000A000000000000000A0000A000000000A0CA0F0AC0E00A00000FCB00C0A9C9000009000A0F0AC00B000900E0A000B000A00A00A0FEFFFFFFFFFFFFFFFFFFFFFFFFFFB9A9CBDFFFFFFFFFFFFF9FBFFBDBC9F9C99E9DCB0DBCBCB90F9F9A9C000A00000000000000000000A0000000000000A9E0E09A0A0000000AB0DA9AD0ACA00A00A90000E90B0000A0A09E900000A00900B0900FFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9BDFFFFFFFFFFFFFFFFDF9DBD9B099E99A9B9DA9909C990F0D9CB900000A0000000A0000000000A0A00A000000000000A0C90A000000DEA0000A90B00000000A0000A000A00000E00EB0A000F0A000ACBCEFFFFFFFFFFFFFFFFFFFFFFFFFBDB0BD0BDFFFFFFFFFFFFFBFBFBDAD99A0909D09CBDADB9BCBD9B0B90DA000000A090000000000A0000000000A0A00A00A09CA0E090A0000A90000000ACADA00A0AC0B00000000000A0AD00009AE0E90A00000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF990FFFFFFFFFFFFFFFFDFDBDBDB9C990F009E990990D0990FDBD0F0900000000A00CADA000000000000000C000000000A00F0A0000000F000A000A909A00000DAF0000000000A09C0A00A0AC9EBCA00A0AFEFFFFFFFFFFFFFFFFFFFFFFFFBDF990FF9FFFFFFFFFFFFBDBFBDBDBD0B909009909E9F0F9B90F9090F99000A00A0A00E9A00000AC0000A0A00A00A000000AC0E00000000009A00900900A0000000AC0A09A0000000A0B00A00000E0EA900000CFFFFFFFFFFFFFFFFFFFFFFFFFFFBFF990F9FFFDFFFDFBDFBD9DBDBFBD9E9099E090909909CBD9F9F990F090000000000AC9A0A000ADA0900000A0009000000B0A00A0000E0E9A00B000090A900000AC9A000A00000000E009A00A0EDEEB000A0FFFFFFFFFFFFFFFFFFFFFFFFFFFDBDF999F9FFBFFBFFFBD9B9BDFFDBF9DB9C990DA99E9F990F90F0F9D0B0F0A00A0A000AA0000A0000ACA0A00CACA00900A00000000B0E9EB000000B00000CA000090A00A000A0A0A0A90E00000CA0E9E9A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9F09FBDFDFFF9FDBFFDFFBDFF9FBDA9AD9BD9C9909E99EDBD9E9BDD0000A0000A0000A0A00A0A0090000A09000A0000000A000C0CACA09A0F00000ADA90000A00CF0E9A00000900E9A0A00A0E9ECA0E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFBDFDF9F90DFFBFDBFFFFFFFFFFFF9FBDBD9D9BCB09A09E99F9B9DB9F0D9A9A00000000A0A0000A00000E0A0A0CA0A900C0EABC90A0A0ACFF0000090A000A000000000A0F0E00A0A0A0B0AC9090000A0BCB0CAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBF9F9A9FDBFDFFFFFFFFFFFFFFDFF9E9AD9BF99DB9DF0FDFADE9DABD0000000A0A00000A00000009000C0BC9C000B09C0A00000EDAE9A000ACB0F0C90A900000BCEFF0F000000A009A0A0A000000ADB9DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFF9F9F99AFDBFFFFFFFFFFFFFFFBDFBDBDBCD9E90DB9F9B9D9BDB9DCBDB000A0000A000000A0000A000A000A0ACB00A0BC9A00000ACFE9000DACF09A0AC0090A9CAF0FA00A00B00A0A000000A000FDBDFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9DBDFFFFFFFFFFFFFFFFFBDBDADBBF99FBCF9FDEBFDBDE9BDA00A0000A0000A0A000A00000A09A00C090E90000A0000A0CB0B00A0ACB00A000900AC9CAD0F09CB0CA00A90000A0B090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFBDBDBFBDFFFFFFFFFFFFFFBFDF9F9DBD90F0D9BCB9BDDB0F9BDF0B00000A000A090000000A0A900000A0BEE90F0009000000A0ECA0D0000A000000A900A0B0A0E0E0EB0E900A000000CADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFF9FBDFFFFFFFFFFFFFFFFDFBDBC9E9E9F9FBFDBDFDBBDF9FDA9F00000000A000E9E9A00000000A00000C0FFE9A000000000000BDA0A0A000A00A0000900009E9ADADE9A0AC90A09A00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFDFBDFF9FFFFFFFFFFFFFFFF9F9B99E9F9F9FDB9FDE9FF0FDADA90000000A000000000A00A00900000AC0EBE9A00000000000CA0000000A000D0B0A0A90000000A0A0000B0AD0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFDFBFFFFFFFFFFFFFFFF9FBDBC9F9F0F9E9BDF0F9FDBF9BDB0000000A000A0A0A0A000000A00A00009A9C9000900000A00AB000A00AC090A0B0C9C900A0A0A000000CACAD0A0CFFFFFFFFFFDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFDFFFFFFFFFFFFFFBDFBDAD9F0F9BDBDBDF9F9F9BC9FC9AD0A0000000A00000000000000000000A0000A090A000A000ACE9000000A0A090009A0E000900000A00A0F0FAF0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFBFFFFFFFFFFFFFFFFFBDBDB09F9FDBDBDF0F9F9FDBF99F9AD0A0A00A00A00000900A00900900A9000B09A000A00000000FAB0A0A0E0CA0B0A0090A000E90A000000EEFCB00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFF9FF9BDF9F0BDADFB9F9F9EBD9CFA909A9090A00A000A00A0A000A00A0A00E9E9CAC9A0000000A0A0BD0000009EB000090B0090A000A0000A0ACBCB0CBFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFBFFFDFFFFFFFFFFFFFFFFFFF9FDA9E9F9FDB9CF9F9F9DBFB99F909E0E000A00A000000C0B09009009E000A09A000A0000A0000F0A9A0A0E0009000000A0A00A0000A000CBEB0E9EFF9FFFFFB9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFFFFFFF9F0B9F9F9F9B9FB9BD0F9FAD9CF09CB0B000A00A0A0000A0B00ACBC0A0000A00A000000A00000A0A90000000A90090000000000000A0000A000000ADFFFFFFFF9FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFF9FFFFDBFFFFFFFFFFFF9FF9F9D09E9E9C90D9CB9E9D9E9B9DA90000A00E00000A9090000909A90A0A000000A00000000A00AFE9A9A0A000A00009000000000000A000A0A0000FFFFF9FFBD9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9FFDBFF9FFBFFDFFFFFFFFFFFFF9F9A9F99F9B9F90B9099A999E9E99F9A000A00ADA090A0A0B0A0E0E000000000000000000000A00B909000000A0DA9A000000000000000000000A09FFFB9FDFDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FF9FFF9FFFFFFFFFFFFFFFFFFBC9D0F990909090D9BC9DADBD9BC90000009E0A0A0AD000C0900909A000000000000000A00000AF0A00000A00DAC0D0000000000000A0A000A000CFF9D9FBFBF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDFB9F9BDBF9FFFFBFFFFFFFFFFFBDBD9B0B90C90D0BC90BC99AD9D0BC9A9A0CA0E000000DAB0A9ACADACA00A0000000000000000A0A0A909A00000A0A9A0B000A000000000000A00000FFF9BDDFFDFFFFFFF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBCBDBC9F9F9FDFFFFFFFFFFFFBDB0D9D0B909BD99BD99AD90B0BDB0D00B0CA00A000A00CBCADADA9000000000000A0000A0000000DA0000000000000000A0000A000000000000A00CFFF9AF9FFFFFFBFFF0FFFFFFFFFFFFFFFFFFFFFFFBDB9DBDB909B90F9FBFFBDBFFFFFFFFDBDB009009F099E9CBD09A99C909DB0F00A0CB000A00A0000CACACA0A00000000000000000A000A0A90090000000A00A00000A000000A0A0000A000FFFB9D9F9BDFFFBDB09DFFFFFFFFFFFFFFFFFFFFFFFFFFBF9F9F9C9B909C9FDFFFFFFFFFBFF9099A99099F099B90BD9CB09F090D0F0CFACA0000000A0A0A0A00000A0000000A0000000000000F00A000000000000000A00000000000CA9A00CFFFF9D9B9DFFBDB9E90FEFFFFFFFFFFFFFFFFFFBFFF9FF9F9FDB9F9BD0999B9FBFDFFFFFFDF909F0C9ED9F0F9E9CBD90B0DB09E90B0A0A000A00000000000000A0000000000A0000000000000A0F090A0000000A0A0A000A000000A0A000C9CBFFFFBB9CB9F9FFDF9B09FFFFFFFFFFFFFFFFFFFFF9FFBFFFFFBFF9F99B9F09CBDBFFFFFFFFBF90099990E990909900090900D09E9C00000A000000A00A00A00000A0A0000A00000A0A0A00A000B0A000000000000000A0000000A0000A0A0A0CF9FFFDB990F09FBF0900DFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9E9CBC9099DBDBDFFFFFFF9F9F9000A990000000090000090B00909A0A00000A00000000000A000000A0000000A0000000000A0E900000000A0A0A0A000A00A0000A00000000FBFFFFF9F9999F9F9909CFFFFFFFFFFFFFFFFFFF9FFFFFDFFFFF9F9F9B9F9A99E9F9FFFFFFFFA90090D00000000000000C90909F9000000000000A0A00000000000000000000A00000A0A0A0000B000A000000000000A0A00A0000000A00A0DFBDDFFFFFF990FFF9CA90ADFFFFFFFFFFFFFFFBF9FFFF9FFBDB9909090D0909CB9F9FFFFFFFF9D9090000000900000C090B00F0D0000000A000A0A000000000A00A0000A00A000000A0000000A00A0000000000000A0A000A000A0A0000000A0EDBFFFFFFFFB9090B9900DBFFFFFFFFFFFFFBF9FFB999B0090000000009009090D0FFFFFFFF9FB090090900000000909E909090B9B0000000A00000A0A000000E90E0A00000000A000A0A0A00000DA0000000000A0000A0E0F00000000000000FFDFFFFFFBF9E990000900DFFFFFFFFFFFFFDFF9FDBE9DBD0900000000090B090B99FDFFFFFF9F9E900009E909ADBCB9090090D0C090000000A0A000000000000A000CA0000000000000000A0000A00000000000000A000000A0A00000000000E9F9FFFFB090900909000D0FFFFFFFFFFFFFBFFFFBD9FBDBFBD0900B00BC909099CFBFFFFFFFF99909090009CBC90900909BCB09B900000000000A0A00000A0A0C0A0A00A0A0000A00A0A0000A0000000000000000000A0A0A0000000000000ADF9FDBFB0D09009000009AFFFFFFFFFFFFFFFF9F9FFB9CFFDFFFB9D0D9090909E9FBDFBFFFDB0F0F9A90090009090909CAC00909C00000000A00A0000000000C00A0000000000A00000000A0000AF00000000000000000000000000000000000FBDFFFD99000900000000CDFFFFFFFFFFFFFFFFFFFF9F999F99FDFB9A909090F9DBDBFDF9FBFDB90D90090909009ACB0999990DA0900000000A000A0000A0000A000000A0000000000A0A00A0A00A000000000000000000A00000000000000000FB9DBF099900009000009AFFFFFFFFFFFFFFFFFF9FFBF9A9F0B09C990090F99BF9E9FBFF9F99FF9ADB90009090990DBCBCADB0900900000000A0000A00000A00A0A0A000A0A000A0000000000A0F00000000000000000000000000000000000F9DBF999E009A90000909ADFFFFFFFFFFFFFFFFFFFF9FFFDF9F9F9B09DBCB9AD09F9F9F9FF0FF09F990DA90000000909909900900000000000000A000000A0000C000000000000000A0A0A000000000000000000000A00000000000000000000E9BD9C9E99F9900000000CDFFFFFFFFFFFFFFFFDFFFFFDBFBF9F9FDBDA9990D09F0B0F9FF9FF9FF9F0F990900000000000000900009000000000000A00A000ACA0A0A00A000000000000000A00A0A00000000000000000000000000000000000DF9E9BDBDF9E9900000009AFFFFFFFFFFFFFFFFBFBDFFFFDFDFBDA909000090F90D9DBC9FFF9FF9E9F9F0DAD0000000000000000CB0000000000000000000000000000000A0A0A00A00A0A00A0CAB00000A0000000000000000000000A0000000E9990DFBF990009000000D9FFFFFFFFFFFFFFFFDFADBDFBB090090009090DA9E90F0FBF9FDFBDF9FDADB09099A90000000000090990000000000000000A0A0A0A0A000000000000000000000000CA00000000000000000000000000000000000FBDEFFBD90090000000000FFFFFFFFFFFFFFFFFF9DBDA9D090090090000009D9FF9FDFDFFBFDFBFFBDBFDBDAD09C900009000C09C0000000000000000A00000000000A0000A0A000A0A00A0A0A0A0000000000000000A00000000000000000000999990909000000000090FCFFFFFFFFFFFFFFFFFB909009E09C0F0BC9E9FFFFF9FFFFBFDFDBFDFBDBD0BF0F9FDB0D0F9E0909B0A900000000000000000000000B00000A0A0000000000A0000009E00A000000000A000000000000000000000000000090000000000000009FFFFFFFFFFFFFFFFFFFFDF9F99DBBD9FDBDBDF9F9FFDFFFDBFBFFBFDFFFFFFDBDF0BC9A9009D0F00C90000000000000000000A00A000A000000A0A0A000A000A0A00A90000A0A000A000000000000000A00000000000000000000000000000009FFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFBFF9FFFFFFDFFBFDF9F9FDADF9BD99F90B009090900000000000000000000000A000A9A00000000A00A0000000EA0A0000000A0000A0A000000000000009000000000000000000090000000DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFDFDBFFDFFBFFFFFBDB9C9A9E90C9090000000000000000000000000A00000A0000A0A0A0000000A0A000B0000A0000A000A000000000000A000000000000000000000000000000909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFDFF9FDBDBD09BD0900B090009000000000000000000000000A0A0000A00000000000A00000A0E00A00A0A000000000000000A0000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFF9FFDFFFFFFFFBDB09F09090909000B000900000000000000000000A0009A0A000A0A0A0000000A000009A00000000A0A00A0A00000000B00000000900000000000000000000000009CBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFBFF9FFF9DB09909A0C90900090000000000000000000000000A00000A00000000A00000000000E000A00A0A00000000000000A00000000000000000000000000000000000909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFFF9FFDFDFFFF99B0909E909DB9000900900000000000000000000000A00A0A000A0A0A00000A00000000B00000000000A000000A0A0000000000000009000000000000000000000000BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFBFFDFB9F0D9F990DA900090C0900900000000000000000000000000000A000000A0000000000000A0000A0A0A000A0A000009A0B000000000000000000000000000000000090D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFDFFFBF9D099B09A909D099009A900000000000000000000000000A00A0A00A00A0000A00000A00A0F000A0000000000000ACA000000000000000000000000000000000000090C90AD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFBFFDFFBB900090D09A99E90009009000000000000000000000000000000A00A000A00000A00000000A000000000A0000000090A0A00000000D000900000000000000000000009A9DBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBFFBFDFFBF9D90DB9DB90BC9A90090909000000000000000000000000A0A00A000A000A0000A0000000E0F0000A0A0A00000A000A0A0900000009000900000000900000000000900909DA9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFDFFFBFDF9A0DB9CB900D9909090000000000000000000000000000000000000A00A0000A000000A0A90AB00000000000A000A00000A09009000090000009000000000000000009E9E9DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FDFFB99DBC9BDA9990A90000909000000000000000000000000000A00A0A0A0000000000A000000ACA0A000000000000000A0A00A00000000000909000000000000000000C0909A99DADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBF00BDBF09900F99090900009000000000000000000000000A000000C000A00A00A0000000A00B0000A0A0A00A00A00000000000000000090000000000000000000900900F0D9EFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFF9FFFFFF99D9F09F9CB909AD0909090000000000000000000000000000A0000A0AE9000000CA00A00000A000000000000000000B0A0A00009000000000000000009000000000DAD9090FBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFBDBF99E9E99F9A990F09090000000000000000000000000000000A00000E0CF000A09E0B00000A00AF0000000000000000A000900090000000000000900000000090000000900B0F0DEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFF9F099BDA9C90909009A09090000000000000000000000000090A00A00BE0FA0C0E0E09A00000000A00000000000A0A00A00A00A00000000090090000000000000000000B09C90F9FBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBDFF9B0D0BDB9BDA9099090000000000000000000000000000000C0F000000E0DA9ACBCA00A000000F0000A00A00000000A00A00A00900000090000000000000000900000D09A90D0FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFBDF9C9F909C909C9AC909090000000000000000000000000000ACA0A0A0F0EA000A0A9A000A0A00A00000000000A00A000A09A09000900000009000900000000000000000C000FBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBFFDBDFB0B9ADBDB9B909090000000000000000000000000000000CACBE090C00A9000A0000000A0000A900A000000000000A0000ACA00000090009000000000000000000090090909C9F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFBD90D909090DA90900909000000000000000000000000000A9E0FCE0B0ACA0A00000A0A0000A00EA000A0A0A000A0000000090A90000090C00000000000000000090000000CB0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDBDFBF9ADBCB9909CB09000000000000000000000000000000000A0A9AECB000C00A000000A000000B0000000000000000000A0A000000000090900000000000000000000000900DAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFBFBDF9F90999CA9099090900000000000000000000000000000A090CEE9A00A0A0A000A0A090A090A000A0A0000000000000000000000000000000000000900000000000009000DAFDAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBFDFDF0F90DBC909DA90000000900000000000000000000000000C0ACAA9A0A00AC00000000C0A90A00E000000A000A000000000000A00000000000000900000000009009090000009DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFBF9FBDB909A900900900000000000000000000000000000CA0A000000000A00A9A09A00A9E9A00A0B00000000000000000000A0000000000000900000000000000000000009090CADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBDBDFBFDBDF0F909B00900090000000000000000000000000000CE9A00BCA0A00A0C0CA00000A0E9E900CA0000000A0000000A00000000000000090000000000000000009000900000BDAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFDFFFFBD9BDB09909C090009000000090000000000000000000009A0AC0A000000A00A0ACACA900EDA9A0AA000A00E090A0000000A000A00000000000000000000000900000090000090D0FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FBDFAF0F9F0B0090090000000000000000000000000000000A0C09A0A0A90A00A0AD0B000ACB0A0090B0000000AA000A000000000000000000009000000000000000000000090000ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDFFF9FFFDB9D99909D90909009000000000000900000000000000000CA0E000000A00A00000AC9A090E9C9A0ACA0000A000E9000000000000A0090000000900000000000000900000000900909EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFBDBFFFBFF9F090B00000000000090090000009000000000000900B0A90A000A90A0A000AC0A000A00090B0000000AC0A000000000A00000A0000090C090909000000000000000000090DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FF9E9F09A99AD09009000090090000000000000000000000900E0C00A00E0CA000000A00B00E0E9A0A000A0000AC0A00A000A00900A000090000000BC90C000909000000000090A90ADBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFBDBDFF9F9F9DBD9090909000900000000000000000000000000000AC90A9AC0B00A000A00A09AC0ADADA0000E000A0000A9A000A900A0A900000000000090900909000000000000000909C90DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFDFFFFBDBF9F9A909CB0900009000000000900900000000000000009C9A0E0000ACAE09A00009CA00ACACA0E9A0B00000A00C00A0C0A00000A0A0000900000000000000000000000000000C0090BC9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF9FBDBDBE9F9F9B090090900000000090000000900000000000000000009A000009E00E09A00CAC0E0BCB0000E0A0A00CA0A000A000A0A0000000000000C09000000900000000000090090B0C9FFFDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBCBD99090909009000009090009C0900000000000000000090B0A0A000B0E0E0B000A0CA90B0A9CA00ACBA00C000A00000000A0000000000000000090CA90000009000000000000000C0B9E9FFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFF9FDB0BDB909A9090090900090000000000B009090000000000000000000000A0000B0000FAD0B0CAC00CA0A0CA09E0ADA000A9A0A00000000A00A90000900009000000000000000000000009090C9F9FFDFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFFBF9F9090909000090000900909000909000DA9CB0000000000009C900A0A0C0A0E00B0E0CA00E00ADA0000A90AA900A00AC000000A000A0000000909000000090909000000000000000090000090DBDBFFFFFFFFFFFFFFFFFFFFFFFFFDBFFBDBD9F9F90B00090900090000000009000090009009009000000000000A00C0A9AC00E0000FADAE0ED0ADA9A90A00E0A000A00A0A00A00B00000000CA00000000000000090000000000000000000900BCBDF9FBFDFFFFFFFFFFFFFFBFBDFBFDADBCFA9909D09900000900000090909000000000000009000000000090B00E0FCACB0F0F0BE00E09A0AECAAC0CACA0B000A00000000000E00000000A099E90090000000000000000000000000D0090A9C9BCBFFFFFFFFFFFFFFFFFFFDFFFBFDBF9F999DAD9A900090000000909000000000900900900009000000090E90CE0FA0A90E0E0E00CE90E00EDADC0EA0900E0000000A00000A000A00000090C09E9000000090C900900000000000000900C90BC9F0D9F9F9FBFFFFBFFBDFBF9F9F9BD9F0BCB09B090090000000000000900000000000000000009000090090A0A9EEDEDEA9E0F0E9A0E00AC0ACAAE90E0A09A0000A000000000A000000000A9EC90F00090000000000000000000000000000090099AD0FBFDF9F0FDB9FB0DBF9E9F9B099990900909009000000000090000000090090900000000900000009C00E0AEBA9CA9E0F0E0B0A9CACACCDAEC0AC0E0000000000000000000000A000009E900D000900900000000000000090090909C0BD0AD0BD09A9E9F9BCB9CB9099990009000000900000000000000000000000000000000000000000090090B09AC0FCBCCEF0CA0E00E00CA00ACAAAC0ABC0A9A000000000000A000000A900A0A9E900F909000000900000000000000000000009000909009AD9909009009009000000900900900090090000090000000000000900009000000000900000A9C0E09A0ACEAF0AADEDAF000AC0ECCACC0E0C0ACA000000000000000000000009000000909E90D0090009000000000090000000090090900009090009009090090090009000000000000000000000000000000009000090000000000000909C9CBCBCA0ECBCF0E9CACAC0A0F00E0BAC0AE0E0E00F0A00000000000000A00000A0000A090009E9A9A090000000000000000000000000000090000090009000000000009000000000000000000000000000000009000090E9000900000009000B09CACB090ACAEFEADEBEBCA00E0ECCAE0C9A0A0E0A0000000000000000000A0B09A0000A09C090D0D9CA909000000000000000000009009000900900900009090090000000000000000000000000000000000000000900909A9CA00900CA90D0DADEBCA0E9EEDE9EACE00E9CE0E0A0C0EA0C0C000A000000000000000000000000000000000B0DA9A009C00090000000000000000000000000000000000900000000000000000000000000000000000000000000090009000009090009090B09A0E00F0D0E0FAFEFDEB0F00E0ADACE0AC0CA0A0A0F00000000000000000A0900A00A00A0E90DA0D0D9F09AD000900000000000000000000090090009000000000000000090000000000000000000000000009009009CB000090090D090B0D090C09EFAEAE0ECEEDAEBCE00E0ACACA0E00A00000000A00000000000000A000A00000009000A00DB0F0090C9A900C09000000000000090000000000900090090000000000000000000900000000000009000000000900909090000009AD090B0E9A000EDADAF0EFAFFCEBCACADE0CACACBC0ACA0000F000000000000000000A0000000A0A0A9CB00D0DB0F90C0DA900090900000000000090000000000000000000000000000000000000900000000000000000090C9A0000000000B090B0D0D0000EEDAFECAEBCFEEFFE9E0CA0ECAC0AC0AC000A000000000000000000000000000A0000000A00DBCBCD0009B090009A0000000000000000000000000900900000000000000900000000009009000000000900F0090909000000B090E9C9A9A90ADADAEE0F0ECEFEFFACAC0E0ECA0E0E0E0A0A0000A00000000000000A00000A000000A00A0000009CB0F9D0C909C90D9000000900009000000900900000000000000900900000900000000000909000000009009A90000000D09C099A90D00A00ACACE9EACFAFEFFEFFA9E0E0A0DA00000C0000009A0000000000000000000000000000000A9A0E9AD90E9B0F090DA0DA09000000000900000000000909C0090090C000009C00009000900900000000000D0090D0900090B00009BC0DADAD00000E0F0E0E0ECAFEFFEFCA0E0E9E0CACA0A0A00A00E00000000000000000A00000000000000000090DADB9E0D0DAFA9DA99000000009000900000000900090900000009C9000B0000090000000000090900A090B000090C0090B9009B090E0A0CA09E0E0E9E0EFEFFEFE9E00E0E00A0000C0000000000000000000000000000000000000000A0A0ACAD09C9DB0F9C9DA9D000900009009000000090C00C909A0090909000090009A09C000009090900000909AD0900B00090000CB9F09CF009E90CEACAF0E0FECFFEFE9E00E0000E00A00A00AC0A0B000000000000000A00000000000000A000000090BCB0F0D9E9B09CBCB00900000F090090000009A90A0D0900000A09C090D090009009000000000000D09000900090090DB9C909CA0F0E0E0B0CBC0E0E0FEEFFFFEBCA0A0E0000C0000000000E000A00000000A000A0A000A0000000000A0B0A0009C90F090C9E90090D000000009C90C0900900009C909E9090D090900000C9000000009000090090B0090009090900B0DBB0BC9CACADA9E0E0EACADACADEFEFFEDAC0C00A0A00A00A00A000B0A0000000000000000000000000000000000000E0B0F90F0F9090C9CB090900D09A9A90900000900C0B0090F0909E9E9D0B090A90900900090900F090DB090F000A09F0F0D0D090ACBCACE0F0F0CBCACAEEFEFFEDA0A0A000000000A00C00A0A000000A0000A00A00A00A0000000000A0ADA0B0900D00F9F9CBCB9A909AC009A0C9C900090090009090C9CF0D0AD0909A0090C90CA000009E9E0909F090009009C9DB099B09A9A09E0E0E9E0E0EAC0E0EDEFFEFFEAD0C00AC00E00C000A00C0F0000A000A00000000000000000000000000000A0EB0BD0C9A909D0D09C90900090B0F9B0090C090000909A99AD9090F099D0A9009090F0D0909F9F00B0090009A90BC9E9CB090CAC0ACBCACBCAD0EACBCAFEFFEFBC0A0A000A000A0AC00A0A00A0A0000000A0A0000A0A0B0A00A0A0000A0A0A000C9CB9BCDE9E0B0DA9CB09C9AD0D0C9D0A990090900F0D0E90F0F090E0090090090090BCBD090990090A9090DBD0B90F9CBCB09ACF0EACACACAC00E0ACAFEFFEFEF0C0CA000A0000A00C000F00000A0A0A00000A000000000000000A00000D0F0B0A0D0B99F99C9AD0A90CB0D09A9BCBBD00B0C9E9F09A909E909DAD99009000900B9C990B9E9A0D909D0FBDB0A9D0F9E0DA0CACA0E0CBCADACADA0ACEDEFFEFF00A0A000E00CA0000A000AA000A000900000A00000A00A00A00000000BCA0A0AC00F0BDADE9E9AD9A9D090D0B00DCB9C90F0D9E90090D09E9DBDA9900AD090F009C0B9AD9C9ADDBADB0F9C90D9F0BCBCBAC9EAD0ECBACA0E0A0A0C0CAEFFEFFE9E0C00A000A000CA000A009A00000A000A000000A00A00000000A00A000DA9000B00E9ADB9FBD9A0D00BCB090D0B0CF9AD99A09F9BC900090A0BDE9F990F090DB09BCBDA0BD99AD90DB90B0F0F0F90DA0DAE0CAF0ACCACA00D0CA0A0CFEFFFEBE0A0E0C0A0000A000A0C00E00000000A000A00A00090000000000000ACAC0E9A0CA900F0E9C9BC990F909DADA09C9B0F9AC9DF09C9ADB09C99C099A9E990DA90DBC99C9D90BCB9ADB0DA9DB9F9F0FA0FE0CAF0CAC0A000DA0A00000A0EFEFFFEDAC00A000CA0000AC000A09A0000000000000A00A0A0A000000A00A9009A90000000A00090B0CB0E900C0E909CA90C90D99E90F0BD9ADBC9A090009C9000B9CBBC9BCB0BCBDB0D9BCB99CB0E9E0F09E00FACCAAC0BCACA00000A00C0E9EFFEFFADA0E00A0A00E00000A000A0000A00A0A0A00000000000000A090A0000A0A0A0A0A0009A0A00B0D99CB909C9E99009ADA9E9E909D0AD9C9B0D09E900B0909009C9BCB9DF9BCBDBEDBDBCB0ADACBC9EB0EAC0A0D0AC09000ACA000A0ACEFEFFFACAC000AC000000CA0AC0A0E00000000C0000A000A000000000CA0900A0000090000A0A000000000CA90AD0B09A0D0C909C909C90AD9B0B9C90B00DBD09A9CB00B0F90FA9EDBDA99A9A9A9ADA0F0BAC0E9C0BC0AE0A0A0E00000AC00CBEFFFFEFF0ACA0000E0A0A000000009A0000A0A9A00000A000A0E9000000E0A000000A0A0000000A000A00A90C900D0D0D09A909A9CB09E900C09CA909090009AD9009D00D0FD9F9BCB9DB0DB0DA0F0F0ADCBAF0E0E0AC009C00000A00C00A00CEEFEFFE9E900E0A000C00A0A00A00E00A00C90000A00000000000A00A0B090000A000000A00A0A00A00000CA90C9A9A90BC90F0D0BD0F90F9B9090DAD0090DADB0990B9DBF9AF0F9BDA9ADA0FA9F0B0F9ABC0CADA00CB0E0A0A0A000A0A000ACAFFFFEFE0CA00000A0A000C0CA0CE90000A0A00A00000000000B000000C0A00A000A0A00000000000000A0A909A90DC9C00BC990AD0BD0F90C0F0DA90ADE9099CBFCBC9E9CBD9FDADA90F0BDB0FA9EDA0EC0EACA0F0A0000000C00E000000E0EFFFEFFEB0ACA0ACA0000A0A0A0FE0A9000090A0000A000000A00A000A9A000000000000A00A0A90A00000D0CE09C9A9A90900CADD9EDAD0F9BD0F0DE9D09E9CA9C9BDBF9FF9EF0BDB9EB0BCBEBCBE9ACF0AE09AC0AC0ACA0E0A0A000A0CA000CEEFFFFFCE00C0000C0AC0C0ECE0FEEA0A0A0000000000000000000000009A0000000000000090E00A00A0A0A9E0AD0E90F090900ADBCBFBDADAD9F0DA9F0F9FDB0F0F09E9BF99FDACB9E9EB0BCBCADA0EC90E00BC0B00000000000A00A00A0A0FEFFEFCBDA0A0A00A00ACAE9EFEEFB000900A00A0000A00000B0A00000A000A00A00A000000AC0BC90A0000F0AD0A090F0DADCFF90DBC9CAD9F9E9FBDF0BCF0BCF990DF9F090F0ADBE0BA0FADA09E0CB0AAC9AC0A0C0A0A00ACA0000C0000C0EEFFFFFBEACAC0C0A0CACACFEFEFFFC00A0A0000000A000A00A00000A0A0000000000000000AC0BE0A00000A00F0A900E0CBCBA909E9E90B99A9EBDBC9A9DBDBDF99ADB9A909E9ADB00B0DB090A9E0EB0E9C0A00A000A0000E0000CA0A00A00ACFEFEFFEF0900A0ACEBCFEFFEFFFFEBE000000000A0000000000000000090A009000000A0A009AC090A00A00A0000CA009A0B0D0F0909B90DADB9DADBF9CBCBCB9FFDBCBDADA9ADACEBCBACB0ADA0B0CB00A90E00DA00C0A00000A0000A0CA0CAEFFFFFF00E0E0ECBCEEFEFEFEFEFF0B0B0A00A0000A0A0DA0A000000000000A0A000000000000B0A000009000A0B009A0000A000A0E00C90900909E9CBF9BDBDA09EFBCB0FBCB09A9CBC9A0F00F0CB0CB00E00B000A0A00A00A00A000C0000ACFEFFFEFFE0E9E9EEFFEFFFFFFFFEFBC000000000A00900A0000A000000A00900000A00090A0A0C000A0BCA00B0000A000A0000B09090B0A0009E0B09B09E9E9A9FA9ADBCFBCBCBE9EFEBE9EBFFBFBFFBE9A90AC0A0C0000C0AC00C0A0A0A00CBCFFFFFFACBCEEEFFEFFFEFEFFEFFFE0A0A0A00A0000A0BC0B0000000A000CA0000000A0A00C00A0A9C0000CAC0CB0000000A0A000A0A0090A9A09C0E00F0B0BCB09BCBEFBFBFBF9EFADADBFFFFFFFFFFB9A0A00A000A0A0A000A0A000000CA0EEFEFFEFEFEEFFFFEFEFEFFFFEFFEFB00090000000A0000A000000000000B000A000000000B0A09000A0A0A09A9A0E9A00000090A090000A00000A0B0BCADADABCBACBFBFFFFFFBFBDFEFEFFFFFFFFFFFFF90CA90CA000C000A0000A0AC0A00E0FFFEFFFFEFFEFEFFFFFFFFEFFFFFFCB0A0A9A00A00000000A0A00A00A0000B009A0000000009A0A0000D0DAC0E900009A09A00090A00B00A0A090E0F0B0B0BCB009ADFFFFFFFFFFFAFCBFFFFFFFFFFFFFBFA90A000B0A0A0C00E00C00A000E0EEFFFFFFEFEFFFFEFFEFFEFFFEFEFFF0A000000B00A0A00A9000000000CACA00A000A00A0A0000000A0A0AA0B000E9A0000000A0A09000009090E09A0ADAF0FB0B9EBAFFFFFFFFFFFFFFEFFFFFFFFFFFFFF9A0AC0B0C00000A0A00A0A000E0BCEFEFFFFFFFFFEFFFFEFFEFFFEFFFEBA009A000A0000000000A000A0000A0B0CADA000000900A000B0090C9C90A9A9000A00A090090A0000A0E0A90AC9F0F0BBCBDABDFFBFFFFFFBFFFFAFFFFFFFFFFFFFFBA9C90A00A00A0A00C0A000C0E0ECEFFFFFFEFEFEFFFEFFFFFFFFEBFACBCF0A000A0000A0000A0000A0000A0D0CA900DA0000000000A000ACA0A0A0000A0A90090A0BCA00A0A000090A909A0B0BE9BEBDAFBFFFFFBFFFFBFEF0F9FBFFFFFFFFFF9A0A00E00A00C000A00CACAF0FEFFFEFFFFFFFFFFEFFFEFEFEFAFCCFACAA900A000A0000A0000B00000A000A0900A000B000A0A000000A0900000B00000C0A00000009E090000B0AD0A0A9CAD0BE9FBFF9E9FBFBFBFBFFFFFFAFBFBFFFFFFFFBE900E90A00E0A0E00E0ACBCEEFFEFFFFFFFFFFFEFFFEFFFFEFADABA0000F0A0000000A000000000000B000A00A0A90A000A0000000A0A9CA0B0B000A0A00A00A00B0A009A0A0A0CB0A9000A9ABDBFFFBFBFBFBFFFFBFBFFEFECBCBFFFFFFFFFB9A0B0A00DA000000E9ECFEFFFEFFFEFFFFFFFEFFFEFFFEAF0BCAC0C0E0AA0000A0A0000000A0A00A0000000000000009009000A0B00000A000000A00900A90909000900A000900B09000A900FDAFBFBFBFFFFFFBFBFFFFEFF0BFBFFFFFFFFFFBCB0C00CA0090E9EE9EEFEFEFEFFEFFFEFFFFFFFBEFFECAF00E000A0A00CF00A0000A000A00000000ACA0B00A000000A00A0000000A9A0A9A9A0A000ACA900A0A0A0A0A90A9A0A000A9A900B9ABFFFFFFFBFFBFBFBFBFBFFFEFDAFFBFFFFFFFFA900A0A90AE0E0E0FEFFFFFFFFFFFEFFFFFFFFEFEFACABC0EA0E0AC0CACA0B000A0000A0000009000090000000A00A0000009A000000000000000A90000E00000009000A0000090A0900E9E0E9FBFFBFBFFBFFFFFFFFFFFFFBEBF0FFFFFFFFFFBF0B0D0AC90E9EFFEFEFEFFEFFEFFFFFFFFFFFFEF0FAC0A00C00C0ACACACF0A0A0A0A00000A0A0A0A0A0A0A0A0000000A0A0A000A0A0A0A0A0A0B0A0B0B0B0B0B0B0A9A0B0A9A0A90A0F9BB9BFFFFFFFFFFFFBFBFBFBFBFFEFFCBFBFFFFFFFFFF0B0E0ADAEEFEFEFFFFFFFFFFEFFEFEFFFFFFFE9EE0E0E0E0A0E0E0E0ECAA00000000000000000000000000000000000000000000000000000000000000000000000000000000000A9FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBFBFFFFFFFFFFB9ACBCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE0E0E0E0E0E0E0E0E0A000000000000000000000010500000000000070AD05FE")); - strs.Add(func2(8), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D16540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00F00900000000000009090FB0000900000090000000909BFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0009C90C0F9E9BE000090009000D09009009000000000000000B0900000000900000FF009CD00000009000090900000DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B0D0900909E9FC9000900900FBFA90000000090000909000000D00B0000000000009000009B00000000090900000909BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0900B00009E9E09000900F9DFFFF090009000090000090090B09090000000000009F00000F0000009000009000000BFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AC90009009090C9000099E00D0FFFE900000000090009000F000000000000000009E90090F00000090090900009C9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00900000000900900009F00090909ED009090900000090090000090000000000009E0009F0000000000000909E90FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFFFFFFFFFFFF90D00909090909000900BC90900009BDA90000000000BEFFE00000000000000000090F09A0009000090000900090BFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFCBBF00000000000090009FE00000000FFC000900909DFBD0B0000000000000000000099ED00009000090009F00009BFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFC9F000000909000000099E00000090B0090090000BFC00D00000000909A00000000009000000000000900BF009ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFBFFFFFFFFFFF9E9FF90000009090090009BD0B0909C900000090900900B00000000000900000000000009000090000000900009BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFBFFFFFFFFF09F0009000900000000000FBC9000A00909000009F000F0000000090000900000000000000000000900009F009EFBFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBFFEFFFFF0F009000000900000000090DAFDBD0900009009FE000900000000009000900000000000000000000009090FC9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFBDFBFFFFFBFFFFFFF0000000000000000009000090000000000000090000F000000000000000900000000000000000000000090009FFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFBFFFFFFFFFFFF090909090090000000000009000900090000000000B0090000000009000A0000000000000000F00009000900BFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFBFFBFDFFFDFBFFBFFFF00000000000000009090090000900000009BF00990F00000000090000909000000000000000900F9E0009009FDFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFCBDFFBDBFFFDFFFBFFC000900900000000000000000900090009CFC9FF0EB09090000000900000000000000000009009009A000009BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFBFFFEBFFFFDFFFFFD0009009090DBDB00000000000000090FBFFADAD0F90009A00900009090900000000000000F00090D9000000FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFBFFFBFDFF9FFFDBFBFFFEF9EB00000000F0FADFBCBC90000090000BCFFCF0F00F0090090900909000000000000000000090000000009009BFFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDFFBFFFFFFFFFFFFBFBFFD000900099A9DF0FFFFBCF000000090BD0B09000B09A90900090A090900000000000000009E00009000009AFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDAFFFFFFFFFFF9FBDBFBDFBDFDFBCBA000099FEDFE09F0D0FFBC00000900D0A9C0000F0BDA09A9000900009000000000000000099E000B0090099FDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9AFDBFFBDBFEFFFFCFBDFAFBCFFDFD00000FFF0F9C009E09CBC00009E9AFD000000F900D009C09009000090900900000000000090000000000BFBFBFBFFFFFFFFFFDFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFDBEF9FFEF9F9F9FBDFADF9FBDBEBFE909009BD009B0F9FE9F0900009C900000000B09F0090B900000900000000000000000000090990000009FFFFFFFFFFFFFFBFFBFFFFFFF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFBFFFFBFF9F099EB9F9FBCBE9FABDBFEFFEFFDFBC00090FE9AFEF9E09F000000000000000000F0900B09000090000009090000009000000000000000009FF9FBFFFDFBFFBDFCBFFFBFFF0FFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFEFFFFBE90FDFADBF9F9FDFCBFDBF9FBFFF00000090DBDFFED00000000000000000000B0B909F090B000000000000000000A90000000000009000BFFFDBFFBFDBDFBFBFDBFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFBFFDFBDBE9F9F9B0BDFF0FBEFAFBDBFDFFFFFEFF0009000000909090090000000000000000F9CB00BFC90900900000909009009C0900000000000000099FAFF9FF0FAB0F9FBEF9FFFDBFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFBFFDFBFFFFFFFFEFCB0B9FBDF9FDBFFEBFAFFFBDBFF000900090000000000000000000009000F09099E90B00900000000000900909ADA900000000000090BFDB9E90B9D9F9ADBDBFFFBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFFBFFBFF9FADBDBDBCBCFBAFBBE9F9FFDFBCFFFFFF90000000000000000000000000000000B0A9E099E9C090B090000090009000900000000000000000909BC99BCDBEBFFFFFFFFADFFFFFFFFFFFFFFFFFFBFFFBFFFFFFFFFFFFFFFBFFFBFFCFBFFFFDFBFFDBFFFAF90B9FFDFFDFFFFBFFFFFFFBDAC0000000000000000000000000000000F9090B0090B0009A000000009000C000900000000000000000009AE9BBF9FDBFBFBFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFBFFDFFFDFFBDFBDBFAFDEBFFBCBDEBD9E9FBCBFBFADFFBFFFBFEFF909F0000000000000000000000000090FC909C900909000909009090000B9090C0900000000000000000999E9CBFAFDFDFFFFDBFFFFFFFFFFFFFFFFFFFFBFF9FFFBFFFFFFFFFBFF0FFBFFBFFFEDFBFDFADFBDBDBEF9F0FFF0FDFFBFCFBDEDBDAF009F9F9000000000000000000000000FB09A90A90000900900900009090000A9000000000000000000000B9FBDBDBFBFBFFDBFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFBDFEFBFFBDFADF9FBFBDFBFDBEDAFBCBDAFBF9FFFBF9EDBFFFBFFFF9F000000090000000000000000000000B0F0900900B0900000B009090B00090900000090000000000900099CBCBDBFADFFFFBFFFFFFFFFFFFFFFFFFFFFFDFBFBF9FDFBFFFFFF9FFF9FFBDFBEFF9FEBE9BE9BF9CBFBF9F0FADBCBFFBFFF0FF0F9E0000000000000000000000000000090F09F0A90090000090909E0000000000000900000000000000000000B9BDAF9FFBFBFFFFFFFFFFFFFFFFFFFFFFFFBFFDFFFFBFFDBDFBFF9FBFF0FFBDBDBE9FDFFDBFF0FBF9E9EDBDBFFFDBDFE9FFDBFBC9FA00000000000000000000000000000F90BD9E9009000000000909090909000900000009000000000000090E9BDBF9FFFDF9FBFFFFFFFFFFFFFFFFFFFFFBFFBDFFFFBFFBFCBFFDF0FF9EFADBDBFBB9AF9ADBCBCBDBBEBF09BFAFBDBF0FAD0FBC9D09000000000000000000000009000B090B0909A009000909009A0000000090009000000000000000000099ADADAFBDBFABFFFFFFFFFFFFFFFFFFFFBFDFF9FFB9F9FFFFFBFDABFFBDFB9FBEBDADEFDBEDF0BDBFADF9F0F0F0FDEFF9FBDBF09B0A90000000000000000000000000000F00B0DA9090000000009000090090000000000000000009000000009ADB9BDBCBEDBDFFFFFFFFFFFFFFFFFFFFFFFFBFFE9FEFF9FF9FDBFFCBDAF9FE9F9E9FB9BADB0BDADADBDAFF9F9FFB9B0F9E9F0DBC0900000000000000000000000000000F09CB09AD0B00000000090900900000000009000000090009000000090F9E9FBDBF0BFBFFFFFFFFFFFFFFFFFFFFBFCF9FFDBDBF9FFBFE9FBFBF9EB9F0F9FADEFDBCBCB9F9FABDB0FAF0BDEFF0F9E0B00B9000000000000000000000000000090BE9009090909009000000009009009000000000000000E00009000009B0F9B0FBDBDBDFFBFFFFFFFFFFFFFFFFFFFFBFFBFFFBCBE9FE9FF0DBCBDBDE9FADB9B9BCB9DBCB0F9FDADBDB9F0A90F9ADBC9F000000000000000000000000000000000F90B00F0B0C00900900900900900B09000000900000909000000000000DBC9F9CBF0BFBFFFBFFFFFFFFFFFFFFFFDFFFBFCBDFFFDFB9FB9FBDBFADA9F0DBCFCFCBDAA99ADBE9ADBCBCF099FBBCB099A0900000000000000000000000000000000B0F09B0909B09000000009000009000090000000009000000000900009BA9FADBF09EBDFBFFFFFFFFFFFFFFFFFFFBF9FDBFEBF9FBDFF0FF9E9E9F9F0FB0F9B0BB0F9DADBC9BDBE9F9B9E009C90DA009000000000000000000000000009000000F09BC09A900900900900009A000009B0000000900000909000090F00090DA99ABCB9BEBDFFFFFFFFFFFFFFFFFBFFFFFEBF9BDFF0FBCBFDAF9F9F9ADF09F9ADBC9F09A9A9BADA9DA9E9E9900BCB00900000000000000000000000000000000900F009B09C0B00B0000009000090000009000000000000000090009000009BDAD9DBC9D9FADFBFFFFFFFFFFFFFFFFFDBFDFCFFADBFDFBDBF9FADB0F9A9F0BD9ADBE9F0D0D09DADA9F9B09ACB090090000000000000000000000000000000000000F09A0F099090D0900000090900090090B00000090000000000000900000009A0B0B0BF9FBFFFFBFFFFFFFFFFFFFBFFFBFBF9FBDBF0FBE9FBDBCBDADB0F0BE9F09B0B0B0BDA9BBCBC0F0D90009000000000000000000000000000000000900000B00D990B0009A000009090000900000000000000000000000000000000099B9F9F09ADBFBDBFFFFFFFFFFFFFFFFFFF0FDF0FBCBE9FBD9F0DADBDADB0F9BC9DA9E9E9C9BDA90D0990B909A0000000000000000000000000000000000000000000F09A0A090B00900000000909000000909000000090000000000000000000000909E9DAF9FEFBFFFFFFFFFFFFFFFDBFFFA9F0DBF9FBDBEBFBF0F0B0DB0D0B0B0F9A90B0009CB0F0A9C0B009000000000000000000000000000000000000090000FB09909E9C900900009000000000000009090000000000000000000000000900B090BDBE9BFFFFFFFFFFFFFFFFFFF9FFDFBFBCBDE9E9F9CF9F9F9FADB0F9E9F0D9F099F0B09909D0B00900000000000000000000000000000000000000000000F00009A90B0B000009009000900000000000000000000000000000000000000909A09AD9FF9FBFFFFFFFFFFFFFBEFFF0FADBCBDA9BFBCBB9E9A9E99B0F09B90BAB0BCA09C9ACB0A9090000000000000000000000000000000000000000000000F99E909DA9000900000B0000009009009090009000000000000000000000000009090BDBE9FFFFFFFFFFFFFFFFFF9E9F9DBCB9EBDF0DBFDE9F9F90F0DADBC0F0D0D00990A9090090000000000000000000000000000000900000000009090009BE09A9A0DAD900000900990000000000000900000900000000000000000000000000090B9FBFFFFFFFFFFFFFFFFFFFFBFADB0F9DA9FAD0B9F0DA9F0B90B09B09B0B090AD909A9009000000000000000000000000000000000900000000009000F9F0909B09AB000000900A900000009000000000000000000000000000000000000090BCBCBFBFFFFFFFFFFFFFFBDBDADFADF0B9F0DBF9E9FBADA9F0F9CB0DB0DAD9A9000B000900000000000000000000000000000000090000000000000000F0B0F0000F9C900000090900900000000090900000000000000000000000000000000009B9FDFFFFFFFFFFFFFFFEFEBDB0DB0FAD0BA90FDB0D9BF09B0B99E9ADA90AD09B00090000000000000000000000000000000000000000000900090000B00F90B0B90B0000099AD0000000090900000000090000000000000000000000000000090FFBFFFFFFFFFFFFFFDBDBDB0FB0F9D0F0D9F0B0DBAD0DBCBC0E909090F9000009000000000000000000000000000000000000090900000000000000F909A9090CBC90000000B0909009000000090900000000000000000000000000000000009A9FFFFFFFFFFFFFFFFFBF09F0DB0B0B9B0B0BDBAD0B9A9B09B9BCBCB0000B0900900000000000000000000000000000000000000000000000900000FA9ADA90B9A9A9000090000000000090900000000000000000000000000000000000000009FBFFFFFFFFFFFFFFBDE9FE9B0DBCB0F09C909C9BD0F9C9E9C90909C9B9900090000000000000000000000000000000000009090000000000090000F0009ADA009C900B00009A90090009000000090900900000000000000000000000000000009FFFFFFFFFFFFFFFFFBF09BC9A990D09E9ADA9A9A90B0B9A9ADA9A9AC0009000000000000000000000000000000000000000000000009009000000B09BBD0909A9AC909000090000000009000090000000000000000000000000000000000009BFFFFFFFFFFFFFBEBDBC9BC9AD0E9A9A909B09D0D0BCB9C9AD09C90909A90000000000000000000000000000000000000009000000900000000000F000CBFAD00C9B090A0900000090009A000000900000000000000000000000000000000000BFFFFFFFFFFFDFD9FADBF0B90B990D0D0BC0DA0B0F09CB0F9A9A90F090000000000000000000000000000000000000000000000000000009090000F9A9090B0B0B00F099000000000090090900000090000000000000000000000000000000009FFFFFFFFBD9A9E90D090D0BD0A9A90B099A99C909B090B0D09CB090A9090000000000000000000000000000000000000000000000000000000000F090B0BDBC90090BC009000000000090900000900090000000000000000000000000000009BFFFFFF9FCBFDB9BDB9B0B9C0BD090B0DA090A9A90C9AD90B0B09CB0D0000000000000000000000000000000000000000000000000000009000000B0AF0D0BCB9A90BCB090090000000900A90000000000000000000000000000000000000000BFFFFDFBDBFCB9EDB0FC99CB9900BC90909CB900DA9B090F09C9A90900090000000000000000000000000000000000000000000000009090000090F9090B0F9BC900090F00000000090000909000000000000000000000000000000000000009FFFFFBFFFDBFFFB0FDB9FA90BCB909A90B0900DB090C9E90F0BC90B00B000000000000000000000000000000000000000000000900000000000000FA90BCB0F0BE909A9A9F000000000909000B00090900000000000000000000000000000000BFFFFFDFFFF9FFDFBFE99F9F090CB0DA9CB09A09A9B090B09909A9C900900000000000000000000000000000000000000000000000000900000900F9E0909E9F99AD090DA9090000000000090009000000000000000000000000000000000009BFFFFFBFBDFFF9FBDF9FE9F09E9B090909090900D009A9C9ACB0D0B090000000000000000000000000000000000000000000000000000000090000F09B00A99A9E9B0CB09E900000000000900090000000000000000000000000000000000009FFFFFFFFFFBDBFFFFBFF9FA9F9BC9B0A9A90F09A90F090B90990B09000900000000000000000000000000000000000000000000000090000000009BAC0909ACBE9FCB90A90B09090000000009000909000000000000000000000000000000009FFFFFFFFFFFFFFF9FEDBFDFF0F0BC0D90D0909090090F90CB0E9090E90000000000000000000000000000000000000000000000000000000090900F9B0AD09099A9BCB9C009CA00000000000090000009000000000000000000000000000000BFFFFFFFFFFFFDFFFF9FDAF9FBDF9B9A90B0A9E90B09000B09909E09009000000000000000000000000000000000000000000000000000000000090F0AD90A0B0ADBCB0F9A90B90900000000090009000000000000000000000000000000000BFFFFFFFFFFFFFFBFFBFFBFDBFDA9E9E90F09D0900D00B09090A0909B09A000000000000000000000000000000000000000000000000000000900000B0990A9D009BCB9F00909000000000000009B00000000000000000000000000000000009FFFFFFFFFFFFFFFFDFDF9F9BFCBFDBDB0F909A09A9009090DA0D9A090C09000000000000000000000000000000000000000000000000000000009090F00AC90A9F00BCB09B09E90900090000000009000900000000000000000000000000009BFFFFFFFFFFFFFFFFFBFBFEFDFBDFADBCB00F09B9C90B009A099A09F00900000000000000000000000000000000000000000000000000000000000009AB099A900BD09ADAD0F090000000000000000000000000000000000000000000000000BFFFFFFFFFFFFFFFDBFDEDBDBE9FB9FBCBDBB0F0C0B0909E09000900090A90900000000000000000000000000000000000000000000090000000090900F0A0A09A90A909B9A909A090000000000000009000000000000000000000000000000BFFFFFFFFFFFFFFFBFFDBF9FBDB9EDFBCBDAD0D0B9B0DBC90909A9CB09A090000000000000000000000000000000000000000000000000000009000009BB00909E9E99F0F0E90F09000000000000000000000000000000000000000000000009BFFFFFFFFFFFBDBDFBDAF9FAD9EDB9A9F9E9ADBBDAC9A09A90A09000900D009000000000000000000000000000000000000000000000900009000909A9CF0A0B0009A00B099F00B0000009000000000000000000000000000000000000000009FFFFFFFFFFFFFFFADF9F9E9DA9B0ADBD0F9BDB0DA9BC9B0909090909E0909A000000000000000000000000000000000000000000000000000000000990BB0090B9A09A9CBE09B0D000000090000000000000000000000000000000000000009FFFFFFFFFFFFBDF9F9BE9F9EBDAD9B0DA9AD0BCBBDE9B0DADA9C000B090A0090900000000000000000000000000000000000000000000000000900000AD0F00A00ADA0D0B09BC9DA90000000000000000000009000000000000000000000009BFFFFFFFFFFFFFEBF9F0DB099099A9C9B0D9A9DB0DA9F0DA9090B09000090900000000000000000000000000000000000000000000000000000000000B09BA0009A99090A9CBCB0A90000009090000000000000000000000000000000000000BFFBFFFFFFFFFFDBD0DADB09F0F9AD09BCB9A9CBADB9F09A909E9090090900000900000000000000000000000000000000000000000000000000900090D0BCF0A0A9AA9A09A9A90F900000000000090000000000000000000000000000000009FFFFFFFFFFFFFBFDBFB990F0909C90F09090D0B9DADADFF90F09E9090000A90B000000000000000000000000000000000000000000000000000009000B0B09B009009AD0BC09CB90BD000000000900000000090000000000000000000000000BBFFFBFFFFFFFDFBC90DAD990F90B090BCBCB090E99B9A9DA909A90F09A090000909000000000000000000000000000000000000000000000000000009090F0B00A0A0B0BC9A9A9E9CB000000909000090000000000000000000000000000009FFFFFFFFFFFFFF9DB9F9DBCF99090DAD09090DA990F0F9FADA9AD0B9000900090000000000000000000000000000000000000000000000000000909009ADB00E000090B000B009E9AB900000000009000090090000000000000000000000009FFFDFBFFFFFFDF9FBDFFDBFDBDADA9099A9BC9B0D0B0B9EBDB9C90BCA90900090090000000000000000000000000000000000000000000000000000A0B090009B0000A90BB00DA09BD0E9000000090090000000000000000000000000000000BBFFBFDFFFFFFBFFDFFDBFFDBDBD9DB9009C9A9C9AD09C99FADA9A9099CB009000009000000000000000000000000000000000000000000000000009090F0090BB00A00A000B0A9F00B99A0000000090A0000009000000000000000000000009FFFFFBFBFFFFFFFFFDBC9009090B09CBDB0909A909A9A9ADBDBD0D0BCB0090009000000000000000000000000000000000000000000000000000000090909A090F0A00A9A9A099009F0FAD09000000009090009A00000000000000000000009FFFFF9E9FFFFFFFDBCB09BD9A9AD09E9090DAD090F09C90909BFAB0BC90DB0E90009000900000000000000000000000000000000000000000000000900F00090CBA0000000A09A0E9B0B0909000900009000000000000000000000000000000BFFBF9F9FFFFFFFDBC99FFFFADFF9E909009099ADB09A9ADA9BCF9D090B0B00900000000000000000000000000000000000000000000000000000000009090B09B0B00A00B00B0B09ACBDE9A9E90000000090000909000000000000000000009FBFFDA9BFBFFFBD9BFFFFFFFFFFEFF0F090A900900F0D090909B9EB0F09C90909090009000000000000000000000000000000000000000000000000909A0000000BF0000A0A0000B09B0B9C909A900900000090000000000000000000000000BFFFFBDA9FFFFFD0BFFFFFFFFFFFFFF9BFAD9AD00990B0F0BC9ADBDF90B0B0DA9A009000000000000000000000000000000000000000000000000000090909090900B000A0900A0B0B00F9E90B09C09000000900009900000000000000000009FFBF0F99FFFFF00BFFFFFFFFF9EBFF0BCFDA9F009000909909AD0BEB0F0909A90C90000000000000000000000000000000000000000000000000000000B0000A009AA000000A00000BCB9E9A90C9A90000000000000A0000000000000000009FFFFFF90BF9A9909FFFFFF9F009BDB0F0FBA9CB09AD00909E9A90BDB9D0BDA9090909A900000000000000000000000000000000000000000000000000090009090BA9F0A00A000A0B00B00B09A9B09A000000000900990000000000000000009BFDF990BDFFDF09BFFF9E9E99D000090909C0B0F009A000090DA99ADFA990DA9E9A0000000000000000000000000000000000000000000000000000009A900000009AB00000B00000A90F90F0D09A9D9000000000000E909000000000000000BFFBFE9A9B090900F9F9F9F9E9BD9B0CB090900909009090090090F9B0F00B0909090900900000000000000000000000000000000000000000000000090009009000B0F0000B0000000A9A0B09A9E9E0A9000000000009000000000000000009FFFF0909D09A909B9F9F9F9F9FCB0D99090B09909090000000090B00DFBDBC9ADA9CB00900000000000000000000000000000000000000000000000000090000009BCBB00A000A000A9A9AD09E9F90999C09000009009A90900000000000009FFF90B9F9A9FDFBFFFFFFFFFFFFBFDBF0BDA9CB0A90AD909090909909B90009A9090900900000000000000000000000000000000000000000000000009000000900B0A0A0000A00A00000B0BDA90ADB00A900000000000000000000000000000BFBE9090F9FFBFFFFFFFFFFFBFFDBF09F09DA9BD9E99A09A9A9A9ACB09E9B9AD09A9A09A0000000000000000000000000000000000000000000000090009000009009A9F00000B0000A00A00BCBD9ADBD00B0900009090909000000000000009FDF9900B0FADFFFFFFFFFFBDF9FBCBF09F0BDADA99E9DA9C90D099090B9C0D90B09C90D090900000000000000000000000000000000000000000000000000000009A00AB00A0000A000000B0B9A9ADA9A9009A0000000000000000000000000BFFBBCB099BDBFBFFFFFFBFFFAF9FBD09A0909909F09A99E9A9A90090900B9A0F09A990A90000000000000000000000000000000000000000000000000090000090A0B09F0000A9A0000A0B009ADADA9AD09000000090009090000000000000BFFDBC9909BCBFFFFFFFFFFFDBD9F0D0B9C99ADA9F09AD0F090D09E9B09E9900990D09A09009000000000000000000000000000000000000000000900000000090BC9000AA000000000000000B0DBDB0D09E9E909000000000000000000000099FBFDBF0BC099BDBFBFFFFDFBCA909A9009AC909B0BD0B90B0B0B0990F90B0F9E0B0B0C909A000000000000000000000000000000000000000000000000000900009A9AB0B0A000A000A00B000000BCBADA909A0090000000009000000000000BFFFBDBD9B9A9FADFFFFFFF9F99E09009A99A9B0C9CBD0F0D9C90B0FB0BD0909900909B00C90909000000000000000000000000000000000000000000000000009000A90BF0000A90000000000A9B0BD0B09E909000000000090000000000009FFFFFFFBF09D09FFBDFFFFBE9F099009000090C9B9A9A99B0B9BD9F90D0B9E9A0BDA9009A90000000000000000000000000000000000000000000000000009009ADA90A00B000000A0000A0A00900FF0B0DA90F000000000000000000000009BFFFBFDBD0DBA9BF9FFFFF9FDBE9B00900909009BC0DBD0F09CBC9E90F9BDA909D9009E9090A9000000000000000000000000000000000000000000000009000900900B0FBA0A00B000000000A00A90B9E9A9E90B00000000009090000000000FFFFFFFFBFBD9E99FBFFFFFBFDF9C9BC9B09C9B009B09A90F9BDBFBDB9E90DADB0A9B09A90900900000000000000000000000000000000000000000000000090A90A0B0B0AF00000A000000000009A9CBDAD09AD090000000000000000000009BFFFFFBDFDBE99F0BDBFFFFFFBFFBC9B0DA9A090909F09F90F0F99CBCB9F9B90D9C0D0900F0900090000000909000000000000000000000000000000000009009090B00AB9B0000A0000000A00B0A9A90B9A9E90BC000000000009000000000BFFFFFFFFBFF9FE9BDBFFFFFFFFDBCBD0F09D9F0F09A09E90FBDBEFBDBDA9E9E9A9B9A9A90900B0900009009E9ADA0000000000000000000000000000000000A900AB0A900EA0000900000000000A0B09E9E9F09A900000000000900000000009FFFFFFBFFF9FF9BCBDFFFFFFFFBFDB0B09F0B099009DB9BFBDBF9BDB0F9F9B9F9AD0D09C9009000009000B0909090000000000000000000000000000000090909A9009A9ABF0A0A0A00000000A09000A90BCBCBD09000000000000909000000FFFFFFFFF9FFF9FDBFBFFFFFFFFDFADF9DB0BC9E0D9A9CBD9DBCBFDBDF9E9E9E9C9A9A9A9A9A0900900009C909009B00000000000000000000000000000000900A90ABE0A00B0000A9000000000A0A0B0BC9A9B0AF0000000000000000000009BFFFFFFFFFFFBFBFDBDBFFFFFFFFBDB0F0DBDBB99A09B9EBEBFBF9FE9FBDB9F9B9BDB0D9090900900009009A90B00C90000000000000000000000000000000A909A990B00B0F00009A00A0A0000000900B0BCBCBD00900000000009000000000BFFFFFFFFFBDFFF9FFFFFFFFFFFBDFFDB9A909C9A99FCBDBDF9FDF9BFBC9F9ADE9E90F0BD0B09A00900009090C909B00000000000000000000000000000009009E0A0B00B0AA0A00A0A0909000A9A0A0B0F09A9B0B9E09000000000000000009FFFFFFFFFFFFF9FFFFBFFFFFFFFDFBCB9E9CBCB0D0F0B9F9FBF9FAFFDBDBE9F9B99CB990A9C9000900909A09090F000000000000000000000000000000000090BA90B00B0A0F0000B009AAA0000000000B0A90C9C009A0000000000900000000BFFFFFFFFFBFFFFBFFFFFFFFFFFBDDBDE90B909B0B9BDF9EBDEFBDF9ADBF9F0F0F0BC9E9DA900900000009000B09090000000000000000000000000000009A9AD0A9AA00A00B0A000BAE9000000A000090B9E9A09B90D9000000000000000009FFFFFFFFFFFFFBFFFFFFFFFFFFFFBE9A9F90FBCBD0F9A9F9FBDBFBDFF9F0F9F9F9F9B09A909A90909000009A90BCB00000000000000000000000000000000909A90090B00B0F0000B0B0A0A0A0A000A0A0A09A99AC09A0900000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFDF9F9F0BD09909B9CBDADBDBFDFBDBF9F9F09E90BC9F9E9E900A000909009C909000000000000000000000000000000009CADA0B0A000B00A000A0A00000000000000090BBC9E090BCB000000000000000009FFFFFFFFFFFFFFFBFFFFFFFFFFFFBCBD0BD0BDADB0FBDBFFFFDBFBDBF0F9F0BDB0BD9A9090909090900000900000900000000000000000000900000000009A90900A09A000AB000000000000A000A0000A000B09B09090B00000009000000009BFFFFFFFFFFFFFFFFFFFFFFFFFFFDF0BDA0F9A9BCB0DAF9BCBFCBDEBDBFE9F9AD9CBADADA9A9E9000000090B000000000000000000000000000000000009009A0B09A00A0A0F0000000A0A0000A0000A00A9A9F0D009A9C90000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFBF9F09DB09D099DBDBDFFBDBFFBDBFDB9F9F9BA9D909B0D09009090000000900000000000000000000000000000000000B00900A00B0009AA000000000009A000A00000000A0B9A9000B0000000000000000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBDA09F9A9E9A9ADAF9FFF9FDBFDADFADAD0DB0BDAD9A909A000090000900000000000000000000000000000000009009E0A900A00A9A0B000000A0A00A000A000000B0B9BCAC00090C9000009000000009FFFFFFFFFDBFFBFFFFFFFFFFFFFFDBDA99F0AD0909FDBD9F0B0F0BFCB9FB9DB9FB0BDA9A090F0909000000900B00000000000000000000000000000009009009000A90A0000E00A0A090000000A9000A000A0A0B99090A90A00000000000009BFFFFFFBFFFFFFFFFFFFFFFFFFFFBF909F00990B9FA9ADBEBDBD9BD9BDFBDFADE90F099C9F09090DA90000000900000000000000000000000090000000A09A90A9A900A9A9A0B000000A0000A000A0A00000B0F0ACB0090090900009090000000BFFFFFFFFBDADBDBFFBFFFFFFFFDFFFA9BDADBC09FDBC99DADAF0BE9BDEBDB9BF99F0BB09A9A9A0000000000090000000000000000000000000000000900C0B000A0A000A00F00000A0000A000B0A0000A00BA90B00909000000000000000009FFFFFFFFBCB9B0BC9FDFFFFFFFFFF09D0909099BC9A9B0F0F9D9FD9FCB9DADFC9AD0BD0F0D09C9909000000000000000000000000000000000000000909A9900B00000A900AB0A00B0000A000A0A000A000B000B0DA00A009000009090000009FFFFFFFF9F9F0D99BDAFBFFFFFFFF9F0BCB0BCBC9A9C0F9B0B0A90B0B9FABDA9BDABD0B909A909A0000000000000000000000000000000000000000000090A0B0A00A90A0B0A00A000A0000000090A0000A0A9A9A0D009900000000000000009BFFFFFFFFFFBF9E90B99FDBFFFFF9E90909C909A909B90D0D09909090909DA9DABD09F0CB0D0B0090000000000000000000000000000000009000009099AC9A090B00A0B000F090A00000A00000A9A00009A000A9A0900AC0900900090000000BFFFFFFFFFEDBF9F9CBCBFFFFFFFFDBDB0B90B090DAD0B0B0F0FBCBCBC9A99E9D0F9A9B909A9090000000000000000000000000000000000000000000A09B09A0A00B000A00A9A000000A0000A00A00A00A00A09A90B00990000000900000000FFFFDFFFF9FBCBCBCB99F9FFFFFFFBE909C09C90B090BC9F9BD0090909AD0B9B0B9ADAD0F090CB09000000000000000000000000000000000000000090DA0A090B0A0A9A90AB0000A00A0000090A00000B00009ADAD0C900A000009000000009BFF9BBFF0FBC909099ACBDBFFFFFBD99CB09A9AC9BCBDBBD0F0F9BCB0909ADACBDAD990B090B90000000000000000000000000000000000009000009A9A9009AA00009A0A00FA000000000000A000000A0000A0BA9A9BC9090000000000000009FFFC909FFC0000000990B9BFFFFFADA9090009900909C0FBC900090BCB09099909ADAD09A90009000000000000000000000000000000000000000B0C9A0B0A090B0A000000B0A0A00A0000000A0000000A00000F0F00B0F0900000000000000BFF90090BFF00000000090FDFFFFDFBCB0E99000B090B9F0FE00000090090000090909A9C90DA900000000000000000000000000000000000000090B909A0F9A0A0A9A0B0A0F000000000000A0000000000000A9AA9BD0B09A000090000000009FBCB0009EF0900000090F9BFFFFFBD9099000B9D00900BFF00000000900090B0A9A9A9CB0B0900000000000000000000000000000000000900090900EB09A00B009A9A0000B00000A00000000000000A000A09E090F0ADAD000000000000000FFFFDA9009000000099A9B0FFFFFBC9A090009000BD009FFC0900000000000909D090D9A909000900000000000000000000000000000000000900DAC9B00A9AB0B0A0A9A000F0A0A000A0000000000000A0000ABFAB0F909A9000090900000099FFFBDA9000000900009C9FBFFFFFFE9DA0F009090A9F000F000000000009A0900B09A0900009000000000000000000000000000000000900009A09B00BE9A00A000B000A00B00000A000000000000000000000009AB0F09C00900000A900000ADBFFFFBD0B0900909C9B09FFFFFFBDA9900900D090090900000000009000900B09E99CA909000000000000000000000000000000000000090009000B00B09A90BA00A090A0F000000000000000000A00000000BAA90F9E9A900000009000009BFFFBFDFFBDF0F0A99A9CBFFFFFF9FF9CB09A90A90090F0F090009000090909090C90A900000000000000000000000000000000000000000000900BD0B0A0A9A0000A90A000A00A00000000000000000A00000A0090A9A090090000000000000BFFFFFFBE9E9B9F9DA9DBBDFBFFFFE9CB0C90099009000909CA9900D99CB09AD0B90B909000000000000000000000000000000000000009000000090A0B0A9ACAB0A90A0000B0000000000000000000000000009A0A9ADBE90000090009000090F9FFBFDF9F9E90B099A9FFFFFBFF9FBC9B00900090B0909A99CA990A0909C9A9CA90C00900000000000000000000000000000000000000000090B0A9A0B00AB0000A000000F0000A0000000000000000000000A9A00009009090000000000009FAF9E9ADA0909009AC9E9BFFFFFBFCBB0C9F0F0B09090BC90B99CB990B0B0090900B0900000000000000000000000000000000000000000000000D0A9A0B000B00A9A0A000B0A000000000000000000000000A0A09A90ADB00009B000090009BFF9E9C9090000090D9B9FFFFFDFFFBD0F9A090900000909A9C9A900E90D09F09A9D09A900000000000000000000000000000000000000900009090A9A090A9A00A00000000A000A00000000000000000000000900A0009000909000000000009FFFF9B00000909ADBAFFDFBFFBFFADAF90090000090909AD09ADBCB99E9A000090A00000000000000000000000000000000000000000000000000A9A0B0A9A00A00A0A0000F0A000000000000000000000000A0A000B0009000090900090900BFFFFFFFBDB9FBFFBDF9FBFF9FFFDFBDFE990090900000090BC90090009090909E090909000000000000000000000000000000000000000000909ADA900B000A00000000000B00A000000000000000000000000B0A9000F00B9000A0900000909FFFFFFFFFFFFFF9FBFFFFFFFFFFBFFBF9EBD0A000000000009A9A9CB000000B0900000000000000000000000000000000000000000000000000090A0A9EBA09A0A00000000F00000A00000000000000000000B0000A090090C0909000000000BFFFFFFFFFFFFFFFFFFFBFFFFBFFFFFDFFFDAF99090900900900D00900909090900909090000000000000000000000000000000000000000009A90A9E9A900AA000000A0000A0A00000000000000000000000A000A00000B009B000090000009FFFFFFFFFFFFFFBFFFFFFFFFFFFFFFBFFFBFFFDEF0B009009009009009CB09000000000000000000000000000000000000000000000000000000009A9A0A0A900A000000000F00A00000000000000000000000BA900A00900B00F090009000909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBDBCBDA09A09A09A90B00000000000090000000000000000000000000000000000000900009090FA00090000A00000000000B00000000000000000000000000000A900009009009E9A0009009FFFFFFFFFFFFFFFFFFFFFFFBFFFBFFFFFFFFFBFFFFBCBDBC9F0900009090000000000000000000000000000000000000000000000000000900A0900B0A00A00000000000000E00000000000000000000000000B0A00A0000090B00909909009ABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADFF9E9B0000090900000900000000000000000000000000000000000000000000000090090DA0B0A90A000000000000000B0A00000000000000000000000A0A000000A9B0090B0BCA00A909FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFDFFB9EBD0090900000000000000000000000000000000000000000000000000000000090000B09A0090A0000000000000000F000000000000000000000000000000000000099AD0D09090900BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFBF9EF9009009090900000000000000000000000000000000000000000000000000009000090DA00B0A000000000000000000A0000000000000000000000000000000000000AC9A90B000009C9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBFFFF9DE900900A090000009000000000000000000000000000000000000000000009000090A909A90B0A00000000000000000F00000000000000000000000000000000000090909CB0D0B0009BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFDAF9EB900DA90900000090000000000000000000000000000000000000000000000000000090BC90A00000000000000000000B000000000000000000000000000000000000A90B0B09A90090B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFBF9F9000B0900090009000000000000000000000000000000000000000000000090000090A9AD00B000000000000000000000E00000000000000000000000000000000000090090DAD0900009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDFDBCB090090909000000000900000000000000000000000000000000000000000000000009C90BA0A00000000000000000000B00000000000000000000000000000000000009ADA90B00F009A9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BCBD0090B00B09000900900090000000000000000000000000000000000000900000900A90BD090000000000000000000000F00000000000000000000000000000000000A009090BCBD090009FFFFFFFFFFFBFFFFFFFFFFFFFFFFFFBFFFA90F9DB9A090D00900009000000000000000000000000000000000000000000000000000900090F00A0A000000000000000000000A0000000000000000000000000000000000000B0B0F0900B0099BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9FF9DA9C0909A90090000090900900000000000000000000000000000000000009000000000BDA9A9000000000000000000000000B000000000000000000000000000000A00000909C909EBD00B0C9BFFFFFFFFFDBFFFFFFFFFFFFFFFFFFFFBD909EBDA90009009009009000000000000000000000000000000000000000000000000090090009C00B00000000000000A00000000E000000000000000000000000000000000000009ADB090AD009A0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9FBDB0F0900B900900000909000090000000000000000000000000000000000000000000009BCA9A0000000000000000000A00000B000000000000000000000000000000000000B0A909F9F9A900999FFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFDA9FADF90009C0000900900000900000000000000000000000000000000000009000090000B00990900A0000000000000000000000A00000000000000000000000000000000000000D0BE9A00DAD090BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFF090F9F90009A9090B0090090090000009000000000000000000000000000000000000009AD9E90E00A000000000000000000000000F00000000000000000000000000000000000B09A909E9F9A909A9E9FFFFFFFF9FFFFFFFFFFFFFFFFFFFDFF09F9F9A900090009000009090000900000000000000000000000000000000000000000000A09009000000000000000000000000000A000000000000000000000000000000000000009E9E9A9C9E90909BDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A9E9ED000909000900900009090000000000000000000000000000000000090000000099D0A9A0A09A00000000000000000000000B00000000000000000000000000000000000A09A909F9E9A90F09BCBFFFFFFFDBFFFFFFFFFFFFFFFFFFFFBC09BDA90909A00090000090900A0900009000000000000000000000000000000000000BCA009C9000A000000000000000000000000E0000000000000000000000000000000000099AD00B0A9E9E90BC0B9FBFFFFFAFFFFFFFFFFFFFFFFFFF9FC99FDA9000090909000909A0009090009000000000000009000000000000090000000090090B0B0A009000000000000000000000000B000000000000000000000000000000000A0A0DAFD099E909E90BD0F9FFFFFFDBFFFFFFFFFFFFFFFFFFFBF009A909009E0009A9000090900000000000090000000000000000000000000000009A0F009CBC000A00A0000000000000000000000B000000000000000000000000000000000090B09A9AC99FA99AD0B9ADABFFFFBFFFFFFFFFFFFFFFFFFFFDE900D0009009900000090900090909009000000000000000009000000000000000000D9009A90B00090000000000000000000000000E000000000000000A000000000000000000000DADADB0E9DAD09BC09BDF9FFFF9FFFFFFFFFFFFFFFFFFFAF099B09000B000909000009090000000000900090000000000000000000090000000B0AD0B0DA00000A000000000000000000000000B00000000000000000000000000000000000A9B0BDB0E9FADA9BCBDBCB9FFFF0FFFFFFFFFFFFFFFFFBF9FD0BC0009009009A900090900A09A9000900000000000000000000000000000000099C090B0DA9A09A00000000000000000000000000A00A0000000000A00000000000000A0000000009CB0F9B09F9E9B0B09ADBFFFFDBFFFFFFFFBFFFFFFFFFF0C0B0B000909000009000009090000900000090000009A0090000000000000000000BDA9C9A000A0000A00000000000000000000000F0000000000000000A0000000000000000000BCA9CBCF0F0BCBCE9CB0DADBFFFADBFFFDFFFFFFBFFFDBDFB09C909009E0900900090900009090000000000000000900009000000009000000B0009A0F9A009A000000000000000000000000000B00000000000000000000A00000A0000000000090B9B0F9E909B99A9CB9A9FFBDBFFDFBFFFFFFFFFFBEFBC9A900000090009000000009090000090009000009000000000000000B0000000909E90D90009A00000000000000000000000000000A0000000000000000000000A000000000A0000B000C0FDA90BCBCAFDB90FDFBDCBFFFFFFFDFFFDFBDFDBC9090B090090909009090909000A9000000000909000A900009000000900000009ADA90F00A0B0000000A00000000000000000000000F00000000000000A000000000000000000000000B0909ADF090DBD9A9E99A9FFB9FFBFFBFBFBFBFDAFBDB0000000090A0000000000000090009000009000A0090000000000000C90000900909E90B00000A00000000000000000000000000000B00000000000000000A00A000A000000000A000000A909ADF0B0FADDA9EBDA9FED9FF9FDFFFFDFAF9DAFCB0090000090900900000900900900000900009090000009000000090A00000009A090E900A9A0000A00000000000000000000000000A000000000000A000A0000000000A000000000A009000A9A0F0F9FAB9C90B9EDB9A9FFFBFADBFFD9EBDB9C090090090000900009000000000000000909000009009000900000090000000AD0F090A90000000000000000000000000000000000F000000000000000000000000000000000000009A009E9C9F9F0F0D0DA9E9C9B9E9FFDBDFDFFDB9A99F9E90000000000900000000009090090009000A000000000000900000090000000990B09A000A00000A0000A0000000A00000000000000A00000000000000A00000000000000000A0000000B0090B00B0F9FAFAD09A9E9E9ADBBEFBF9FBED0FF0F0000900009000000000009000000000000909000009A90000000009A0000900BCAD0A00A00000A00000000000A00000000000000A000B00000000000000000000A0000A00000000000A0000B00090CBCAD9F9A9C90909C9ADF9FDBF0F9A90BD9F00000000090090000000000000000900B00C09090000000900000090000009090A90B009A0000000000000000000000000000000000E000000000000A00A00A0000000000A0000000000A9009E0B09F9AF0DF09ADA9A909B0F9ADAF9E99F9A909090000000000000000000900009000900B000000900090000009000009009E0900A00B0000000A000000A00000000000000A0A0000B000000000000000000000000000000009000A000000B00909ADAD09A09A909C90E90DB0FDBDBC9E9A9DA00000009000000000090000009000A900D09009C90E900000009A0090900DA09A0B09A0000B00000000000000000000000000000000A00000000000000000B00000B000A0000A0A009000B00900C000BEDADBC9CB0009090BC9B0BC9B090DA090000000000000000000000000009090E9A0090A0A900000000000000000B00B0B00A0000A000A0000A0000000000000000000000000B000000000000000A000A0A00000000000009000A000A00B009099A90F0B0CB0B00090BC9D0BC9ADB0900000000000000000000000000900000900900090900900000009000900BC0B0B00F09A9A00000900A000A000A000000000000A000A00E000000000000A0000A00000A0A000A000000A00000000900B00009E90FCB09C0090E909A0BC9A9009000000000000000000000000090000B09A9D0B9E0000B00000009000000F00B000F0A0A000900A0A00090000000000000A000000000000B000000000000000000000000000A000A00A0000000000009009E9E90F0B0D0A900A90000909AD090000900000000000000000000000A09D0DAC9A00000009C00000900A009E900B0BEB0A909A9A0A09000A00A0000000000A00000000000000A0000000000000000A0000A000000090000000A000A000000090090CB0C9CBC9C9FD0009000009E000000000000009000900000009090900B0900090D009E9000000A0909A09A9B0A90090A0A000000A00000000000A000000900000090A0000F0000000000000000000A00000A000A00000009000000A00000B00B0F9B0B09A000AD00000090090000000000900000D009009000A00D0B0090BCBCB00B00000000900000DAD0ACBCA9A0B09000A9A000A00B0000000000000A0A00000000000A00000000000A000000A09000A000A000A000000A00000900000000900C00DAD09FF00000000E9000000000000009CB0000000090909A90DADA90900090000009000009CB090B0B0A90E9ACA0B000009009000A0000000000000000000A00000B0000000000000A00A900A0A000000000000A9A00000000A0000909A0FBC9A90FF000000000090009090000090C9A0000B00BC9A9E9E90CB000000000009009000009B0B0D0A0B009AA900B000A9A00A00A00000A000000000000000A0000000E000000000000000000A90000009A00A0000000000000A09A9000009090B0DCB00F090000090009A0009009000B00909000900BC9009CB0000000000000090A000900C9CB0B0DA9A0900B009A9000000B00A0A000000000A00A0000000000000B0000000000A000000000A00A000000000A0009A0000000000A00000000DAA9CB00009CB00C9AD0909E090CB0000000099E0F9000BCA0000009000000900A90000E9A9A9C9EB0000BCB00A000A0B0A00000900000000000000000000000A0000A0000000A00000A0000A009000A00A09A090A0000A0000000A90000090F09D0BC90B0E90FDBAD0ACBC09A0900D0D0B0F0E90000BC009000090000000900D00090900D0DA9B00B0FB0A00B0B0A090009000A000A000000000000000000A000000F000000000000000A000000A00000000000000A000000000000A0A000A0900A09AD009BE9A0C9AD9C0B0C9009A90BC90090D0E90090000000000090F00B00000A0BDA9A9AC0BCB0000B00000900A00A0A000A0000A0000A00A000A0000000000A00000A0000A000000000A00A000B00A000A0000000000000000000B0900B0D9EDA0D009C9DBC9A0B9CB0EBDADAD00AD000A9000000C009000000A000D000009C9009E9E9A90A0B0B00A9A9A0B00A00090A00000000000000000000000000000B0000000000000A00B00000900A000090A00000000000A00000000000A000A0B0FDAAF0F0A00ADDACB0D90E90000AD000AD00000009A000000000909A0090B00B0F09B09A0A9000A0B0000000000900A0090A90A000000000000000000A00000E0000000A0000B00000A9A0A000000A000000A000009000000000000009A0900B0BDD0D09D099A0BD0E0AD000009000009000000000090000000D0E0090A0C90C90BE0A00900A9A0900B0A0B0A000A000A0000000B0A000A000A0A0A00000000B0000000000A0000A00000000000A0000000000000A00000000000000A0090A0000FABEBEACA0C9C0A9090000000000900000000909000000909A90900C909ADBAF0090B0A0B0009A0A00900009A0009A90A0A00000000000000009000000000A000000000000A0000A9A9A00A000000A00A090A00000000A00000000000A09A9A909C9C9DBD09A09C00CB000000090000000000000000000AC00000D0BCBC9A090B0A000900A9A0009A0A0A9A0009A00A09009A000000000000B0A000000000B00000000000009A000A000B0000000900000A0000000A000000A0000000000000A0A9A0A00BE090A90090F090900A00000000000000000BC9090900A9090BE9AAC090A9A0A90000A00090B0009A000B09A0A000000A00000000009A00A00000E00000000000B0A000009A000000A00A000900000000000000000000000000A00000900909FC9CADC0F00009E000909AD0A000000009CB0000A0AC9E90F0F0B0D0B0A0900900A09000A9E000B0A00A000A0900A00A0000000000A9A000000000B000000000A000000A90A0000A00000000A0A0000000000000000000000000000000A00A0A0BFADB0B09CB0F00C00000009000009ADA00C9CB09C9A90F0BA90A0B0B090A0A0000A0B09A009A00000900B000A90000000000000B0000000000A0A00000000000A0A00000000A000B00A900000000A00A00A00A000000000000000000000009000DADEDE0AC90F9B000000000909BC909F09A90D0B09E9AF0DA09A0000A00000A90000A00B0A90A09A0A00900000000000000000000A0A0000090B00000000000000900A0A090B0000000A00900A000000000000A00A00000000A00000000000B0B0B0BD090000ACBCB09090DADADAFCA9E9CB0AD0FE9E90BA9A09A9A000000000A09A9A00B0AF9A00000A0A000A00000A000A00000900000A000E00000000000000A0A0909A000B0A90000A0000009A000000000000000A0000000A00A0000A0000000ADA0B00D90F0DADAFADADAD9BDE9FADFDAF09A9A00000000009A00000000000A0B00BB0A00B0B00000000000A0000000000A000000000AB0000000000000A000000A0A9A0000A00000A009A00000000000000000000A00000000000000A9A0B0900D0DB0ACB0F9E90D0F9ADAE0BDAD9A0B09A000000B0A00B0A000A90000B0B090A9ACB09A00009000000000000000000A000A000009A9A0000000000A0090B00A9A90000B00090A9000000000A09000000A0000000000A000090A000900000000B09A0D09C9ACBCB0B0ADAD9F0A90A0B0A09A9A9A0000B009000000A0A00000A00A9A0A009A0A0A00A000A0000000000000000000A000B0000000000000A0000000A0A900A00A000A9A0A000000A000000000A00A000000000A00000A00B0A0B00A09A09A009000000D090A009000900000000009A0900A0A0B00000090A9A90A9009009A009000000000000B000000009A90A0000000E000000000000000A000A90090A9000009A9009000A0000000A0009000000000000A0000000000009000900A09A0900A9A009A0A090A0A9A00090A00A00000A000000000A9A9A00000A90A0A00A09A0A9A090000A9A00A000A00A00000000A00B00000000000A00000A900A0A00009A0B00A0A00B00000000000A00A0000000000000000A0000009A0A0A0B09A0A00B00090A09000A909AC0A0A090009A00000009A9A0B0000009A0B00A0909A90A009000A0A090000B000000A90A0000A0000A0000000000000A00000A0900B00A0000A90900000090A00A00000000A00000000000A00009A0A0009090000A909000000A09A00B090A00B009000A000000B00A00000009A0A0A0000B090A0A0A009AA0B000000A00BA0A00000009A00000B00F00000000000000000009A0A00A90B0B00A0A0B000A0000000000000900A0000A00000009000090A0A000B090A000B000000A9A00A0B0B00B0A0B009A000000900A9A0A9A90090A9A00A00000909A090000A90009A0090000000A00000000000A0000000000000000A0A00090B0A00000B090000B00000B0000A00A0000000000000009A0A0900A9000A000A000A000B0B0090000900000B009000A000B0000A00000900A0A9A09A0B090B0B0A0A09A09A090A0A0000A0000A00000000000A00B000000000000000000900B0A0090A0B0000A90A0090A0009A0000000A0000A000000A00000A0A0000009A0090000A00000A0A9A00A0B0B0000A9A9000000A000009A0A9009009A9000A000009009A0BA00A0009000000A0000000A0000A0000E00000000000000000A0B0000B0A0900B0A90A0900A0000A0000090009000090000A900000900900A90A09A000A09000A00090000000000A0A900000B0A00090A0A000000A0A0A0A9A90A0A9A0A0A0BC9A900000A000B000000A0090A00009A0B000000000000000000000A900090A00000000A0000009000000A00A0A0000000A0000000A00A00000000000A000A00900000A000000009090A00A00009000A0900000000090900000A09000000090BA00A0B0A090000A9A00000A000000A000A0000000000000000000A900A9A0A90B0000B000A90A00000A000000900A000A0000A000B00090A90A09A0000090000000A00000B0000A0A0009A90A0A00A000000A09A090A0A0A90B0BA0A0B09A0A09A9000000A000A90000009000000009A0F000000000000000000000A000009A000B00009000000A00900009A000009A00009000A0000A000000000090000A000A000009000000B009009A0009000000B0A00000000A009090A0B0090000A0909A00A9A0A900A0B0A00000000A00000A00A0000000000000000000000A9A9A00B000A0000A00A9000A0000A0000A00000000A000900090A00A09A000A00A000B00000000A00A00000A0A00000A000000000B000A0A0090A00A9B0BA0B0B000A0ADA9000900A09009AB00A00A0000000000B0000000000000000000A09000A9A00A900B00000000000000B0000A900A0090A000A00A0A0000090009A000000000009A00A000000B0000090A9A009A000A0B00A0090900A900A0ABADB00A0B090A900A0B0A0000A0B0BCB000000000000000E000000000000000000000A0009A09A90A000A000000A000000009A000900A000000900900009A0A0A00000A90A900A00000000009000A9000A0009A000A9000BA90A0A0A000A09090BA0AB0000A09A0B000000B00000A9A0000009A00000A00B00000000000000000000000A9A09A00A09000000A0000A00A00A0000A009000000A00A0000A0090090A000000000B00A000000A0A00000A0B090A000000009ABCA0009009A0900A0FA00909A0B09A0B000A09A00A09A9A0A0000A0000000000A0000000000000000000000000DA009A9A0A00000000000000000000900A00A00A9000000A9000000000B0B0A00A00090000A009009A0B00000A90A00000A0A90B009A0A000A0A09A009A0A0900A09AC0B09A09A09A0000090A00000A00A0000B000000000000000000000A9A0A9A000090000A0000A00000000900A00000000000A090A000A9A0A0A00000090090A0A0A00000000000000B0B0A909A000900A9A90A909A09090A09A0A9000A090A09A00A00A0B0000A0B0A00B000000000000E0000000000000000000000009A0009A9A000000000000000A00A0000A900000A0090A009000000900900A0000A00900090B00A0A9A09A0B00A9A0A000A0000000AADA0A00A00A90A0900E9A90AC90A09A90B0900A9A90009AB000A00000A000B0000000000000000000A00A9A009A000000A000000000A0000000A0000A09A0090A00000A900A00A00A900A0090A00B00A009000000A0000A9000000000A0B0A9A90A900000A90A90A0A9A00A9A0A09A00A000A000000A9E000A0000A00000BA000000000000000A000090000B000A00A00000000000000000A09009A00A0000A0000A0000A090900000A09A0A00000A0000A00B0B090B0B0A9A9A9A0090000009AA9A9A9A90A90A09A9A9A900B09A00B090A0009A0B09A9A00000009A00000F000000000000000000000A9A00A0000000000000000000000000A00009090A9000B0900B0090A0A09A9090000090B0009A90000000A0000009A000000A000009A090A00000A90A09A000009A090AA0B00A009000A090A00A9A090000000000AA00000000000000000000A0000000000000000000000000000000000A0A00A00A9A00A0000A000000A00A0A9A9A0A00B0A00A9A9A9A90B0B0B09A9A00B00A00A00B0A9A9A0B00B0B09A9A9A00BA909000B00A0A0B09AB0BA9A000A0B0A0000A9B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000A00A000000000000000000000B00B0A00A000A00B000A0A9A000000000A000000000000000000000000000000000000000000105000000000000DFAD05FE")); - strs.Add(func2(9), NorthwindResources.ToByteArray("151C2F00020000000D000E0014002100FFFFFFFF4269746D617020496D616765005061696E742E506963747572650001050000020000000700000050427275736800000000000000000020540000424D16540000000000007600000028000000C0000000DF0000000100040000000000A0530000CE0E0000D80E0000000000000000000000000000000080000080000000808000800000008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00D999D999999D9D999DB99DD9F9D9D9D99D99D9F9D999BD9FD9D9D9D9D9DFD9F9F9DBDBD9DBD9DB9FD9FDFFFFFFFFFFFFFFFFFFF9D9F9DB9D9DFD9DB9F9BDF9F9D9DBD9BD9F99DBD99999999D9DBDBD9BDDD9F9DBDBD9F9D9D99D9BD999D99D9D99DB99D999D9F9D9F9D9D9999D9B9BDBD99F9D9999D9DBD9FDBDBDBDBDBD9F9D9DBD9D99FD9F9DD9FDD9FFFFFFFFFFFFFFFFFFDBDF9DBDD9F9DBD9DD9DD9D9DDBD9D9DD9D9D99D99999D99D9F9D9D9DD99BD9D9D9D9F9DBD9FD9DD999DB9DBD99D99D999D999D9BD9D9DBDBDD9D9DD9D9DD999999999FD9F9D9FD9D9D9D9F9D9F9D9DBDF99F9DF9F9F9FFFFFFFFFFFFFFFFFFFFD99DF9DB9DF9D9D9F9F9F9F9BD9F99F9F9DBDF9D99D999D9D9D9D9F99BDD9D9F9F9F9D9D9D99BD999999D9D9F99D999999D9F9D9D99F99DD99B9D999D9B99D999D9D99FD9DBDD9DFDBDBD9D9D9F9F9D99DF9FD9FD9FDFFFFFFFFFFFFFFFFFFFFBDF99D9DFD9F9DBD9D9D9D9DD9D9DD9D9D9D99F99999999B9DBDBD9D9D99DBD9D9D9D9F9F9D9D9BD999D9F9D99DBD9D999BD9D99D9D9D999D9D99F9F9D9DB9D9999BD99F9DDB9F99D9DD9F9F9D9D9DBD99D9DBD9FD9FFFFFFFFFFFFFFFFFFFFFD9DDBDB9DBD9F9DBDBDBDBD99F9F99F9F9F9D99D9999D99D99D9D9DBD9F9D99F9DBDBD9D9DBD9DD9F99999DBD9999999F9D9DBD9BDBD9FD9BD99D9D9D9D9D999999D9DFD9F9DD9DF9F9DBD9D9F9D9D9D9FDF9DFD9FDDFFFFFFFFFFFFFFFFFFFFF9F9D9DDBD9F9D9D9D9D9D9FD9D9DF9D9D9DBD9F999999D99D9DBD9D9D9DBD9D9D9D9DBD9D9D9B9D999D9D9D99D9D9999D9F99D9D9D99D99D99F9D99DB999999D9D9DF99F9DDBDF9D9DBD9D9F9DBDBDBDDB9DBD9F9FFFFFFFFFFFFFFFFFFFFFFFD9FDBDBDBD9D9DBDBDF9F9D9BD9F9D9F9F9D9D999D9D999DBDBD9F9DBD9D9F9DBD9F9D9F9DBD9D9D9999BD9F9B99999D99D9D9BD9D9D9BD99D9D9BD99D99D999F9F99FD9DBD9D9D9F9D9DBD9D9D9D9D99DDBDF9DD9FFFFFFFFFFFFFFFFFFFFFF9F99D9D9DFD9F9D9DD9DD9FDD9D9DBD9D9D9DBD999999D99D9D9D9D9DBD9D9D9DBD9F9D9D9D99D9F999D9D9DD9D99999FD9F9D9D9BDBDD9DF99F9D9D9BD99999D9DD9D9F9DBDBDBD9F9F9D9F9F9F9DBD9BDDBDF9FDFFFFFFFFFFFFFFFFFFFFFFDDF9FDBD9DBD9DBDB9F9BD99F9F9D9D9F9DBD9FD999D9BD99D9F9DBD9D9F9DBD9D9D9DBD9F9D9BD9D99999F99D999D9D99D9DB99FD9D99D99DD9D9DB9D9999DBDDB9DBD9DBDDD9D9D9D9DBD9D9D9DBD9FD9FD9DF9FFFFFFFFFFFFFFFFFFFFFFFFBDD9DD9F9D9D9D9DD9DD9FD9D9D9F9F9D9D9D9999D99D9D99F9D9D9F9D9DBD9F9DBDBD9D9DB9D9F99999D9D999999DBDF9D99D9D99D9F9BDDB9DBD9D99D9D9D9B9DBD9DBDDB9F9F9F9FD9D9F9F9F9D9D9FDBDF9DFFFFFFFFFFFFFFFFFFFFFFFFD99F99F9DBDBDF9F9FDB9D99F9F9D9D9DBD9F9D9999D999BD9D9F9F9D9F9D9D9DBD9D9DBD9DD9D9D999D9D9D999D99D99DB9DBD9D9F9D9D99DBD99D9999B9DBDDD9DDF9DF9DDD9D9DD9BDBD9D9D9DBDBDBDDBDFFFFFFFFFFFFFFFFFFFFFFFFFFDFD9FDDBD9D9D9D9DD9DF9FD9D9F9D9F9D9D9F99D9DB9D9D99BD9D9DBD9DBDBD9DD9DF9DBD99F9F9D9999F999999F99D9D9D9D9DBD9D9D9FD9D9D9BD9D99D9D9BD9B9D999F9F9F9F99DD9DBDBDBD9D9D9DBDD9DDFFFFFFFFFFFFFFFFFFFFFFFFF9FD9BDDBD9F9F9F9BD99D9F9D9D9F9D9DB9D9D99B9D99D9DD99F9D9DBD9D9DBDB9F99D9D9F99D9DB99999D99999D9F9F9DBD9F9D9F9F9D99D9DBD99999D9DBDDD9DDBDFD9D9D9D9DF99F9D9D9D9F9F9F9DF9F9FFFFFFFFFFFFFFFFFFFFFFFFFFD9DFDBDD9D9D9D9DD9DF9D9DBD9D9D9BD9D9F99D9D9F99F99D9D9F9DD9F9F9D9DD9DF9F9D9DD99F9D99D9999D9F9D9D9D9D9D9D9D9D99D9F9D9D9D999D9F9D99B9F99D9D9F9F9F9F99F9D9F9F9F9D9D9DF9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD9DB9F9F9FDBDBDB9DBDBD9F9DBDD9D9F9D99999D9D99D9FDBD9F9BD9D9DBDBDB9D9DBD9B9D9D9999BD999D9DBD9DBD9DBD9DBD9D9F9D9BD9999D9BD9F9FDD9DFDBDBDD9DD9D99D9DBD9D9D9DBD9DBDF99FFFFFFFFFFFFFFFFFFFFFFFFFFFF9DBDFDD9D9DD9D9D9DD9D9D9D9D9D99F9D9DB9D9DF9D99DBD99D9D9DDDBDF9D9D9DD9F9D9D9D9F9D999D9999BD9D9F9D9F9D9F9D9DBD9D9D9DF9D99D9D9DD9BD999DD9D99F9DBDFD9D9D9F9F9D9DBDBD9DFDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9DB9DBDB9F9F9F9BDBD9F9DBD9D9DDB9DD99999DBDD999D9FDBDBD9D9DBDBDB9FD9D9F9DBD9DBD999D99D9D9D9D9DBD9F9D9DBD9D9F9D999999D9D9F9BDD99DF99DBDF9DBD999F9F9D99D9F9FD9D9F9DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BDBDD9D9DD9D9D9DD9D9F9D9D9F9D99D99F9D9DDD99BD9DBD99D9D9F9F9D9DDDD9DF9F9D9D9DBD999D99D9DBDBD9F9D9D9DF9F9D9F9D9BD9D99D9BDBD9DD999F99FD9D9DBD9D9D9D9D9FD9F9D99F9F9FFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDD9DB9F9DBDBDF9F9F9FD9DBD9D9F9D9DF999F9B99DD9D9D9FD9DBD9D9D9FDB9BDB9D9DF9DBD9DD999B9B9D9D99D9F9D9F99D9D9D99D9D999D9BD9D9DD9BD99DDD99F9F9D9DBDBDBDBD9BD9D9FD99DFD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9FD9D9F9D9DD9D9D9DD9F9DBD9D9F9F99D9D99DDF99DB9D999F9DBDBDBDD9DDD9DD9FD9D99DBDBD99D9D99F9DBD99DBDDDBD9DBDD9BD9F999D99D9F9BDD999B9DF9D9D9DBD9D9D9D9FDD9F9F9FDF9FFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9FD9D9DBDB9F9F9F9BD9D9D9F9D9D9D9F99D999D9F9D9BDDD9D9D9D9DB9F9BDDBDF9BDBD9D99DBD9999DF9D9D9DF9D9F9D9F9D9BD99D99D999DBD9DD9BD99DD99D9F9F99D9BDBDBD99BD9D9D9D99D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F99F9DBD9DD9D9D9DD9F9F99D999D99DD9DBD9D9D9D9DD9B9DBDBDBD9DD9DDDBD99DD9D9F9DDBD9999DF99DBDBD9D9F9DBD99D9DD9D99D99BD9DDBDBDD999DB9DBD9D9DDBDD9D9D9FDD9F9F9F9BDFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9DBD9DBDBDBDBDBD9D9DD9FDF99F9BD9D9DBDBD9F999DD9D9D9D9F9F9F9BD9FDDBDBD9DB9D9D99D99DF9D9D9DBD9D9D9D9F999DB9D99D9D9F9D9D99D99D9D9D9DBDB9D9BDBDBD99BD9D9D9DD9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9F9F9D9F9D9D9DD9D99F9F9BD9999D9DDB99F9D99D99DBD99BD9BDBD9D9DDDDBD9F9DD9DBD9DBDBD9DF9D9DBD9F9DBD9F9DBD9DF99D99F99DBD9DBD9DB999BD9DBD9D9D99D9D9D9DFD9F9F9FDBD9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD99DBD9F9F9F9F9FDD9D9DD9DD9D9999D9D9D9DDBDD9D9FD99DD9DBDBDB99FDBD9F9F9D9D9D9D9D9BDDBD9D9D9D9D9F9D9D9D99D999D99D9D9F9D9BD9D99D999D9F9D9F99D9F9F999D9D9D9DD9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9DBD9D9D9D9D9D9DBDBD99F9BD9F9DDF99DBDB9D9BD9D99DDB9D9D9D9DDF9D9DF9D9DBDBDBDFDBDDDBD9F9F9F9F9F9DBD9F9FD9F9D9D9F9D9D9F9D9999D99DF9D9DBD9DBDBD9D9DDBDBDBDB9F9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9F9D9F9F9F9F9F9F9D9D9FD99D9D9DB99D9D9D9D99D9DB9DB99D9F9F9F9F9F9DF9F9DBD9D99D99DBF9DF9DD9DD9DD9D9D9D9D99D99F99D9D9F9D9D99D999BD99DBD99D99D9D9DBDB9D9D9D9DD9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9DBD9D9D9D9D9D9F9F9D999D9F9999DF99F9D9F9F9D99D9D9DBD9D9D9D9D9FD9D9FDD9F9DDBDFDDDF9DF99F9BDB9F9F9DBD9D99D99DBD9FD9F9D9DB9D99D9D99D9FD9F99F9F9D9D9F9F9F99F9BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9DBDBDBDBD9F9D9D9F9DDF9D9DFD99DF9D9BD9D9DBDDBD9D9D9DBDBDBD9F9BDBD9BD9D9B9D99BDF9DF9DF9DDDDD9D9DD9DBDBD99D9D9D99D9DB999D999D99BD9D99D99D9D9DBDBD9D9D9DF9DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9D9D9D9F9DBD9D9DB99D9D999D99D99DD9F9D9D999DB9D9F9D9DD9DBDDD9D9FDDF9DDDBDFD9DDF9DF9DBDB9BDBDB9F9D9D9D9F9DBD9FD999D9D9999F99D9DB9D99DBDB9F9D9DBDBDBD99F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DBD9F9F9F9D9D9DBDBD9DD9F99DDB9DB9DB9D9DBDBD9D99D9D99DBDBDBDDB9F9FD9F9DBDBD9D9F9F9F99FDD9DDD9D9DD9D9D9DBD9D9D9D99F9D9D9BD9D99D9D99D9F9D99DD9DBD9D9D9D9FD9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9F9DD9D9F9F9F9D9D9DB9D99DB99D9D99DF9F9D9D9F9FD9F99D9D9D9DF9DD9D99F9F9D9DBDBDDFDDDFD9F9DB9FDBDBDF9F9F9D9DBDBDBD99D999D9999D999BDDBD999D9BDBD9DB9DBDBD9BD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9DBDBD9D9DD9F9F9F9DF9DF9D9D99FD99D9D9F9D9D999D9D9F9BDBD99F9F9FD9DD9F9FD9DDBDDBDBDBD9DBDD9DD9D9DD9D9D9F9D9D9D9D99DBD99D99BD9FD99D9DDB9D99D9F9D9BD9D9FD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DBDBD9D9F9DB9F9D9D9D99D99D9F99D99D999F9D9F9DBDDB9F99DD9D9FD9D9D9DF9BDD9DBDF9DFFDFDDDFDF9D9F99F9F9BDBD9F9D9F9D9DB9D99D9F99DD9D999F99B99D9D9F9D9BDDDBDBD9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99D9D9F9D9F9DD9D9F9DBDDBD9D99DB9D99FD9DBD9D9D999D99D999F9D9F9F9DB9DDDBDBDF9DBD9F9F9F9D9DF9DFD9D9DDD99D9DBD9D9F9D99D9999D999B99DD9D9D9D9DBD999DD9B9D9D9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9DBD9F99D999F9D9D9D99D9B99D99DB9D99F9D9DBD9D9D9D999FD9DBD9D9F9DDBDBD9DD9FDFDFDFDF9FDF9DF9DBDBDB9FDBDD9D9DBD9D9D99F9D9BD9D9D9B9D9D9D9B9D9DDB99DD9F9F9DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DBD9D9DDF9DF9D9F9DBDF99DDD9B9D9D99D99DBD9D9F9F9F9DF999D9D9F9D9F99D9DBDBDF9DBDDBDBDFDBDDBDDBDDD9DD99D9BD9DBD9D9F99D9D99D999D99DDB9F9BDD99DB9D9DB9F9D9DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9F9F999D99DBD9D9D99DF99BD9D99D999D9F9D9F9D99D9DB9D9F9F9F9DBD9DFDBDDBDD9FFDFFFDFDF9DDBD9F9DB9FDB9DF9DDBD9D9BD99F9999D999F99D999D99D999F99D9DBDD9DBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDBD9D9FDF9FD9DBDBD9FD99DD9D999F99DB9D9F9D9D9D99D9D9D9D9D9DBD9DBD9DDBDDBDBD9F9DFDBDF9FDF9DF9DD99DD99DB9D9D9DD9D99D9DB9D999D99DBD9D9D9D99D9999D99F9D9DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9DBD999D99F9D9DBD99FDB9D9BD9D999D99D9DBD9F9F9F99F99DD9F9D9F9D9F9FDDBDFDFFD009FDFDF9FDF9DF9DFDBDF9DD9F9F9BD9F9D999D9BD9D9D99D99F99B9D9BD9F99F9D9F99FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DB9DBDDBD9D9D9D9D9D999D9BD99D9D999D9BD9DBD9D9D9DD9DB9BD9F9DD9F9DF9F9DF9FDFF909BDF9FDF9DFD9DBD9D99DB9D9D9DD99D99F9D99D99F99BD9F999D9DB9D9999F9DBD9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DD9D99D9FD9F9BD9F9DD99D99D9B9F99DB9D99D9DBD99F9BD9D9D9D9DBDF9FD9FDFD9FDBDF09909FFFDBDFDBDFD9F9FDF9DF9DBD9BD99D9999D99D999D999D9D9D99D99D9D9D9D9FD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9DB9DBDBD9999D9D9D9DB9DB9D999D99D99D9DF9F9D9F9D9D9D9D9F9DBD99DD9F9DBDFDFDFD90D999DDFDF9FD9DBDD9D99D99D9D99D9DB9D9F99D999D999D9999B9999D9B99F9BD999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99D9D9D99DFD9D9BD999D9D9BD9D9D999D9B99D9F9D9DBD9DBDBD9F9DDFDF9FDDFDBDBFDFF0B00D09B9FFD9FF9DBDBDF9FD9F99FD9D9D99D9D9B9DB9D9B9D9F9D99D99D9D99DDBDF9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DDBD9D9F9999F9D99F9DB99D99999F99D9D9D9D99DBD9D9F9D9D9D9DB9DBDF9FF9FDFDFFDFC9D9099009DFFD9DF9DD99D99D9DF99F9D99D9999D999D99D9999999DB999999D99D99DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BDDB9D9D9D99DBD99D9D9D9D9D9BD9DB999DB9DDBD9D9BD9DBD9F9FDDBD9DFD9FDF9FDFFF9B9099C900BD9FDF9DF9FDF9FD9D99D9D9BD9B9D99999999999D9999999DBD9D9BD99F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D999DB99F99D999D9D99DB99B99D9999D9D99D999D9F9D9DBD9F9D9DBDDFBDBFDBDFDFFFD00E909909009F9FDF9D9D99D99DB9D99D9D99D99D999D9999D9999D99D99999BD99FD9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9F9D9D9D9BD9D999BD9DD9D9999D9D9DB9D9BDDB9D9D9D9D9D9FDBDDBDDFDDFDFFDFDFFB990DA9D0900099B9FF9DFD9DBD9DBD9B999999999D999D99999999999999D9D9D99D99FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BD999D9999D999DBD9999999D9D9BD9B9D99D99D9D9F9F9F9F9D9FDBD9F9FBFDF9FFDFDF00CB990990DB00009D9F999F9D9D9D99D999D99D9999999999999999999D99999BD9B9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9F99DBD9DBD99999B9999999BD99D99D9BD99DF9D9D9D9D9FD9FDDFDFDDDBDFDFFFFF9DB000990F00009E90BD9FD9D99F999D99D9999999999999999999999D9999BD9D99DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD99BD99F9D999999999D9DBD999D99D999DB9D99F999D9F9F9F9D9FD9F9F9FFFFFDFFDFDFDA909090999000090909999DBD999D9999999999999999999999999999999D9999F999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D99D9999999D999D9999999B99D99D9F99D99D99DDBD9D9DDF9F9DFDFDFDBDFDFDFFFFF09000909090099009000999999D999999999999999999990990999999999999D9D9D99FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999D999DB999999D99999D999F9999D999F9D9B9DBDBDB9DF9F9FDBDFDFFDFFFDFFFF909A9090F09D000000900099999999999099999909999999909909999999D99999999DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9F9999D99999D99999D99999999D999F9D999F9D9D9D9DDBDDDFDBDF9FFDFFDFFFFF99000000C990B0900900000009999999999909999999099090909999999999999BD9F9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999D99999D999999999D99D9D999D999999D9D9DBDBDDBDDBF9FDFDFFDFFDFFFFD9D9A0009DB0090000000000000000000099999909999999090909090909999999D99999DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9999D99F99D999999999999999999999999D9DBD9BD9D9F9D9FDDF9F9FDFFDFFFF9B9BF9C900E909099009A900000000000000000099909090990000909999999999999999D9BFFFFFFFFFFFFBFFFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9B99999999999999999999999999999999999D9DBDD9FFD9F9DFDFDFDFFFFF99DC9D0900B090000900000000000000000000000000909090000900909099909999999D999DFFFFFFFFBFFBDF9FFDFF9FBF9FFBFFFFFFFFFFFFFFFFFFFFFFFD9999D99999999999999909999999999099999D99D9D9BD9DBFDFF9FFDFFFF999C9A9FF9909090A0990090900000000000000000000000000000000090909909999999999999FFFFFFFBFFFBFFBBFBFFBFBF9FB9BDBDBF9FFBFFFFFFFFFFFFFFF99999999999D9999909999990990999999D99BDF9F9FDFDBDDDBDFFDFFF909F09FDFF990B00B09000990A000000000000000000000000000000009009990999909099999999FFFFFFDF9FBF9BDFFFBBDBDBFBDBF9BBDBFBDFDBBDBFFFFFFFFFFD99D999999999909999999999090909999999D99D9D9D9BDDBFDFDFFB909909DF9BDFF9D09000B0900B90900000000000000000000000000000000900909090999909999999DFFFFBBFFBDFFFBDBFDFBFBDBFBDBFDBDBDBBBFDBFF9BFBFFFFFFF9999999D99909999990990909090990999999D9F9F9FDDBDDFFFF090900090B9C9B9D909000909E9BC09000000000000000000000000000000000009099909909990990999FFFFB9DB9FFBF9FBFDBBDBDBDBDBF9BFBFBDFDBFF9FFF9FBDBFFFF999999999999999909990999999999999999DBD9D9D99FDBF999099000900B0DB0D0B09090D000900990000000000000000000000000000000000000090099099099909909FFF99FBFFFBF9FBF9FBDBFBFBFBDBBDF9F9FBBBF9FBF9BF9F9FFFF999999999999999099900990999999999D999D9F9DBDFDBD9900900090009099090BD99C09BDA90900B0000000000000000000000000000000000000000900909909999990BFFA9B9BDBDBFBDBFB9F9F9FDBDBDFBFBFFBDFDBFBDBFDBFBF9BFF990999999099999990999999999909999B9D9F9DBD9999990000090909090900909D909B000990000090900000000000000000000000000000000000000090090990990999DF999BDBBFBDBFBDBFFBFBF9BFBFB9F9F9FBFBF9F9F9BBDBDBF9DBF9990999999999099909999909099099D99999999900900009000090000900B90F0AD0909990CF909090000000000000000000000000000000000000000000900909999909FB09B0B9F9FBF9FBF9BDBDBFF9FFFFBFFBFDBDBFBFBFDBBF9F9BB9099999999990999990909099999999999999990900000000000000090F900900099D990D9000B9A0000900000000000000000000000000000000000000000000909909999F0090999FDBFBDBDBDBDFBFBF9FF9FBDF9FDBFBFDBDBDB9F9BF9F990909999990999090999999990999999999900000000000000000009099009099B90909900009090BC900000000000000000000000000000000000000000000000000909099F909B9B9BBDBBFBFBFBBDBDBFBFF9FFBFFBFBDBFFFBFBF9FB9B9A990990990999999990090999999990990900000000090909009000009AD090B000F0F909DB09090C9009090000000000000000000000000000000000000000000000099990DB090090BDBBDBDBDBDFBFBFFFDBFBF9F9FF9FF9FB9F9FB9BDBD99A9909909990909099990990999099990900000000000000000000009099A90099099CB90B00000B90B000000000000000000000000000000000000000000000000000000909000909B9BBDBFBFBFBBDFDBF9BF9F9FBFBDFBFFBDFBF9FFDB9BB99909099909999999090990999090000000000000000009000000000000090990AD0F9D09090909909009009000000000000000000000000000000000000000000000000900900909099BDBDBDFBDBDFBBF9FF9FBFBDF9FBFDBDFBF9FB9B9F99DB0909090990909909009099909000000000000000000000090900000909009A099B9FBD09A000009090090000000000000000000000000000000000000000000000000000000000090BDBBFBF9FBFFBFDBF9BBB9BDBBFBDBFFFBDBF9DBFB99A909000909099990909090909000000000000000000000000000000000090A909900CF0DBD9900900B009A090090000000000000000000000000000000000000000000000090000000090B9F9FBF9F9FB9BDBF9DBF9BDB9FBDB9FBF9FBBD9FB99B9B99090990909009000090000000000000000000000000000090090000900DADB999FB909E90A09090090000000000000000000000000000000000000000000000000000000000009099F9FBDBFBFBDBFB9BBB99BDBDBBDBFFFDFBF9FBF9DB090900009009090900090000000000000000000000000000090900000090090B90D00B9D09999909A90090009090000000000000000000000000000000000000000000000000000000009BBFBDBFBDBDBDB9F9D99FB9B9BDBBDB9BBBDB9F9BB999B00909009909000090000000000000000000000000000000000000090A90990F909DCB9090C90090B0009A0000000000000000000000000000000000000000000000000000000000090DBDBFBDBBDBB9F99BB9B999BDB9F9BFFFDFBDBBF9DB090900009000000090000000000000000000000000000000000000090009090A90F90B90909B9090B009000909009000000000000000000000000000000000000000000000000000000099BF9BFBDBF9F9BBD99B9BDB9B9B9F99B9BF9F99FBBDB090900000900090000000000000000000000000000000000000000009009A9909090DFBA9009A90909009000000000000000000000000000000000000000000000000000000000000900BF9FBDBF99B9BD9B9BDBDB9F9F9F9BF9FB9FBFB9F9B9909000000000000000000000000000000000000000000000000090000A909C0B0F9CB9D900B009C00A9000090B0000000000000000000000000000000000000000000000000000000009B9FBDBB9BBBDB9B9BDBDBDF9BF9F9F99B9F99B9FF9B00900000000000000000000000000000000000000000000000090009090909A9099090DF09009A9B90909090000900000000000000000000000000000000000000000000000000000000BDB9FBF9F9D9B9B9F9BDBDBBFDBF9F9FBDB9FF9F9BF9B9000000000000000000000000000000000000000000000000000000000009099BC9F9AD90090900990900A90090000000000000000000000000000000000000000000000000000000000BFBDB9B9BB99D9F9F9BFFDFBFDBFBF9F9DB9BF9F9BF9090000000000000000000000000000000000000000000000000000009090A9AD09AD99FB0909A9B00A00990B000900000000000000000000000000000000000000000000000000000009BDBBDBDB9DB9BB9FFFFDBFFFFFFDFFFBFBF9F9BB9F9B90000000000000000000000000000000000000000000000090000090000BD090BD9FE9F9C90B9A90999F000909000000000000000000000000000000000000000000000000000000009BDBBDB9B99B9FBDFFBDFBFFBDBFFBFF9FDF9F9BD9FBDB00000000000000000000000000000000000000000900000000000000090900B9DAF990FB90B09090F0B0D0B00090000000000000000000000000000000000000000000000000000000ADBDBB9B9DB9F9FF9FFBFFFFFFFFFFFFFFBFFFBDBB9B9F9000000000000000000000000000000000000000000000900000000090009900F9DFD9D0B90D00A90909B00090000000000000000000000000000000000000000000000000000000009B9BDBDB9B9FBF9FFFFFFFFFFFFFFFFFFFFFBDFBD9BDB9B0000000000000000000000000000000000000000009000000090090A9000BD9DF9FA99909DA9B9E909A909000900000000000000000000000000000000000000000000000000000009BFB9B999BDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDB9F900000000000000000000000000000000000000009000009090000AC900B000B0FDFD9C099A9B00990A909090000000000000000000000000000000000000000000009000000000009F9BDB09BBDBFBFFBFFFFFFFFFFFFFFFFFFFFFFBDBDBDB9000000000000000000000000000000000000009000090900C0000909909090999FFF909BB0900090090090B009000000000000000000000000000000000000000000B0F00000000000BF9BD9BD9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBDB9000000000000000000000000000000000000000090000F9F0090090A09CBDBC9DFDBD99BB99A90B0000A9C90090000000000000000000000000000000000000000009AF000000000B9BDB9B9BFDBDFBFDBFFFFFBFFFFFFFFFFFFFFFFFFFF9F9B0000000000000000000000000000000000000000009000F0900000990B0909909FF9E9B900A90B900090099000000000000000000000000000000000000000000000090F000000009F9B9B9FBDBFFBFFFFFFFFFFFFBFFBFBFFFFFBFFFFFDFBFD00000000900000000000000000000000000000000900909000B09000D09ADF0F9F9E9900BD9DB00900009A009000000000000000000000000000000000000000000AD0FB90000000F9BBDBDBDBFFFFFFBFFBFFBFF9FF9FFFFFFBFFDFBFFBF9FB9000000000000000000000000000000000000909009B000009090009A9ADB9F9C9E9909F0B0B0900B009009000000000000000000000000000000000000000000909A090CF000009BBD9B9FBFFFBFFBDFBDFBFDBFFBFFBF9FBDFFFBFFFFFFF9FF00000000000000000000000000000000000000A900009090000090BD9DBDE9F999BC9D9F9F9FAB009CA90A90000000000000000000000000000000000000000000090FB9BB000009BB9DB9FBFFFBFFBFFBFDBFF9FF9FFFFFFFBFFFFBFFFFFFBDF0000009B0000000000000000000000000000000090000090900090F09DBDFFCBC9BDAF9B09090B0A990900090000000000000000000000000000000000000009AF9A90FF000009F99FBFFFFDBFDFBFBDFFBFDBFFBFF9F9FBFFDBFFDFBF9F9FFB90000000000000000000000000000000900009090090900000090F9B0BDBD9F99DF999D0909BA9E990000900000000000000000000000000000000000000009E09009EF900009BB9FBDBDBFBFFFBDFDBF9FFBFDBDB9FBFFFDBFFDFBFFFFFFFBDF90000D000000000000000000000000000090000000000009090F9909D0FBFF9CB9CBDB99A90DA9A09BB0A9000000000000000000000000000000000000000B9B090FFF00000099F9BFBFFFFFFBFFBFFFFB9DB99B9F9DBDBFFFFBFFBDBFBF9FFBF0000B000000000000000000000000000009000909090900B090B0FCBDFDDBF9E99ABC9D00B999900909000000000000000000000000000000000000000000000A9FF9000000F9BFDBDBF9FBFDBDFBF9BDB99B9DB9B99BDBDBFFFFFFFFFFF9BDBF00090000000000000000000000000000009000000A009009A9099FF9FBD0F9909B99B09B090A099A0009000000000000000000000000000000000000000000000FB0000009B9F9BFBFFFFF9FFBFDBF9B9FDDFBDFDFFDBDBFDBDBDBDBDBFFFFFDA000000000000000000000000000000000000900909009909090F9FFD9E9FF990BDA9DB0B9090B00090000000000000000000000000000000000000000000009B90000000BDFBFF9FBDBF9FFBF9BD99FDFBFBDBDBBDBFFDFBFFFBFBFFFF9F9FB90000000000000000000000000000090090A9009C090B9A90BCB9DBFFFDFD00ADA9BB0990B0090A900090000000000000000000000000000000000000000000000000000DBB9F9BFDFBFBFFBDBDB9FFFBDBDFFBFFDBF99B9DBDBDBDBF9FFFFFFF909000000000000000000000000000000900090B9F99C9BC999CB990FBFFBD9FB0DAB009B9B09009B000000900000000000000000000000000000000000000900000000BDFBFF9FBDFFDBF9F9BDB99DBFFBFFDBFFFFF9F99B9FB9BDBFBFBFBFDF000000000000000000000000000000000900A90B00B909B0A9BDADBDF9FFFDF9BB90DBBFB9009B9A90000000000000000000000000000000000000000000000000000BDB9F9BFBFBF9BF9F9F999FB9FFBFFFBFFF9FFFFBD099909BFFFDFDFFBF00000000000000000000000000000090000BD0909990BD0B9C99DFDBDFF9FBD9A9B0B9FB9B0B00090000000000000000000000000000000000000000000000000000BDBFFFFFFDFFDBF9F9B999BF9FFBDFFB9FBFFFFBFF900099BFFDBFBFBDFF9000000000000000000000009000000009090B09A9CBD0B909B0F9FFDF9F090BBB0B0B9B0B9090B09A000000900000000000000000000000000000000000000000009BDBF9FBFBFBFB99B9900BDBF9F9B9B9999B99F9BB900009F9FBFFFFFFBFB0000000000000000000000000090000009E90BD0B90B990B0D99F9FFBFFD990BEB09099A9B9A9CB0900090000000000000000000000000000000000000009000000FBF9FFBDBDFDBDB9900090BFB9B9999D9B999999999999F9BBFDBFBDBFDFFD0000000000000000000000000000909090BD0A90F90DA90B090F909DBDB09BDB90A9A9B009DA99A9A900000000000000000000000000000000000000000000000BF9FFFBFFFBFBFB990000099999999BD9B9D9F9B9D9DBFB9BDBDBBDFFFFBFFBB000000000000000000000009000000009D0B9B09A9B09A99FD9EBFBCB0900BB0A909B0DB9A99A9B0000009000000000000000000000000000000000000F90000F9FFB9F9FBDBF99F9B9D999999999F9FBFDBF9F9FBDFBFDBDBDBFDBF9F9FFFD000000000000000000000090000090A9F9AF90C9A9090B9B0F9F9D0099D09B9A9BFA9A9B0F9F0900B000000000000000000000000000000000000000000000000BFBFFFFBDBBDBFB9BDBBDB9FDBFFFFBDB9B9FBFFDFBFDFBF9B9B9B9FBBFFFBFD00000000000000000000000009000900FD0DB9B09B0B0BC9FFCBAB9A90B00B00A9B09A9BB909F9A9B09000900000000000000000000000000000000000B00009F9F9FBDBBD9B99FBDBDBFDFBFDBF9B9B09999B9FBFFBFBDBF9BDB9F9FDBBDFFB0000000000000000000000000A9000909BD909DBCBD9F9B00F9D90090B9F09ABDB090990009AB09000009000000000000000000000000000000000000090000BFBFFBDBDBBF9FB9B9B9F9FBFFBF9F0999F9BD9F9F9FFFDBDB99B9F9F9BDFBFF9A0000000000000000000000090000009F09090F0BDAF9F099FF9E9F9EDE90ABDAC900000090B909A909A0000000000000000000000000000000000000000009F9FDBDBFB9F99B9DBDBFBFBFDBDB9B9BDB99F9B9BFFF9FBDB99F9F9F9BFF9FFFBD00000000000000000009009000909B90999CBD9F9B9B00B09DBDF9A9B99B09A9B9A09A000900B00A0009090000000000000000000000000000000000F0000ABFBFBB9F9F9FBDB9B9F99FDBFBF9B999B9FF9F9F999BF9FB9B9BDBFBFDF9FBFFF9000000000000000000009000900000C9E9A90F9F0909090DABC9FDFF9A9000000F9A090000000B090900A000000000000000000000000000000000009B9B9D9FBDFDB9B9F9FBDB99BFFBF9F9B99999F9FFFFF9F9F9FF9F99F9FDBDBFBF9F9FF9000000000000000000000000090009090909900FD00A9A9FDDBDBFDFDFF0000099A9A00090000000A009900000000000000000000000000000000009F9F9FBFBDBB9BDBF9F9FBF9B99BDBFBF9F9FBFFFFFFFFFFFFFDBB99B9FFBFFFDFFFFFFFF00000000000000000000009000009A90909A09F90B09C9F9FBFF9CBFFFD000999AB00000000009009090009000000000000000000000000000000F0FFBFFBDF9FBDBF9F9FFBDF9F99BDBF9F9F9FFDFFFFFFFFFFFFFFBDB9DFDBFDFFBF9FF9FBDA000000000000000000090000000000BDA9090909090B9BCBD9999F9FFF000000090000900000000000090000000000000000000000000000000099FBDFBDBBFBDBF9BFBF9FFBF9F9999FB9FFFFBFFFFFFFFFFFFFFF999BFBFFFFBDFFFFFFFFF900000000000000000000000900909909C90000B009BD0D9FB09A9DFFDF00009000000900000A0009A09A90090000000000000000000000000000B9FFBFFBDBDBF9FFDBDFFBDFFFFFB9B9DB9FFFFFFFFFFFFFFFFFFFB9F9FFFFFFFFFFFFFFFFFF0000000000000000000009000000E99F9E9090DB0D0F999D0BC90BDBBF009000F009A00009A900000900000000000000000000000000000000009FF9FB9DBFBF9FBDBFFBDFFBDFF9FF99B9FFFBDFFFFFFFFFFFFFF999FFFFFFFFFFFFFFFFFBFB000000000000000000000000090090FCB909FA90DB990D09F09BD9ADDF00009A9E00090000000090900000000000000000000000000000000000FFBFB9FBF9FDBFFBFFFFFBFFFBFFF9F999FBDFFFFFFFFFFFFFFFDBFFFFFFFFFFFFFFFFFFFFDF90000000000000000009000900090BDBDE9EBD9DBC0099B9F90F9090BF00000909A090000A000000A0900900000000000000000000000000000BDBDBDB9BDBFBF9FFDBFDFF9FFFFFFFFBF99FBFFBFFFFFFFFFFFBF9FFFFFFFFFFFFFFFFFFFFFFB00000000000000000000900000C9090B9F9D909DF9B009D0BD0F9009909A900009909000900000090090000000000000000000000000000000FBFFFBDBDBDBDBFBFFFFBFFFFFFFFFFFFFBF9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFF0000000000000000000000000B00B09090B0B90BDFDFF0990BDF0B9C900000B09000009A000000909000000900000000000000000000000009BDFB9FB9BBFBFFFDFFFFFFFFFFFFFFFFFFFFF9FBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB00000000000000000090900909900B0D909009CFFDF90B09090909B90000B00A09009A9A0000900A09090000000000000000000000000000BDFBDB9B9FDBDBDBFFBFFFFFFFFFFFFFFFFFDBFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF90000000000000000000009A9009909B09A9F9BB9BB9090909AB0F090000090900B000090090A909000A0000000000000000000000000000FBFFB9FDB9BFFFFFFFFFFBFFBFFFFFFFFFFBFFBDBFDFFFFFFFFFFFFFFFFFFBDFFFFFFFFFFFFFFFDBF00000000000000009000909A0B00B09DB90909C900A9CB9B090F9B0B000A000900B0B009A09C90090909090000000000000000000000009FF9F9BB99B9BFFBFBFDFFDFFFFFFFFFFFDFFF9FFFBFFFFFFFFFFFFFFFFBFFFFBFFFFFFFFFFFFFFBDB00000000000009000090A909909E9F0DCBDADBBF99CB90C09A9CBD900B0900009A0900B00909A90A000000000000000000000000000000FB9B9BDBB90FFDBFFFFBFBFFFFFFBFDBFFBFFBFFBDFFBFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFF9BD0000000000000000000090F0A9F9909B9FD9F0D90FFDADB9A9FB90B0B0B00B09A09A0B0A9CA90090090B09000000000000000000000009FBDB9F9F90F9FBFDF9FFFFFBFFFFDFBFF9FFBDF9FFF9FFFFFFFFFFFFBF9FBDFFBFBFFFFFFFFFFFF99B0000000000000000900B0909DB9A90B0DFBFFDBDDF9A9B90DFF9CF00009B009090A9A090B0909A0000000000000000000000000000000FF9B90BB099BFFFFBFFBF9FFFDBFBBFFDBFB9FBFF9FBFFFFFFFFFBFDBDBF9FB99F9FBFFFFFFFFFFFB0F900000000000000000900B0A9009C909B0D9DBDFBFDF90DB90FDB9BB0A0B90000B009A00AB090900B09090000000000000000000000009B9B9909B009FBFFFBFFFFBDFFFFDFB9BDBDBDB9BFDFBDFFFFFFFFFBFB9B999B99BDF9FFBFFFFFFFD9B0000000000000000900990990BDB9A9C9B90DFFFDBDB090D99DB0C90000B00909CBA90BFB90B009A00A00000000000000000000000000F9090909009B9FDBDFF9FBFFBF9BB99B9A9B9B9F9BBFDBFFFFFFFDBD9BD9B9BDB9F9BFBFDFFFFFFFB9F9000000000000090009A090AD0B0D90B000BFF9DBDF9D09FD9A9D9A0A9B0BF0BABADBA9A90A9A9A90909000000000000000000000000BB0900090909FFFBFFBFFBFDBF9BD99F999999909BDF9BFFFFFFFBBFBB99B9BD9BDBBFFDFFFFFFFFF90B000000000000000009009DAD9B0909090B9D99DA9DB09BDF9099A900000B09B0F9FBCBB9A90B9A9A0A9A900000000000000000000000990909000000B9FFBFF9FDFBDBF9B9B9A9F9B099B9B9FFDFFFFFFDF999B90990B9A9D9BBFBFFFBFFF9F9B0000000000000090090B09B00B09A9090099CBDFF090D9FF9009A900A9AB0B0BB0FB9A9A00B00B90900A000000000000000000000000990D0909009DB9FDFBFBFBFB9B09B999B9999B9090B9BBBFFFFFBFF0909FB090090B99999B9FFFFF0B900000000000009000BC909E9F90F090B0FA9DBDBDBD090D9DAD0DDFA09A90B0B90BFFA9A9B000B00B00B9000000000000000000000009A9BB9A90000BFFBFB9F9B9999099090909ADB909B99F9FDFFFFFDB9B90BD09000009000DB9F9FFFF9909000000000000000009A90909EB90B09C9909D9EFDB0099FF99BBF909BA9B0B00AFFF900F0A0000B090000000000000000000000000909F9F9090009F9BDF9F9B990000000000009F0009099BDBBFBFFFB909090B00009000009A9DBFFFFF000000000000000000999090F009B9CBC9FBF09F9BD900090FF9CA090B0A0900A9AB0BBFEBBFF0B00B0BA9A9000000000000000000000090B9B09000009BFFBFBFBDBDB000000000000B990090B9BDFFFFBDBDB90900000000000DB9BFFFFFFB00000000000000009000A9A90B9009B9FBC9DBD0D0BDB90B9ADB999E99B000B00A9A90DFFCBFFFCFA9ADBCDA0000000000000000000000909B990900000DBDBDBF9BFB9F900000000000009009CB9B9FBFFFFBD09090900000A9B90999FBFFFF90000000000009000B99C909D0B90D0909FBC99999D90090DFFDBC99A9000A00A9A9ABBB9BFFFFBB0FFFFBB090000000000000000000000990000000000BBF9BFDFF9F9B9090900000009000999B9FBFDF9FBDBB9009909A9B9900B9FBDFFFFD000000000000000090009A9E99C0D0B09A90BD9DAD09D9FFFFDFDBDA900B090BB9A9B9009A9BBBBDFFFF0FD000000000000000000000009000900000009BD9ABDBB9B9B909B00090090000A9B0B9F9F9FBFBDB990B000099000099DBF9FBFFFB0000000000009009009B09090F9DB900090BD90B909FFFFDBFBFBC9D0900FBA9E0F000BA000909BABB9FBFA000C000000000000000000090900000000009BBD9B9090909B909B90900900990999B9FBFBDBDBBDB999990009099A9B90FBDFFF90000000000000000A900909090F909909AD9099D90FFDF9A9009DBDB09A9A9E9BBA9A00B00A0009900A90B909A9A9000000000000000000BA9000000000099B9900000000090909090099099B0DB999F9BFBDB9FBC9A99000900909B990B9FFF900000000000000900B09A9F090F9009C9FFFF09CBDFBDF9FFF0909D900FBFBFADBAC9AD0B00B0A00000000000000000000000000000000990000000009B9B000090090009000000009009A909B9FBF9F9BDB9F99B990090000909090BFDFFB900000000000000B009C90D909BD90F9FDFDF9099DF9FDF9FDBD0F909090BB09A9B0B9AB0B0000000A0090900000900000000000000000000000000000009000099B000090000000000009090DBDB9F9BDBDBDBBDA90909000900009ADFDBFF9F0000000000000900909B0B09F0FFFDFFBBBFD90FF9FBF9BDBC9F9CB099BCBB000A90A9000000000009A00A00090A09000000000000000000000000000000900B0B0F90000000000000000909A9B9F9F9B9B9BD9BD99A90A90A009D099BFF9FB900000000090000900A90D0B009099A999C0DBE9D9FC99C90990F9F9F09BB000000000B00B0000009009A0900009000000000000000000000000000000000000999909B0000000009009A90B99BDB9B9F9F9B9B9BBFBDBD9F99FDA9FBE9BDBDB0900000000000000B009A909B09909DBCB990D90FD9B00BDB0BD9E9F9F90BB000000000000000000A0000F0CB0000B00000000000000000000000000000000090B0B9B0900909909D09BDB909F99BDBDB9B909DAD990BDBF9FF9BDB9099FB0B900000000000000B0090090B099A0F909909A99099BD09D909090BDBD090000000000000000000000000FFFFF0A009000000000000000000000000000000000009099099000090009A9B09909B9B0F9B9B9DA99B99BFBF9F9FB9BDB90B9F099900000000000000900D09B09C9AC9990B9C90D0000BD0BC9E9AD09990090900000000B00000000000009AFFFFFFDA000000000000000000000000000000000000009A9B0B9000009A999090B90909B9BDBDA99900909999B9F90909909909B900900000000000000090A000B9E9BE9E900B0B09B0909D99F9FDBD000B9AD0000000000A000000000000ADFFFFFFFDF0000000000000000000000000000000000000090990900000090B99B9000090090B9B9BB9000B00B9F9BFB9000B09090B9B0000000000000009A99090099099F9E99090909909F90D9F9ADBD900DBD9000000BA9000000000000A9FFFFFFFFFB000000000000000000000000000000000000099090000009000909A909900009099A9D9009909909D0BD99000B99A90B090000000000000090000090DB0F0BD9F9E0A9DA9A0DBDA9909C9FF9A9DBC9B00000B0000000000000B09ABBBFFDEBF0000000000000000000000000000000000000000000000090090009909B00009009F99A90900CB090B9F9B09009909090900900000000000000909B00B0909D0A9FDBD0BC909B009D09DBFDBD09A9990000000B0000000000000A000900BFBD900090000000000000000000000000000000000000000000090099000909F90000909B990090B99B009B99090B090B900009000000000000000B00909099A9909900BDA9F9F0B09B9B90BDFF90B09A90900000A0B00000000000B000000000BA00000F000000000000000000000000000000000000000000909009900B909900090B0DA909009A9C900FB900909A9009090000000000000000009A0B0B090DA90990FFDB0F9BDBC900D90FF9F9DA9DAD9000000000000000000B00000AC09A09009FF000D00000000000000000000000000000000000000B090B9000990B9B0090099B9900099DBB9099900B09090900000090000000000000000909090B0990DA0BFFB0FF09ADBDBDF0990FDFFFDA99000000000A00090000000000BCB0A09009EB09A9A0000000000000000000000000000000000000909099000B0909900000909090009A9A99090B09099B090000009000000000000000090900B0F099A9099FFFFDF99DF9FDFDBD90F9E9FFFF90B0000A0009A00A00000000000B0909A000BDB0000000000000000000000000000000000000000009000000909A9000000009A9000099999090F9009B09000000000000000000000000000A90999CBEDA99E9FF9A9F0BDF9F0BD0B09D90F9FFD9000009A0000B00B00000000009A000090000F09E90000000000000000000000000000000000090009090900909909000009090B00000000BC90B9009B9900000000000000000000000009000E0B99FBDADFEBD099090B90D9DB990B0B0BCBFBCB000000000000B000000000B00000000009B09E900B000000000000000000000000000000000009000000090B000B00009000990009099B9B999009B00000090000000000000000090000090990FCBDAF9B9FA9FA0B09099FF9F99C9909B9C9BD00000B00000B00000000A0000000000000ADA0B000000000000000000000000000000000000000009090909909900009009090900009A9090000009909009000000000000000000009009A000BDBDBF90FFFDFF999009FDF0B90A99A0F0DB9CB0000B0000A00000000A00B0000000000009A9BCBD00000000000000000000000000000000000009000000900000900009000000000009090B09000000000009000000000000000000000009B90FFB090B09FBFFF0A9B099DBDA990BD99F9C9B000000A9000000000000B0000000000A0009AC9BCBE90000000000000000000000000000000000000090000B900000000090000090090000090090000090900000000000000000000000900000B9FDE909FF9DFFFFD00FC9FDBDA99EBE9FFBCF900B0090A0900000000000000000000900009B0FBDB0000000000000000000000000000000000000000090900009000000000000000009090009000000000000090000000000000000090090900FFB90BEFFFFFFDFA9FBDBDBC9F9A9D9FFBCBDA0000A0A9A00000000000000000000B0090000090B000000000000000000000000000000000000000090000909000090A90000909B0000009000000000000090000090000000000900900A00009BFF90B99FFFFFBFDFFDF9D99F909DB0B99F9FD0000000090000000000000000A0A00000000000000000000000000000000000000000000000000000000900009090090D09900A9099009000900000000000000000A900000000000A00090909A09FCB0FA9FF9F9BFDFB9D0D90D9E9FD9FA9CBB00A9A90A0000000000000000090900B09000A00000000000000000000000000000000000000000000000090000B090090B09F9009AC990B090009000000000000000000000000900909000090900BFDFDFFFFFF099F0DB990FDFDBF9F009B090000000A9A00000000000000000A0A900A0B009000000000000000000000000000000000000000000000090000000009A999A90990990B09000900000000000000009000090000000000A900A00009FFFFFFFFDBF0FBDBC9DBDB9AD9FA9B0DBCB0000B0009000000A000000000A9090A90900900B0A900000000000000000000000000000000000000000000009909009900999A009A909009000000000000000000000000000000090090099C9000FFFBFFFFBF09ADF09DB999ADB0B9D09A9A900000B000000000000A9A0000000000000B0A00090C9000000000000000000000000000000000000000000000009090009B0B0D90090090900B00000000000000900000000000000000009A0B00000BFDBFFBCD99DBDFD909E90BCBDBA90909000A0000000000000000B0B000000A090A0090900A9A0A9000000000000000000000000000000000000000000000000990099090B009900A0909090000000000000000000000090090009009C0F9009F0FCB9FB90A99FFBDB09BD999CDB0900F00000B000A00000A09A9A9000000A00009000000B00909000000000000000000000000000000000000000000000000900B0000B09090A9090000000000000000000000000000000000900090B90B000A9BB9ED09BD9E9FD9DBD09E9CB90F09B09000B00A090000009A9A00000000090A0000000000900000000000000000000000000000000000000000000000000000900909909000909000090000000000000000000000000909000009A900AD000D9000B90F0BF9DFF90909F9FF90B90FCBF0000B09A0000000A00000000000000900090A0900000000000000000000000000000000000000000000000000000090090000090B0900000900000000000000000000000000000A000B00009090B00BEFF99099D00FBDFF9A909FDBB09A99BFD000000A9A0000000B0000A000000A00A90A090000000000000000000000000000000000000000000000000000000000009009A900009000000000000000000000000000000000009000090BCB009009FFFE9F0AFBD0FBD9C90F09FD0BC9EB09F00A000900000000000A09090000090090000000090B00000000000000000000000000000000000000000000000000000000900009000090000000000000000000000000000900900090900C9009A09FFFFFF0BDFFFB9DB09DF9909ABDBF90FF9000000A0000000B0BA900A000000000000909090A0000000000000000000000000000900000000000000000000000000000000900000000000000000000000000009000000000009A000A090B0090CFFFFFFF9BFFB09A09DBBD0F9FDFFF0FFDB000000000A9A0000000B9000000000B0B000A9A900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090909A90DA09BFFFFFFB0A9FFFF990B00BDF0BFBDBF9BFD0000000B00000B0B09A0A00A0000A00009A90000090000000000000000000900090000000000000000000000000000000000000000000000000000000000000000000900000000900090000FB0D0CFFFFFFF99C909FBA909BDDFB90DDF09F09F0000A9A00000A000A009000009A90000A0000B0F00009000000000000000B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000A90BD00FBFFFFFFFF9AFB09BF9B0FBCBFB90FBE9BFADF9000009A9A00B900B000000000A000009090A90C9000000000000000000900009000000000000000000000000000000000000000000000000000000000000000000000000000000009090C90BDBDFFFFFFFFFDF90BE9F9FB9B9B09A9F9FDEDBD9000A9A0009A0AB00000A00000090B000A0900BFAF0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0B09EFF9FFFFFFFFFFB099FFFFFC9009ADA990B9B0B900000000000900000A090A9000A000A09A0B0FDFBC0000000000000000000900A00000000000000000000000000000000000009000000000000000000000000000000000000000009A9090E9B09FFFFFFFFFFFF909FDFF99F9B0999009009D000009A9A9A00000000900000000900009A900A9EBD9A90000000000000000900009000000000000000000000000000000000000000000000000000000000000000000000000000900000F0B900BE9ADFFFFFFFFFFF09B9A9E9009E000D0DB0A99090A000A000A00000A0A000A000A00A0F00B9F9F0A000000000000000090000900000900000000090000000000000000000900000000000000000000000000000000000000000009C9B009000099FFFFFFFFFFFFFF09A9D9BD9F9B0B0B90D99A0A00BB09000090A09000A9090B009090B0B000A09090000000000000000A0000000000000000000000000000000000000000000A9000000000000000000000000000000000000000B0090009000A9BFFFFFFFFFFFFF0D9AD0F90F090D0909F0900000BA00000A090A0090A0A00B0A000000B099A09A9000000000000000090000000000000090000000000000000000000000000C0900000000000000000000000000000000000009F00900000090CFFFFFFFFFFFFBB0BDB90F90BDABB09F0F00000B09A000090A090B0A900B000000000900A099A000000000000000090000000000000000000000000000000000000000000090B000000000000000000000000000000000A00090090A009000009BFFFFFFFFFF90990BD9F90B909D0BC9F990009A9A90000A009AA09000B00B090000A0009BEA090000000000000000000B0000000000000000000000000000000000000000A0000000000000000000000000000000000090000B90090900090B00B9B9F9BF990A00AD0D00B0D0B0B0BB09A000A000000A900A090B009A09A000A0B009A9A099000000900900000000000000000000000000B00000000000000000000000900000000000000000000000000000000000000900900F000009000090009A9A90A00000999A900B0B0B099CB90900900000000009A00000A9A09BA0900B90009A0A000000000000000000000009000A0000000000900B0000000000000000000009000000000000000000000000000000000000000909900000B09000000009A9000000A09009B0B909A0B90900A00A00A000A0BA90000A9A90A0900A90A0B0A090900909000000000009000900A0900000000000A0000000000000000000000000000000000000000000000000000000000009009A90A00000090B0000000000000000090B9A0BDA90F9EB00B0000000000009A9A00900000B0B0A009A909AD0000000000900000000000000009000C00900000090000000000000000000000000000000000000000000000000000000009A90A900009000099E900000000A0000000900BD00B9BBDBDB9B0B9A0A900000000A9B00A0009A9ADA90B0A9E9A9A09000B0000A900000000000000000009000000000000900000000000000000000000000000000000000000000000000000000009009F09C009A09A000000009A0A0000A0090900A9FBF00B99CB0900A0A000A09AF0B9A90A000B0A9E9B0B0B09A0B00000B0000000000000000000000A00009000000000000000000000000000000000000000000000000000000000000009009090009A909090990000000000900A000909B0909A9B99ACB0900A0B0009A09AB0BB0B00A9A9AB09EB0A9AF0F09000909000009000000000090000090000000000000000000000000000000000000000000000000000000000000000090090A9ACADA9090B0009A0000000000A0A900F90AD090009A90B99090B009A9A9A0BBA9BB0B00B9A9AB9BA90909A9B0A0090A000009000000000000000000000900000000000000000000000000000000000000000000000000000000000000A0B009090909000D090F00900000000009000F0099090A09000B09A90BB09A9A9A9BF09A9A90BA9A9A9BE9BB0BBA9A0909A00009A90A0000000000000000000000000000000000000000000000000000000000000009000000000000000000A909090F0F09A9009A9090B9A900000000A0B0B09B009F000A0009A9C9A99BA9A09AB0BBE9A9A009A9A9A9BA9AF0F0F9A000000900000090000090000000000000000000000000000000000000000000000A000000000A00000000000000000900900C0909F9C9A009CB0B09000000000000000AC09A00F99000009A90DAB09AB0AF9FB0BB9A9A9AA9B0FA99BF9BB9A090A90900A90090000090000090000000000000000000000000000000C0B0000000F000000AD0000000000000000000000000B0B0B090B0D09A90090000000000009A00099B00999A000000F9E9A99BAB90B9BA9BB0A9A9AB9BEBB9BAB0BB00A9000000A090000000900A0000009000000000000000009FD000000009000000009A00C0F0000090000000D0090F00009009E9C90D090BDB0B009090B0000000000A0000B0A0A90DA000009B00B9BDA9F0BFAFB9A0B09A9AB9A9B9BA9B9B009A90A09090900009A909A90090000000900000009000000000A9A90A0000A90000A00C909A00000A000000A009A0009090A9009A9A9A9AD09CB0DA90A090A00000000000B0090900A90DB00000BB0A9A9ABB0B9BA9BA9A0FB9EB9ABA9B0B09ADADA90000A009A90000A000900A9009A0000000000000000009000000900900C000DEF00AC90C900000000009009F0B00A900B00909A9C9A90BDB09A990A909A00000009A0B9A0A90900090B0000DB9E909A9BFBA9B0900BB0BB9A9B9A9A9A09A9A9A009A90A0000009009A0A900000090B090000000000000000000000C0ADBDEFFFFFDFFEFF0E90C09CA900A900909A9C090090B090B90DB9009AD00B00000900000A00BCA09D000999E90000BA9A99BA9ABB09A0A00BBCBB9ABB9A9A000BA9A0B009000000000A0009A00909A0B00000000000009000000000900000B0D0A0B0F9B9BF99B9A90F90CB9C0090E9ADAD0B9A09A000DA9E9B0009090A9090009A0009000B0B09B0A009A09A000009090A09A909A00090B0BBB0B09AB0B09A9000090A00A0000090009A000900A090090A0900000000000000000009A0900E90C9C9AD0A000A009A90A0B00B9EA090909A90090099A9A990009D00A0900A00B0009A00A9A00A9A090A9C9B00900000A0B9BB9A9A90000A9B0BFBBB090A0B09A9A9A0900000000A0A90000A00A900A90A090A09A9000000A00090000090A0900B0BACB0BC9A90000009090B0009CB0F0B09A9AC9A00909E99A90B0090A90900099009A09A9A90A9A0090BC9B0090B00900A90A9A00A00A90A9B0B000A090A0A000000A0B0900B000000000900000B0009000900000090090000000000C909E9F0909B0BCB000000000A0A00F0B0B090B0DA9090B09A0B090A909990009000A90A00900B0A09AF0A9A90B09A000A000A0A90AB9B0B000000A9A0B09A0000A90000000B0B00A000000000A90A0000000000A09A0A9A00000009090AD0F9A9EB09A0F0B0A9A90B000000A9090B0B0009ABC9A9CA9A09AD9099AD9A0D009000A090009B0B0B0B0BA9A9A90A09900B0090A9090A90A0B0090000000B0A00900B00B000000000A90B00A90B00000000000000B09A0090090A00F00A0A900B00909C9A9B0F9A9CB0000A00000CA0A9009A9AD0B9DAB9A9A090ADA090AD9A9000A0090A9B00900B0B9E9A9ADA90900B0090A90A00A909BA900A0A09A0B0B0B0A0B0B0000009A0B0A000090000000000000A00000A090A0B0A9000009090A909BAF0A90BCA9A0DA90B0000900B0B0B0AB0A9A0B90BA90FAD0B0B99990B9AD9D09090BA9009B09B0F9AB9A90A9AAD0BD0B0000A90B00A9A900A00090A09000B0B0B0B0B0A90B0000090B0A00A00000000000000A0909A909009E9E9A9A0B09B0A0D0BDAF0B9E9BB0AB0B090A0000A90BC9A9ADB0A909EFBDABCB00A0CB00909A9090B090B9E90BCBBAB9A90A9A9B0B09B0B0B09A00009AB0A0009A0A900A0BCB0B9A9A009AA0A09A9AA0090090A0A00A009A90A90A0A00A009A9A90000B0AB0A99BAFAFDAF0B0B0B90009AA909AB9AB0BA9E9B0F9F0BFBDEBDBB0BDB99A90B099E90909E9A9B9E9B0BDAB0A9ADB0B09A0B0000A0000B090900B0A090A9009EBDB0A9A9A9A0909A00A90B0A00A00909000A00A90A9009A90B0A9A90A9A9CBF0B9A0009FFFFDB0BCB0ADABA90AA000A9CB09A9B0BB0BFBDFF9FAFCB0B0F0B000F9A999A9A9AB0B0BA0B9A90BCB0BA9E9A9F0A00000B000A9A0B0009AA90A0A0BEFFB9A9A9A9A0B00B00A9A9A9A0B0A0A0000B00A90A9000000B0B0A9000A909B009A0B0FFFFFEF0B0B0B09AB909B0B0AB0B0B0A90A90B0FBFFFFFBFB09990B909A9AABC9BDB9F9F9BB0BBA9AB0B0BB0BDA9B09A09000009A0B0B0B009A0090B9FF9EBF9A90A9A00B00B00B0BE9B0B0B09A9000B0A900000B0B0B0B00A909ABA09A0090BFFFFFFFF0B0A0BE90EBA0B0B90A9A0B9AB9AB0BBCFBDFFFF0F0B0F9EB0DB999BA9ABA9ABA90B90A9B0B0B00B0A9A9A000A00A09A9A9A0B0A9A00B0A9EFFEFF0A9AA90B0B00B0AB0B90BCB0A09A00A0B009A00A0B0B0B0B09A90A0B009A00B0BFFFFFFFFF0B099A9ABB90B9A00A9A0B90A9CADFADFFEFFFFFFFF0BBFB9DBBFBEBDB9A9B9A9BBA0A90A9A9A9A9A90BE090B00909ADB9A9A0A9A9A9A9BBFBFFFFFF009AB0B0FA0B00F0AB0B0A90A0B0900ABA9A99A0BCB0B0A000A9B0B0A90B0A9EFFFFFFFFF0B0A9A9A9EB0A9B09A090AB9BBFFFFFFFFFFFFFFFF909B9A9BFB9B9AFA9A9A9A9009000B0B0000000A90B0A0B0A0A9B0000909A0B0B0F0FCFFFFFFFBA90B0E90B00A9A90BCABCA9A90AA9009A9A0A9A9B0B0F9B0B0A0B0B0B0A9BB9FFFFFFFFFACB0A9ADA90B0A9AA9AA900BCBFFFFFFFDFFFFFFFFB009A909B9EBB9B9ADAB0BAB00000000B0090009A90B00009A9ABBB0B0A00B0FFFBFBFFFFFFFFEDBA9A9A000F9A9AC0A90A9A9EB90ABBE9A9B0A9ACBCB0A0F0B9BD0A9A9B0BCBFFFFFFFFFF9A09ADA9AB0B0A09A90A0BFBFFFFFFFFFBFFFFFFF000A9CB0BFB9EB0F9A90B09000000000000A000000A00B0BA9A9A90A0009ADFFFBCFFFFFFFFFFFB0000000E9A0AC0A900E90A9A90AF909A9A0A900B0B0B09A0BCB0B9B0BADBF9FFFFFFFFFFE9FA9A90E09A9E9AADA9FFFFFFFFFFFBFDFFFFFFF00090B0BDA9A99B00B0BA9A900000000000909000090B0BCBDA909FFBB0ADAFFFFFDFEFFFFFFFF00F00000000B0B00A0000B0A90A90AFABC09000E0E0F0E00F0B0B0A0B09AF9EFFFFFFFFFF9A00E0A090ACBFFF9AFFFFFFFFFFFFFDFEFFFFFFF0000B090B9B9A00A90B0900000000000000000000000BCBF0B0000FFCFB0BFFFFFBEBDFFFFFFFFF00A00A00A0C00C00CA900D0A9CA90090B0A000009A9A9E00BCBC90BCBB9EF9BFFFFFFFFFFDA909C0AC9ACFFFFFFFFFFFFFFFFFBFF9FFFFFFFB000000000009A90000000000000000000000000000A0B0FF00000FFFB0FFFFFFFDFFFFFFFFFFFE0000000000A00A00A0CA00AC0A0CA0E00000000E0F0F00F0CB09A9E900CBDEDFFFFFFFFF0A0E0A0A00A0FFFFFFFFFFFFFFFFFFDE9FFFFFFFF0000000000000000000000000000000000000000000090DADB0000FFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000B0F00E00A90B0000A9BFFFBFFFFFFFFFF00000000000FFFFFFFFFFFFFFFFFFFBFFFFFFFFF0000000000000000000000000000000000000000000000BFF00000000000000000000000000105000000000000AEAD05FE")); - NorthwindResources.Images = strs; - } - - public static byte[] GetImage(int id) - { - return NorthwindResources.Images[NorthwindResources.GetImageKey(id)]; - } - - private static string GetImageKey(int id) - { - return string.Concat(typeof(T).Name, id); - } - - public static byte[] ToByteArray(string hexString) - { - int length = hexString.Length; - byte[] num = new byte[length / 2]; - for (int i = 0; i < length; i = i + 2) - { - num[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16); - } - return num; - } -} -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/NorthwindPerfTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/NorthwindPerfTests.cs deleted file mode 100644 index 0efa4332b..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/NorthwindPerfTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Data; -using System.Diagnostics; -using Northwind.Common.DataModel; -using NUnit.Framework; -using ServiceStack.DataAccess; -using ServiceStack.OrmLite.Firebird; - -namespace ServiceStack.OrmLite.FirebirdTests -{ - [Ignore("Perf test")] - [TestFixture] - public class NorthwindPerfTests - { - [Test] - public void Load_Northwind_database() - { - OrmLiteConfig.DialectProvider = new FirebirdOrmLiteDialectProvider(); - - NorthwindData.LoadData(false); - GC.Collect(); - - var stopWatch = new Stopwatch(); - stopWatch.Start(); - - using (var dbConn = "User=SYSDBA;Password=masterkey;Database=/var/lib/firebird/2.1/data/NorthWind.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;".OpenDbConnection()) - using (var dbCmd = dbConn.CreateCommand()) - { - using (var client = new OrmLitePersistenceProvider(dbConn)) - { - OrmLiteNorthwindTests.CreateNorthwindTables(dbCmd); - LoadNorthwindData(client); - } - } - - Console.WriteLine("stopWatch.ElapsedMilliseconds: " + stopWatch.ElapsedMilliseconds); - } - - private static void LoadNorthwindData(IBasicPersistenceProvider persistenceProvider) - { - persistenceProvider.StoreAll(NorthwindData.Categories); - persistenceProvider.StoreAll(NorthwindData.Customers); - persistenceProvider.StoreAll(NorthwindData.Employees); - persistenceProvider.StoreAll(NorthwindData.Shippers); - persistenceProvider.StoreAll(NorthwindData.Orders); - persistenceProvider.StoreAll(NorthwindData.Products); - persistenceProvider.StoreAll(NorthwindData.OrderDetails); - persistenceProvider.StoreAll(NorthwindData.CustomerCustomerDemos); - persistenceProvider.StoreAll(NorthwindData.Regions); - persistenceProvider.StoreAll(NorthwindData.Territories); - persistenceProvider.StoreAll(NorthwindData.EmployeeTerritories); - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/NorthwindTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/NorthwindTests.cs deleted file mode 100644 index e09c1bb65..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/NorthwindTests.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.OrmLite.Firebird; -using Northwind.Common.DataModel; - -namespace ServiceStack.OrmLite.FirebirdTests -{ - [TestFixture] - class NorthwindTests : OrmLiteTestBase - { - [Test] - public void JoinSqlBuilderWithFieldAliasTest() - { - var factory = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider); - - using (var db = factory.OpenDbConnection()) - { - var jn = new JoinSqlBuilder(); - - jn = jn.Join(x => x.Id, x => x.EmployeeId) - .LeftJoin(x => x.TerritoryId, x => x.Id) - .Where(x => x.TerritoryDescription.Trim() == "Westboro"); - - var sql = jn.ToSql(); - // here sql should contain Employees.EmployeID instead of Employees.Id - - var result = db.Select(sql); - // the generated Sql is ok if the Query doesn't fail - } - } - } -} diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteBasicPersistenceProviderTest.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteBasicPersistenceProviderTest.cs index 48b95ac4e..54ae0a0ca 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteBasicPersistenceProviderTest.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteBasicPersistenceProviderTest.cs @@ -10,26 +10,21 @@ namespace ServiceStack.OrmLite.FirebirdTests public class OrmLiteBasicPersistenceProviderTests : OrmLiteTestBase { - [SetUp] - public void SetUp() - { - - } [Test] public void Can_GetById_from_basic_persistence_provider() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) + using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { - db.CreateTable(true); + db.DropAndCreateTable(); - var basicProvider = new OrmLitePersistenceProvider(db); + //var basicProvider = new OrmLitePersistenceProvider(db); var row = ModelWithFieldsOfDifferentTypes.Create(1); db.Insert(row); - var providerRow = basicProvider.GetById(1); + var providerRow = db.SingleById(1); ModelWithFieldsOfDifferentTypes.AssertIsEqual(providerRow, row); } @@ -40,7 +35,7 @@ public void Can_GetByIds_from_basic_persistence_provider() { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { - db.CreateTable(true); + db.DropAndCreateTable(); var basicProvider = new OrmLitePersistenceProvider(db); @@ -63,7 +58,7 @@ public void Can_Store_from_basic_persistence_provider() { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { - db.CreateTable(true); + db.DropAndCreateTable(); var basicProvider = new OrmLitePersistenceProvider(db); @@ -86,7 +81,7 @@ public void Can_Delete_from_basic_persistence_provider() { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { - db.CreateTable(true); + db.DropAndCreateTable(); var basicProvider = new OrmLitePersistenceProvider(db); diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteConnectionFactoryTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteConnectionFactoryTests.cs deleted file mode 100644 index 461c73bc5..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteConnectionFactoryTests.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using Northwind.Common.DataModel; -using NUnit.Framework; -using ServiceStack.OrmLite.Firebird; - -namespace ServiceStack.OrmLite.FirebirdTests -{ - [TestFixture] - [Ignore] - public class OrmLiteConnectionFactoryTests - { - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - OrmLiteConfig.DialectProvider = FirebirdOrmLiteDialectProvider.Instance; //use Pooling=false ? - } - - [Test] - public void AutoDispose_ConnectionFactory_disposes_connection() - { - var factory = new OrmLiteConnectionFactory("User=SYSDBA;Password=masterkey;Database=ormlite-tests.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;") - { - AutoDisposeConnection = true, - }; - - using (var db = factory.OpenDbConnection()) - { - db.CreateTable(true); - db.Insert(new Shipper { CompanyName = "I am shipper 1" }); - } - - using (var db = factory.OpenDbConnection()) - { - db.CreateTable(false); - Assert.That(db.Select(), Has.Count.EqualTo(1)); - - db.DeleteAll(); - Assert.That(db.Select(), Has.Count.EqualTo(0)); - } - } - - [Test] - public void NonAutoDispose_ConnectionFactory_reuses_connection() - { - var factory = new OrmLiteConnectionFactory("User=SYSDBA;Password=masterkey;Database=ormlite-tests.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;") - { - AutoDisposeConnection = false, - }; - - using (var db = factory.OpenDbConnection()) - { - db.CreateTable(false); - db.Insert(new Shipper { CompanyName = "I am shipper 2" }); - } - - using (var db = factory.OpenDbConnection()) - { - db.CreateTable(false); - Assert.That(db.Select(), Has.Count.EqualTo(1)); - - db.DeleteAll(); - Assert.That(db.Select(), Has.Count.EqualTo(0)); - } - } - - [Test] - public void NonAutoDispose_ConnectionFactory_delete_and_drop() - { - var factory = new OrmLiteConnectionFactory("User=SYSDBA;Password=masterkey;Database=ormlite-tests.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;") - { - AutoDisposeConnection = false, - }; - - using (var db = factory.OpenDbConnection()) - { - db.DeleteAll(); - Assert.That(db.Select(), Has.Count.EqualTo(0)); - } - - using (var db = factory.OpenDbConnection()) - { - db.DropTable(); - var schema = new Schema { - Connection = db, - }; - - Assert.That(schema.GetTable("Shippers".ToUpper()) == null); - } - } - - } -} diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteConnectionTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteConnectionTests.cs index a3ccacc86..91cb2e8ee 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteConnectionTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteConnectionTests.cs @@ -5,57 +5,58 @@ namespace ServiceStack.OrmLite.FirebirdTests { - [TestFixture] - public class OrmLiteConnectionTests - : OrmLiteTestBase - { - [Test][Ignore] - public void Can_create_connection_to_blank_database() - { - var connString ="User=SYSDBA;Password=masterkey;Database=ormlite-tests.fdb;DataSource=localhost;Dialect=3;charset=ISO8859_1;"; - using (var db = connString.OpenDbConnection()) - { - } - } + [TestFixture] + public class OrmLiteConnectionTests + : OrmLiteTestBase + { + [Test]//[Ignore("")] + public void Can_create_connection_to_blank_database() + { + var connString = + $"User=SYSDBA;Password=masterkey;Database=/ormlite-tests/ormlite-tests.fdb;DataSource=localhost;Dialect=3;charset=utf8;"; + using (var db = connString.OpenDbConnection()) + { + } + } - [Test] - public void Can_create_connection() - { + [Test] + public void Can_create_connection() + { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - } - } + { + } + } - [Test] - public void Can_create_ReadOnly_connection() - { - using (var db = ConnectionString.OpenReadOnlyDbConnection()) - { - } - } + [Test] + public void Can_create_ReadOnly_connection() + { + using (var db = ConnectionString.OpenReadOnlyDbConnection()) + { + } + } - [Test][Ignore] - public void Can_create_table_with_ReadOnly_connection() - { - using (var db = ConnectionString.OpenReadOnlyDbConnection()) - { - try - { - db.CreateTable(true); - db.Insert(new ModelWithIdAndName(0)); - } - catch (Exception ex) - { - Log(ex.Message); - return; - } - Assert.Fail("Should not be able to create a table with a readonly connection"); - } - } + [Test][Ignore("")] + public void Can_create_table_with_ReadOnly_connection() + { + using (var db = ConnectionString.OpenReadOnlyDbConnection()) + { + try + { + db.CreateTable(true); + db.Insert(new ModelWithIdAndName(0)); + } + catch (Exception ex) + { + Log(ex.Message); + return; + } + Assert.Fail("Should not be able to create a table with a readonly connection"); + } + } - [Test] - public void Can_open_two_ReadOnlyConnections_to_same_database() - { + [Test] + public void Can_open_two_ReadOnlyConnections_to_same_database() + { var db = ConnectionString.OpenReadOnlyDbConnection(); db.CreateTable(true); db.Insert(new ModelWithIdAndName(1)); @@ -65,9 +66,9 @@ public void Can_open_two_ReadOnlyConnections_to_same_database() var rows = dbReadOnly.Select(); Assert.That(rows, Has.Count.EqualTo(2)); - dbReadOnly.Dispose(); - db.Dispose(); - } + dbReadOnly.Dispose(); + db.Dispose(); + } - } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableTests.cs index 22f446970..2b6d5e503 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableTests.cs @@ -6,145 +6,126 @@ namespace ServiceStack.OrmLite.FirebirdTests { [TestFixture] - public class OrmLiteCreateTableTests - : OrmLiteTestBase + public class OrmLiteCreateTableTests : OrmLiteTestBase { [Test] public void Does_table_Exists() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.DropTable(); + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.DropTable(); - Assert.That( - OrmLiteConfig.DialectProvider.DoesTableExist(db, typeof(ModelWithIdOnly).Name), - Is.False); + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithIdOnly)), + Is.False); - db.CreateTable(true); + db.CreateTable(true); - Assert.That( - OrmLiteConfig.DialectProvider.DoesTableExist(db, typeof(ModelWithIdOnly).Name), - Is.True); - } + Assert.That( + OrmLiteConfig.DialectProvider.DoesTableExist(db, nameof(ModelWithIdOnly)), + Is.True); } [Test] public void Can_create_ModelWithIdOnly_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - } + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTable(true); } [Test] public void Can_create_ModelWithOnlyStringFields_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - } + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTable(true); } [Test] public void Can_create_ModelWithLongIdAndStringFields_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - } + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTable(true); } [Test] public void Can_create_ModelWithFieldsOfDifferentTypes_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - } + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTable(true); } [Test] public void Can_preserve_ModelWithIdOnly_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTable(true); - db.Insert(new ModelWithIdOnly(1)); - db.Insert(new ModelWithIdOnly(2)); + db.Insert(new ModelWithIdOnly(1)); + db.Insert(new ModelWithIdOnly(2)); - db.CreateTable(false); + db.CreateTable(false); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(2)); - } + Assert.That(rows, Has.Count.EqualTo(2)); } [Test] public void Can_preserve_ModelWithIdAndName_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - db.DeleteAll(); + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTable(true); + db.DeleteAll(); - db.Insert(new ModelWithIdAndName(0)); - db.Insert(new ModelWithIdAndName(0)); + db.Insert(new ModelWithIdAndName(0)); + db.Insert(new ModelWithIdAndName(0)); - db.CreateTable(false); + db.CreateTable(false); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(2)); - } + Assert.That(rows, Has.Count.EqualTo(2)); } [Test] public void Can_overwrite_ModelWithIdOnly_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTable(true); - db.Insert(new ModelWithIdOnly(1)); - db.Insert(new ModelWithIdOnly(2)); + db.Insert(new ModelWithIdOnly(1)); + db.Insert(new ModelWithIdOnly(2)); - db.CreateTable(true); + db.CreateTable(true); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(0)); - } + Assert.That(rows, Has.Count.EqualTo(0)); } [Test] public void Can_create_multiple_tables() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTables(true, typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); + using var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + db.CreateTables(true, typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); - db.Insert(new ModelWithIdOnly(1)); - db.Insert(new ModelWithIdOnly(2)); + db.Insert(new ModelWithIdOnly(1)); + db.Insert(new ModelWithIdOnly(2)); - db.Insert(new ModelWithIdAndName(0)); - db.Insert(new ModelWithIdAndName(0)); + db.Insert(new ModelWithIdAndName(0)); + db.Insert(new ModelWithIdAndName(0)); - var rows1 = db.Select(); - var rows2 = db.Select(); + var rows1 = db.Select(); + var rows2 = db.Select(); - Assert.That(rows1, Has.Count.EqualTo(2)); - Assert.That(rows2, Has.Count.EqualTo(2)); - } + Assert.That(rows1, Has.Count.EqualTo(2)); + Assert.That(rows2, Has.Count.EqualTo(2)); } [Test] public void Can_create_ModelWithIdAndName_table_with_specified_DefaultStringLength() { - OrmLiteConfig.DialectProvider.DefaultStringLength = 255; + OrmLiteConfig.DialectProvider.GetStringConverter().StringLength = 255; var createTableSql = OrmLiteConfig.DialectProvider.ToCreateTableStatement(typeof(ModelWithIdAndName)); Console.WriteLine("createTableSql: " + createTableSql); diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithIndexesTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithIndexesTests.cs index ccfefc150..bddcdbc6f 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithIndexesTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithIndexesTests.cs @@ -13,7 +13,7 @@ public class OrmLiteCreateTableWithIndexesTests [Test] public void Can_create_ModelWithIndexFields_table() { - OrmLiteConfig.DialectProvider.DefaultStringLength=128; + OrmLiteConfig.DialectProvider.GetStringConverter().StringLength = 128; using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { db.CreateTable(true); @@ -28,7 +28,7 @@ public void Can_create_ModelWithIndexFields_table() [Test] public void Can_create_ModelWithCompositeIndexFields_table() { - OrmLiteConfig.DialectProvider.DefaultStringLength=128; + OrmLiteConfig.DialectProvider.GetStringConverter().StringLength = 128; using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { db.CreateTable(true); @@ -39,7 +39,5 @@ public void Can_create_ModelWithCompositeIndexFields_table() Assert.IsTrue(sql.Contains("idx_modelwcif_comp1_comp2")); } } - - } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithNamigStrategyTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithNamigStrategyTests.cs index 061443203..122d75313 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithNamigStrategyTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteCreateTableWithNamigStrategyTests.cs @@ -1,39 +1,32 @@ using System; using NUnit.Framework; using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Tests; namespace ServiceStack.OrmLite.FirebirdTests { - [TestFixture] - public class OrmLiteCreateTableWithNamigStrategyTests - : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.Firebird)] + public class OrmLiteCreateTableWithNamingStrategyTests : OrmLiteProvidersTestBase { - + public OrmLiteCreateTableWithNamingStrategyTests(DialectContext context) : base(context) {} + [Test] - public void Can_create_TableWithNamigStrategy_table_nameUnderscoreCoumpound() + public void Can_create_TableWithNamingStrategy_table_nameUnderscoreCompound() { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new UnderscoreSeparatedCompoundNamingStrategy(); - - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); + using (new TemporaryNamingStrategy(DialectProvider, new UnderscoreSeparatedCompoundNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } } [Test] - public void Can_get_data_from_TableWithNamigStrategy_with_GetById() + public void Can_get_data_from_TableWithNamingStrategy_with_GetById() { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) { db.CreateTable(true); ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id= "999", AlbumId = "112", AlbumName="ElectroShip", Name = "MyNameIsBatman"}; @@ -43,20 +36,14 @@ public void Can_get_data_from_TableWithNamigStrategy_with_GetById() Assert.AreEqual(m.Name, modelFromDb.Name); } - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); } [Test] - public void Can_get_data_from_TableWithNamigStrategy_with_query_by_example() + public void Can_get_data_from_TableWithNamingStrategy_with_query_by_example() { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) { db.CreateTable(true); ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; @@ -66,36 +53,28 @@ public void Can_get_data_from_TableWithNamigStrategy_with_query_by_example() Assert.AreEqual(m.Name, modelFromDb.Name); } - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); } [Test] - public void Can_get_data_from_TableWithNamigStrategy_AfterChangingNamingStrategy() - { - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + public void Can_get_data_from_TableWithNamingStrategy_AfterChangingNamingStrategy() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - Assert.AreEqual(m.Name, modelFromDb.Name); + Assert.AreEqual(m.Name, modelFromDb.Name); modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - - } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); + Assert.AreEqual(m.Name, modelFromDb.Name); + + } - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) + using (var db = OpenDbConnection()) { db.CreateTable(true); ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; @@ -110,13 +89,8 @@ public void Can_get_data_from_TableWithNamigStrategy_AfterChangingNamingStrategy } - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) { db.CreateTable(true); ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; @@ -130,8 +104,6 @@ public void Can_get_data_from_TableWithNamigStrategy_AfterChangingNamingStrategy Assert.AreEqual(m.Name, modelFromDb.Name); } - - OrmLite.OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); } } diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteGetScalarTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteGetScalarTests.cs index 1503f8fec..9afc4e7e3 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteGetScalarTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteGetScalarTests.cs @@ -157,7 +157,7 @@ public void Can_get_scalar_value(){ Assert.That(expectedString, Is.EqualTo(r9)); r9 = db.Scalar(e=> Sql.Max(e.Name), e=>e.City=="SinCity"); - Assert.IsNullOrEmpty(r9); + Assert.That(r9, Is.Null.Or.Empty); var expectedBool=authors.Min(e=>e.Active); var r10 = db.Scalar(e=> Sql.Min(e.Active)); diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteInsertTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteInsertTests.cs index 6ee0a2d9f..f4ab29d13 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteInsertTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteInsertTests.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Northwind.Common.DataModel; using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.DataAnnotations; @@ -166,39 +165,6 @@ public void Can_insert_TaskQueue_table() TaskQueue.AssertIsEqual(rows[0], row); } } - - [Test] - public void Can_insert_table_with_blobs() - { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - var dsl= OrmLiteConfig.DialectProvider.DefaultStringLength; - OrmLiteConfig.DialectProvider.DefaultStringLength=1024; - - db.CreateTable(true); - OrmLiteConfig.DialectProvider.DefaultStringLength=dsl; - - var row = OrderBlob.Create(1); - - db.Insert(row); - - var rows = db.Select(); - - Assert.That(rows, Has.Count.EqualTo(1)); - - var newRow = rows[0]; - - Assert.That(newRow.Id, Is.EqualTo(row.Id)); - Assert.That(newRow.Customer.Id, Is.EqualTo(row.Customer.Id)); - Assert.That(newRow.Employee.Id, Is.EqualTo(row.Employee.Id)); - Assert.That(newRow.IntIds, Is.EquivalentTo(row.IntIds)); - Assert.That(newRow.CharMap, Is.EquivalentTo(row.CharMap)); - Assert.That(newRow.OrderDetails.Count, Is.EqualTo(row.OrderDetails.Count)); - Assert.That(newRow.OrderDetails[0].ProductId, Is.EqualTo(row.OrderDetails[0].ProductId)); - Assert.That(newRow.OrderDetails[1].ProductId, Is.EqualTo(row.OrderDetails[1].ProductId)); - Assert.That(newRow.OrderDetails[2].ProductId, Is.EqualTo(row.OrderDetails[2].ProductId)); - } - } public class UserAuth { @@ -244,8 +210,5 @@ public void Can_insert_table_with_UserAuth() Assert.That(rows[0].UserName, Is.EqualTo(userAuth.UserName)); } } - - } - } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSaveTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSaveTests.cs index 6dcac6af6..bbe6fbd0b 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSaveTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSaveTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data; using NUnit.Framework; using ServiceStack.Common.Tests.Models; @@ -9,139 +10,127 @@ namespace ServiceStack.OrmLite.FirebirdTests public class OrmLiteSaveTests : OrmLiteTestBase { - + private IDbConnection Open() => + new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open(); + [Test] public void Can_Save_into_ModelWithFieldsOfDifferentTypes_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); + using var db = Open(); + db.CreateTable(true); - var row = ModelWithFieldsOfDifferentTypes.Create(1); + var row = ModelWithFieldsOfDifferentTypes.Create(1); - db.Save(row); - } + db.Save(row); } [Test] public void Can_Save_and_select_from_ModelWithFieldsOfDifferentTypes_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); + using var db = Open(); + db.CreateTable(true); - var row = ModelWithFieldsOfDifferentTypes.Create(1); + var row = ModelWithFieldsOfDifferentTypes.Create(1); - db.Save(row); + db.Save(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithFieldsOfDifferentTypes.AssertIsEqual(rows[0], row); - } + ModelWithFieldsOfDifferentTypes.AssertIsEqual(rows[0], row); } [Test] public void Can_SaveAll_and_select_from_ModelWithFieldsOfDifferentTypes_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); + using var db = Open(); + db.CreateTable(true); - var rowIds = new List { 1, 2, 3, 4, 5 }; - var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(x)); + var rowIds = new List { 1, 2, 3, 4, 5 }; + var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(x)); - db.SaveAll(newRows); + db.SaveAll(newRows); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(newRows.Count)); - } + Assert.That(rows, Has.Count.EqualTo(newRows.Count)); } [Test] public void Can_SaveAll_and_select_from_ModelWithFieldsOfDifferentTypes_table_with_no_ids() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - db.DeleteAll(); - var rowIds = new List { 1, 2, 3, 4, 5 }; - var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(default(int))); + using var db = Open(); + db.CreateTable(true); + db.DeleteAll(); + var rowIds = new List { 1, 2, 3, 4, 5 }; + var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(default(int))); - db.SaveAll(newRows); + db.SaveAll(newRows); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(newRows.Count)); - } + Assert.That(rows, Has.Count.EqualTo(newRows.Count)); } [Test] public void Can_Save_table_with_null_fields() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); - db.DeleteAll(); - var row = ModelWithIdAndName.Create(0); - row.Name = null; + using var db = Open(); + db.CreateTable(true); + db.DeleteAll(); + var row = ModelWithIdAndName.Create(0); + row.Name = null; - db.Save(row); + db.Save(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithIdAndName.AssertIsEqual(rows[0], row); - } + ModelWithIdAndName.AssertIsEqual(rows[0], row); } [Test] public void Can_Save_TaskQueue_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); + using var db = Open(); + db.CreateTable(true); - var row = TaskQueue.Create(1); + var row = TaskQueue.Create(1); - db.Save(row); + db.Save(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - //Update the auto-increment id - row.Id = rows[0].Id; + //Update the auto-increment id + row.Id = rows[0].Id; - TaskQueue.AssertIsEqual(rows[0], row); - } + TaskQueue.AssertIsEqual(rows[0], row); } [Test] public void Can_SaveAll_and_select_from_Movie_table() { - using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) - { - db.CreateTable(true); + using var db = Open(); + db.CreateTable(true); - var top5Movies = new List - { - new Movie { Id = "tt0111161", Title = "The Shawshank Redemption", Rating = 9.2m, Director = "Frank Darabont", ReleaseDate = new DateTime(1995,2,17), TagLine = "Fear can hold you prisoner. Hope can set you free.", Genres = new List{"Crime","Drama"}, }, - new Movie { Id = "tt0068646", Title = "The Godfather", Rating = 9.2m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1972,3,24), TagLine = "An offer you can't refuse.", Genres = new List {"Crime","Drama", "Thriller"}, }, - new Movie { Id = "tt1375666", Title = "Inception", Rating = 9.2m, Director = "Christopher Nolan", ReleaseDate = new DateTime(2010,7,16), TagLine = "Your mind is the scene of the crime", Genres = new List{"Action", "Mystery", "Sci-Fi", "Thriller"}, }, - new Movie { Id = "tt0071562", Title = "The Godfather: Part II", Rating = 9.0m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1974,12,20), Genres = new List {"Crime","Drama", "Thriller"}, }, - new Movie { Id = "tt0060196", Title = "The Good, the Bad and the Ugly", Rating = 9.0m, Director = "Sergio Leone", ReleaseDate = new DateTime(1967,12,29), TagLine = "They formed an alliance of hate to steal a fortune in dead man's gold", Genres = new List{"Adventure","Western"}, }, - }; + var top5Movies = new List + { + new Movie { Id = "tt0111161", Title = "The Shawshank Redemption", Rating = 9.2m, Director = "Frank Darabont", ReleaseDate = new DateTime(1995,2,17), TagLine = "Fear can hold you prisoner. Hope can set you free.", Genres = new List{"Crime","Drama"}, }, + new Movie { Id = "tt0068646", Title = "The Godfather", Rating = 9.2m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1972,3,24), TagLine = "An offer you can't refuse.", Genres = new List {"Crime","Drama", "Thriller"}, }, + new Movie { Id = "tt1375666", Title = "Inception", Rating = 9.2m, Director = "Christopher Nolan", ReleaseDate = new DateTime(2010,7,16), TagLine = "Your mind is the scene of the crime", Genres = new List{"Action", "Mystery", "Sci-Fi", "Thriller"}, }, + new Movie { Id = "tt0071562", Title = "The Godfather: Part II", Rating = 9.0m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1974,12,20), Genres = new List {"Crime","Drama", "Thriller"}, }, + new Movie { Id = "tt0060196", Title = "The Good, the Bad and the Ugly", Rating = 9.0m, Director = "Sergio Leone", ReleaseDate = new DateTime(1967,12,29), TagLine = "They formed an alliance of hate to steal a fortune in dead man's gold", Genres = new List{"Adventure","Western"}, }, + }; - db.SaveAll(top5Movies); + db.SaveAll(top5Movies); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(top5Movies.Count)); - } + Assert.That(rows, Has.Count.EqualTo(top5Movies.Count)); } } diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSelectTests.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSelectTests.cs index 5ce54dbe7..f5cedab86 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSelectTests.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteSelectTests.cs @@ -99,7 +99,7 @@ public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() db.Insert(filterRow); - var rows = db.SelectFmt("AlbumName = {0}", filterRow.AlbumName); + var rows = db.Select("AlbumName = @AlbumName", new { filterRow.AlbumName }); var dbRowIds = rows.ConvertAll(x => x.Id); Assert.That(dbRowIds, Has.Count.EqualTo(1)); @@ -119,7 +119,7 @@ public void Can_select_scalar_value() n.Times(x => db.Insert(ModelWithIdAndName.Create(0))); - var count = db.ScalarFmt("SELECT COUNT(*) FROM ModelWIN"); + var count = db.Scalar("SELECT COUNT(*) FROM ModelWIN"); Assert.That(count, Is.EqualTo(n)); } @@ -163,7 +163,7 @@ public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() db.Insert(filterRow); var dbRowIds = new List(); - var rows = db.SelectLazyFmt("AlbumName = {0}", filterRow.AlbumName); + var rows = db.SelectLazy("AlbumName = @AlbumName", new { filterRow.AlbumName }); foreach (var row in rows) { dbRowIds.Add(row.Id); @@ -186,7 +186,7 @@ public void Can_GetFirstColumn() n.Times(x => db.Insert(ModelWithIdAndName.Create(0))); - var ids = db.ColumnFmt("SELECT Id FROM ModelWIN"); + var ids = db.Column("SELECT Id FROM ModelWIN"); Assert.That(ids.Count, Is.EqualTo(n)); } @@ -204,7 +204,7 @@ public void Can_GetFirstColumnDistinct() n.Times(x => db.Insert(ModelWithIdAndName.Create(0))); - var ids = db.ColumnDistinctFmt("SELECT Id FROM ModelWIN"); + var ids = db.ColumnDistinct("SELECT Id FROM ModelWIN"); Assert.That(ids.Count, Is.EqualTo(n)); } @@ -226,7 +226,7 @@ public void Can_GetLookup() db.Insert(row); }); - var lookup = db.LookupFmt("SELECT Name, Id FROM ModelWIN"); + var lookup = db.Lookup("SELECT Name, Id FROM ModelWIN"); Assert.That(lookup, Has.Count.EqualTo(2)); Assert.That(lookup["OddGroup"], Has.Count.EqualTo(3)); @@ -264,7 +264,7 @@ public void Can_Select_subset_ModelWithIdAndName_from_ModelWithFieldsOfDifferent rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); - var rows = db.SelectFmt("SELECT Id, Name FROM ModelWFDT"); + var rows = db.Select("SELECT Id, Name FROM ModelWFDT"); var dbRowIds = rows.ConvertAll(x => x.Id); Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); @@ -306,13 +306,16 @@ public void Can_Select_In_for_string_value() }; db.Insert(m); } - - var selectInNames = new[] {"Name1", "Name2"}; - var rows = db.SelectFmt("Name IN ({0})", selectInNames.SqlInValues()); - Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); - } - } + var selectInNames = new[] { "Name1", "Name2" }; + var rows = db.Select("Name IN ({0})".Fmt(selectInNames.SqlInParams()), + new { values = selectInNames.SqlInValues() }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + + rows = db.Select("Name IN (@p1, @p2)", new { p1 = "Name1", p2 = "Name2" }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + } + } //[Alias("RDB$DATABASE")] public class PocoFlag @@ -326,7 +329,7 @@ public void Can_populate_PocoFlag() { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { - var rows = db.SelectFmt("SELECT 1 as Flag FROM RDB$DATABASE"); + var rows = db.Select("SELECT 1 as Flag FROM RDB$DATABASE"); Assert.That(rows[0].Flag); } } @@ -342,7 +345,7 @@ public void Can_populate_PocoFlagWithId() { using (var db = new OrmLiteConnectionFactory(ConnectionString, FirebirdDialect.Provider).Open()) { - var rows = db.SelectFmt("SELECT 1 as Id, 1 as Flag FROM RDB$DATABASE"); + var rows = db.Select("SELECT 1 as Id, 1 as Flag FROM RDB$DATABASE"); Assert.That(rows[0].Id, Is.EqualTo(1)); Assert.That(rows[0].Flag); } diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteTestBase.cs b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteTestBase.cs index 2ba790a40..8700b4c70 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteTestBase.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/OrmLiteTestBase.cs @@ -4,6 +4,7 @@ using NUnit.Framework; using ServiceStack.Logging; using ServiceStack.OrmLite.Firebird; +using ServiceStack.OrmLite.Tests; namespace ServiceStack.OrmLite.FirebirdTests { @@ -11,22 +12,20 @@ public class OrmLiteTestBase { protected virtual string ConnectionString { get; set; } - protected string GetFileConnectionString() - { - return ConfigurationManager.ConnectionStrings["testDb"].ConnectionString; - } + protected virtual string GetFileConnectionString() => FirebirdDb.DefaultConnection; + protected virtual IOrmLiteDialectProvider GetDialectProvider() => FirebirdOrmLiteDialectProvider.Instance; protected void CreateNewDatabase() { ConnectionString = GetFileConnectionString(); } - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { LogManager.LogFactory = new ConsoleLogFactory(); - OrmLiteConfig.DialectProvider = FirebirdOrmLiteDialectProvider.Instance; + OrmLiteConfig.DialectProvider = GetDialectProvider(); ConnectionString = GetFileConnectionString(); } @@ -37,7 +36,7 @@ public void Log(string text) public IDbConnection OpenDbConnection(string connString = null) { - connString = connString ?? ConnectionString; + connString ??= ConnectionString; return connString.OpenDbConnection(); } } diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithAutoId.cs b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithAutoId.cs new file mode 100644 index 000000000..de52273d4 --- /dev/null +++ b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithAutoId.cs @@ -0,0 +1,82 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.Common.Tests.Models{ + + public class ModelWithAutoId + { + [AutoId, ReturnOnInsert] + public Guid Id + { + get; + set; + } + + public string Name + { + get; + set; + } + + public ModelWithAutoId() + { + } + + public ModelWithAutoId(Guid id) + { + this.Id = id; + this.Name = string.Concat("Name_", id.ToString()); + } + + public static void AssertIsEqual(ModelWithAutoId actual, ModelWithAutoId expected) + { + if (actual == null || expected == null) + { + Assert.That(actual == expected, Is.True); + return; + } + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.Name, Is.EqualTo(expected.Name)); + } + + public static ModelWithAutoId Create(Guid id) + { + return new ModelWithAutoId(id); + } + + public bool Equals(ModelWithAutoId other) + { + if (object.ReferenceEquals(null, other)) + { + return false; + } + if (object.ReferenceEquals(this, other)) + { + return true; + } + if (other.Id == this.Id) + { + return object.Equals(other.Name, this.Name); + } + return false; + } + + public override bool Equals(object obj) + { + if (object.ReferenceEquals(null, obj)) + { + return false; + } + if (object.ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != typeof(ModelWithAutoId)) + { + return false; + } + return this.Equals((ModelWithAutoId)obj); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithAutoIncrement.cs b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithAutoIncrement.cs new file mode 100644 index 000000000..2fa53cd85 --- /dev/null +++ b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithAutoIncrement.cs @@ -0,0 +1,82 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.Common.Tests.Models{ + + public class ModelWithAutoIncrement + { + [AutoIncrement, ReturnOnInsert] + public long Id + { + get; + set; + } + + public string Name + { + get; + set; + } + + public ModelWithAutoIncrement() + { + } + + public ModelWithAutoIncrement(long id) + { + this.Id = id; + this.Name = string.Concat("Name_", id.ToString()); + } + + public static void AssertIsEqual(ModelWithAutoIncrement actual, ModelWithAutoIncrement expected) + { + if (actual == null || expected == null) + { + Assert.That(actual == expected, Is.True); + return; + } + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.Name, Is.EqualTo(expected.Name)); + } + + public static ModelWithAutoIncrement Create(long id) + { + return new ModelWithAutoIncrement(id); + } + + public bool Equals(ModelWithAutoIncrement other) + { + if (object.ReferenceEquals(null, other)) + { + return false; + } + if (object.ReferenceEquals(this, other)) + { + return true; + } + if (other.Id == this.Id) + { + return object.Equals(other.Name, this.Name); + } + return false; + } + + public override bool Equals(object obj) + { + if (object.ReferenceEquals(null, obj)) + { + return false; + } + if (object.ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != typeof(ModelWithAutoIncrement)) + { + return false; + } + return this.Equals((ModelWithAutoIncrement)obj); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithSequence.cs b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithSequence.cs new file mode 100644 index 000000000..9aa10ccb0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/ModelWithSequence.cs @@ -0,0 +1,82 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.Common.Tests.Models{ + + public class ModelWithSequence + { + [Sequence("Gen_ModelWithSequence_Id"), AutoIncrement, ReturnOnInsert] + public long Id + { + get; + set; + } + + public string Name + { + get; + set; + } + + public ModelWithSequence() + { + } + + public ModelWithSequence(long id) + { + this.Id = id; + this.Name = string.Concat("Name_", id.ToString()); + } + + public static void AssertIsEqual(ModelWithSequence actual, ModelWithSequence expected) + { + if (actual == null || expected == null) + { + Assert.That(actual == expected, Is.True); + return; + } + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.Name, Is.EqualTo(expected.Name)); + } + + public static ModelWithSequence Create(long id) + { + return new ModelWithSequence(id); + } + + public bool Equals(ModelWithSequence other) + { + if (object.ReferenceEquals(null, other)) + { + return false; + } + if (object.ReferenceEquals(this, other)) + { + return true; + } + if (other.Id == this.Id) + { + return object.Equals(other.Name, this.Name); + } + return false; + } + + public override bool Equals(object obj) + { + if (object.ReferenceEquals(null, obj)) + { + return false; + } + if (object.ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != typeof(ModelWithSequence)) + { + return false; + } + return this.Equals((ModelWithSequence)obj); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/TaskQueue.cs b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/TaskQueue.cs index d565c86b9..2a850e8a6 100755 --- a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/TaskQueue.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.Models/TaskQueue.cs @@ -4,11 +4,12 @@ using ServiceStack.Text; using ServiceStack.DataAnnotations; -namespace ServiceStack.Common.Tests.Models{ +namespace ServiceStack.Common.Tests.Models +{ public class TaskQueue { - private readonly static ILog Log; + private static readonly ILog Log; public const int PriorityHigh = 2; @@ -115,13 +116,15 @@ public static void AssertIsEqual(TaskQueue actual, TaskQueue expected) public static TaskQueue Create(int id) { - TaskQueue taskQueue = new TaskQueue(); - taskQueue.ContentUrn = string.Concat("urn:track:", id); - taskQueue.CreatedDate = DateTime.Now; - taskQueue.Task = "Load"; - taskQueue.Status = "Pending"; - taskQueue.NoOfAttempts = 0; - return taskQueue; + var taskQueue = new TaskQueue + { + ContentUrn = string.Concat("urn:track:", id), + CreatedDate = DateTime.Now, + Task = "Load", + Status = "Pending", + NoOfAttempts = 0 + }; + return taskQueue; } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.OrmLite.FirebirdTests.csproj b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.OrmLite.FirebirdTests.csproj index 669c17043..26dbdff30 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.OrmLite.FirebirdTests.csproj +++ b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.OrmLite.FirebirdTests.csproj @@ -1,149 +1,16 @@ - - + - Debug - AnyCPU - 10.0.0 - 2.0 - {CB988768-7753-4EF2-8C06-6A74B384C78E} - Library - ServiceStack.OrmLite.FirebirdTests + net472 + ServiceStack.OrmLite.FirebirdTests + ServiceStack.OrmLite.FirebirdTests + default - - True - full - False - bin\Debug - DEBUG; - prompt - 4 - False - - - none - False - bin\Release - prompt - 4 - False - - - bin\Signed\ - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - ..\..\lib\FirebirdSql.Data.FirebirdClient.dll - - - - - - - - ..\..\lib\tests\nunit.framework.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - + + + + + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.OrmLite.FirebirdTests.vbproj b/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.OrmLite.FirebirdTests.vbproj deleted file mode 100644 index b5fbcae59..000000000 --- a/tests/ServiceStack.OrmLite.FirebirdTests/ServiceStack.OrmLite.FirebirdTests.vbproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {AF78749C-EDC0-4AA3-8F52-7F58B1F535C2} - Library - ServiceStack.OrmLite.FirebirdTests - ServiceStack.OrmLite.FirebirdTests - - - true - bin\Debug - prompt - false - - false - false - - - bin\Release - prompt - false - - false - false - - - - - - - - - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/ShipperExample.cs b/tests/ServiceStack.OrmLite.FirebirdTests/ShipperExample.cs index 4556f5f5a..919a04f9c 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/ShipperExample.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/ShipperExample.cs @@ -102,10 +102,11 @@ public void Shippers_UseCase() db.Insert(new Shipper { CompanyName = "Planes R Us", Phone = "555-PLANES", ShipperTypeId = planesTypeId }); db.Insert(new Shipper { CompanyName = "We do everything!", Phone = "555-UNICORNS", ShipperTypeId = planesTypeId }); - var trainsAreUs = db.SingleFmt("\"Type\" = {0}", trainsTypeId); + var trainsAreUs = db.Single("\"Type\" = @id", new { id = trainsTypeId }); Assert.That(trainsAreUs.CompanyName, Is.EqualTo("Trains R Us")); - Assert.That(db.SelectFmt("CompanyName = {0} OR Phone = {1}", "Trains R Us", "555-UNICORNS"), Has.Count.EqualTo(2)); - Assert.That(db.SelectFmt("\"Type\" = {0}", planesTypeId), Has.Count.EqualTo(2)); + Assert.That(db.Select("CompanyName = @company OR Phone = @phone", + new { company = "Trains R Us", phone = "555-UNICORNS" }), Has.Count.EqualTo(2)); + Assert.That(db.Select("\"Type\" = @id", new { id = planesTypeId }), Has.Count.EqualTo(2)); //Lets update a record trainsAreUs.Phone = "666-TRAINS"; @@ -122,11 +123,11 @@ public void Shippers_UseCase() //Performing custom queries //Select only a subset from the table - var partialColumns = db.SelectFmt(typeof (Shipper), "\"Type\" = {0}", planesTypeId); + var partialColumns = db.Select(typeof (Shipper), "\"Type\" = @id", new { id = planesTypeId }); Assert.That(partialColumns, Has.Count.EqualTo(2)); //Select into another POCO class that matches sql - var rows = db.SelectFmt( + var rows = db.Select( "SELECT \"Type\" as ShipperTypeId, COUNT(*) AS Total FROM ShippersT GROUP BY \"Type\" ORDER BY COUNT(*)"); Assert.That(rows, Has.Count.EqualTo(2)); diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SchemaUseCase.cs b/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SchemaUseCase.cs index 329c44a98..a29c7173f 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SchemaUseCase.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SchemaUseCase.cs @@ -60,7 +60,7 @@ public void Can_Perform_CRUD_Operations_On_Table_With_Schema() var lastInsertId = db.LastInsertId(); Assert.That(lastInsertId, Is.GreaterThan(0)); - var rowsB = db.SelectFmt("Name = {0}", "B"); + var rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(2)); var rowIds = rowsB.ConvertAll(x => x.Id); @@ -68,7 +68,7 @@ public void Can_Perform_CRUD_Operations_On_Table_With_Schema() rowsB.ForEach(x => db.Delete(x)); - rowsB = db.SelectFmt("Name = {0}", "B"); + rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(0)); var rowsLeft = db.Select(); diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SimpleUseCase.cs b/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SimpleUseCase.cs index 02cdef5ac..3b1d89d30 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SimpleUseCase.cs +++ b/tests/ServiceStack.OrmLite.FirebirdTests/UseCase/SimpleUseCase.cs @@ -10,7 +10,7 @@ namespace ServiceStack.OrmLite.FirebirdTests [TestFixture] public class SimpleUseCase { - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { //Inject your database provider here @@ -45,7 +45,7 @@ public void Simple_CRUD_example() db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - var rowsB = db.SelectFmt("Name = {0}", "B"); + var rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(2)); @@ -54,7 +54,7 @@ public void Simple_CRUD_example() rowsB.ForEach(x => db.Delete(x)); - rowsB = db.SelectFmt("Name = {0}", "B"); + rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(0)); var rowsLeft = db.Select(); @@ -66,7 +66,7 @@ public void Simple_CRUD_example() Guid g = Guid.NewGuid(); db.Insert(new GuidId { Id = g }); - GuidId gid = db.SingleFmt("Id = {0}", g); + GuidId gid = db.SingleById(g); Assert.That(g == gid.Id); } } diff --git a/tests/ServiceStack.OrmLite.FirebirdTests/app.config b/tests/ServiceStack.OrmLite.FirebirdTests/app.config index bad02dc43..ea8a0fbd2 100644 --- a/tests/ServiceStack.OrmLite.FirebirdTests/app.config +++ b/tests/ServiceStack.OrmLite.FirebirdTests/app.config @@ -1,9 +1,25 @@ - + + - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/BooleanTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/BooleanTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/BooleanTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/BooleanTests.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/CustomSqlTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/CustomSqlTests.cs new file mode 100644 index 000000000..3fcf036f7 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/CustomSqlTests.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + public class LetterFrequency + { + [AutoIncrement] + public int Id { get; set; } + + public string Letter { get; set; } + } + + [TestFixture] + public class CustomSqlTests : OrmLiteTestBase + { + string spSql = @"DROP PROCEDURE IF EXISTS spSearchLetters; + CREATE PROCEDURE spSearchLetters (IN pLetter varchar(10), OUT pTotal int) + BEGIN + SELECT COUNT(*) FROM LetterFrequency WHERE Letter = pLetter INTO pTotal; + SELECT * FROM LetterFrequency WHERE Letter = pLetter; + END"; + + [Test] + public void Can_execute_stored_procedure_using_SqlList_with_out_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); + db.InsertAll(rows); + + db.ExecuteSql(spSql); + + IDbDataParameter pTotal = null; + var results = db.SqlList("spSearchLetters", + cmd => + { + cmd.CommandType = CommandType.StoredProcedure; + cmd.AddParam("pLetter", "C"); + pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); + }); + + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(pTotal.Value, Is.EqualTo(3)); + } + + [Test] + public void Can_execute_stored_procedure_using_SqlProc_with_out_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); + db.InsertAll(rows); + + db.ExecuteSql(spSql); + + var cmd = db.SqlProc("spSearchLetters", new { pLetter = "C" }); + + Assert.That(((OrmLiteCommand)cmd).IsDisposed, Is.False); + + var pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); + var results = cmd.ConvertToList(); + + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(pTotal.Value, Is.EqualTo(3)); + } + + public class MySqlExecFilter : OrmLiteExecFilter + { + public override IEnumerable ExecLazy(IDbConnection dbConn, Func> filter) + { + var dbCmd = CreateCommand(dbConn); + //var mysqlCmd = (MySqlCommand) dbCmd.ToDbCommand(); + + try + { + var results = filter(dbCmd); + + foreach (var item in results) + { + yield return item; + } + } + finally + { + DisposeCommand(dbCmd, dbConn); + } + } + } + + // [Test] + // public void Can_access_MySqlConnection_in_ExecFilter() + // { + // MySqlDialect.Instance.ExecFilter = new MySqlExecFilter(); + // + // using var db = OpenDbConnection(); + // db.DropAndCreateTable(); + // + // var results = db.SelectLazy().ToList(); + // } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/DateTimeColumnTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/DateTimeColumnTest.cs new file mode 100644 index 000000000..959ab0a53 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/DateTimeColumnTest.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.OrmLite.Legacy; +using ServiceStack.OrmLite.MySql.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + [TestFixture] + public class DateTimeColumnTest + : OrmLiteTestBase + { + [Test] + public void Can_create_table_containing_DateTime_column() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_store_DateTime_Value() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + + var obj = new Analyze { + Id = 1, + Date = DateTime.Now, + Url = "http://www.google.com" + }; + + db.Save(obj); + } + + [Test] + public void Can_store_and_retrieve_DateTime_Value() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + + var obj = new Analyze { + Id = 1, + Date = DateTime.Now, + Url = "http://www.google.com" + }; + + db.Save(obj); + + var id = (int)db.LastInsertId(); + var target = db.SingleById(id); + + Assert.That(target, Is.Not.Null); + Assert.That(target.Id, Is.EqualTo(id)); + Assert.That(target.Date, Is.EqualTo(obj.Date).Within(TimeSpan.FromSeconds(1))); + Assert.That(target.Url, Is.EqualTo(obj.Url)); + } + + [Test] + public void Can_change_DateTime_precision() + { + using var db = OpenDbConnection(); +#if MYSQLCONNECTOR + if (MySqlConnectorDialect.Provider.GetConverter(typeof(DateTime)) is MySqlDateTimeConverterBase dateConverter) + { + dateConverter.Precision = 3; + } +#else + if (MySqlDialect.Provider.GetConverter(typeof(DateTime)) is MySqlDateTimeConverterBase dateConverter) + { + dateConverter.Precision = 3; + } +#endif + + OrmLiteUtils.PrintSql(); + db.CreateTable(true); + + var obj = new Analyze { + Id = 1, + Date = DateTime.Now, + Url = "http://www.google.com" + }; + + db.Save(obj); + + var id = (int)db.LastInsertId(); + var target = db.SingleById(id); + target.PrintDump(); + + var q = db.From() + .Where(x => x.Date >= DateTime.Now.Date); + var results = db.Select(q); + Assert.That(results.Count, Is.EqualTo(1)); + results.PrintDump(); + + results = db.SelectFmt("AnalyzeDate >= {0}", DateTime.Now.AddDays(-1)); + results.PrintDump(); + } + + [Test] + public void Can_query_DateTime_column_in_select_without_any_format_parameter() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + var obj = new Analyze + { + Id = 1, + Date = DateTime.Now, + Url = "http://www.google.com" + }; + db.Save(obj); + + var q=db.From().Select(i => i.Date); + var sql = q.ToMergedParamsSelectStatement(); + var val= db.Select(q).First(); + Assert.That(obj.Date,Is.EqualTo(val).Within(TimeSpan.FromSeconds(1))); + } + + [Test] + public void Can_query_DateTime_column_in_select_with_format_parameter() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + var obj = new Analyze + { + Id = 1, + Date = DateTime.Now, + Url = "http://www.google.com" + }; + db.Save(obj); + var q = db.From().Select(i => i.Date.ToString("%Y-%m-%d %H:%i:%s")); + var sql = q.ToMergedParamsSelectStatement(); + var val = db.Select(q).First(); + Assert.That(obj.Date, Is.EqualTo(DateTime.Parse(val)).Within(TimeSpan.FromSeconds(1))); + } + + [Test] + public void Can_query_DateTime_column_in_where_with_format_parameter() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + var obj = new Analyze + { + Id = 1, + Date = DateTime.Now, + Url = "http://www.google.com" + }; + var yesterdayString = obj.Date.AddDays(-1).ToString("yyyy-MM-dd"); + var todayString = obj.Date.ToString("yyyy-MM-dd"); + db.Save(obj); + var q = db.From().Where(i=>i.Date.ToString("%Y-%m-%d")== yesterdayString); + var results = db.Select(q); + var sql = q.ToMergedParamsSelectStatement(); + Assert.That(results.Count, Is.EqualTo(0)); + + q = db.From().Where(i => i.Date.ToString("%Y-%m-%d") == todayString); + results = db.Select(q); + sql = q.ToMergedParamsSelectStatement(); + Assert.That(results.Count, Is.EqualTo(1)); + + var id = (int)db.LastInsertId(); + var target = db.SingleById(id); + Assert.That(target, Is.Not.Null); + Assert.That(target.Id, Is.EqualTo(id)); + Assert.That(target.Date, Is.EqualTo(obj.Date).Within(TimeSpan.FromSeconds(1))); + Assert.That(target.Url, Is.EqualTo(obj.Url)); + } + + [Test] + public void Can_query_DateTime_column_in_select_and_where_with_format_parameter() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + var obj = new Analyze + { + Id = 1, + Date = DateTime.Now, + Url = "http://www.google.com" + }; + var yesterdayString = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd"); + var todayString = DateTime.Now.ToString("yyyy-MM-dd"); + db.Save(obj); + var q = db.From().Where(i => i.Date.ToString("%Y-%m-%d") == yesterdayString).Select(i=>i.Date.ToString("%Y-%m-%d")); + var results = db.Select(q); + var sql = q.ToMergedParamsSelectStatement(); + Assert.That(results.Count, Is.EqualTo(0)); + + q = db.From().Where(i => i.Date.ToString() == yesterdayString).Select(i => i.Date.ToString("%Y-%m-%d")); + results = db.Select(q); + sql = q.ToMergedParamsSelectStatement(); + Assert.That(results.Count, Is.EqualTo(0)); + + q = db.From().Where(i => i.Date.ToString("%Y-%m-%d") == todayString).Select(i => i.Date.ToString("%Y-%m-%d")); + results = db.Select(q); + sql = q.ToMergedParamsSelectStatement(); + Assert.That(results.Count, Is.EqualTo(1)); + + var target = results.First(); + Assert.That(target, Is.Not.Null); + Assert.That(target, Is.EqualTo(todayString)); + } + + /// + /// Provided by RyogoNA in issue #38 https://github.com/ServiceStack/ServiceStack.OrmLite/issues/38#issuecomment-4625178 + /// + [Alias("Analyzes")] + public class Analyze : IHasId + { + [AutoIncrement] + [PrimaryKey] + public int Id + { + get; + set; + } + [Alias("AnalyzeDate")] + public DateTime Date + { + get; + set; + } + public string Url + { + get; + set; + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/EnumTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/EnumTests.cs new file mode 100644 index 000000000..8884a832b --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/EnumTests.cs @@ -0,0 +1,274 @@ +using System.Linq; +using System.Runtime.Serialization; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + public class EnumTests : OrmLiteTestBase + { + [Test] + public void CanCreateTable() + { + OpenDbConnection().CreateTable(true); + } + + [Test] + public void CanStoreEnumValue() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + } + } + + [Test] + public void CanGetEnumValue() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; + con.Save(obj); + var target = con.SingleById(obj.Id); + Assert.AreEqual(obj.Id, target.Id); + Assert.AreEqual(obj.EnumValue, target.EnumValue); + } + } + + [Test] + public void CanCreateTableNullableEnum() + { + OpenDbConnection().CreateTable(true); + } + + [Test] + public void CanStoreNullableEnumValue() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithNullableEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + } + } + + [Test] + public void CanGetNullableEnumValue() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new TypeWithNullableEnum { Id = 1, EnumValue = SomeEnum.Value1 }; + con.Save(obj); + var target = con.SingleById(obj.Id); + Assert.AreEqual(obj.Id, target.Id); + Assert.AreEqual(obj.EnumValue, target.EnumValue); + } + } + + [Test] + public void CanQueryByEnumValue_using_select_with_expression() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Select(q => q.EnumValue == SomeEnum.Value1); + + Assert.AreEqual(2, target.Count()); + } + } + + [Test] + public void CanQueryByEnumValue_using_select_with_string() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Select("EnumValue = @value", new { value = SomeEnum.Value1 }); + + Assert.AreEqual(2, target.Count()); + } + } + + [Test] + public void CanQueryByEnumValue_using_where_with_AnonType() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Where(new { EnumValue = SomeEnum.Value1 }); + + Assert.AreEqual(2, target.Count()); + } + } + + [Test] + public void CanQueryByNullableEnumValue_using_where_with_AnonType() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithNullableEnum { Id = 1, EnumValue = SomeEnum.Value1, IntEnum = SomeIntEnum.One }); + con.Save(new TypeWithNullableEnum { Id = 2, EnumValue = SomeEnum.Value1, IntEnum = SomeIntEnum.One }); + con.Save(new TypeWithNullableEnum { Id = 3, EnumValue = SomeEnum.Value2, IntEnum = SomeIntEnum.Two }); + + var target = con.Where(new { EnumValue = SomeEnum.Value1 }); + var enumInt = con.Where(new { IntEnum = SomeIntEnum.One }); + + Assert.AreEqual(2, target.Count); + Assert.AreEqual(2, enumInt.Count); + } + } + + [Test] + public void CanSaveNullableEnum_with_specific_id_select_with_anon_type() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var myObj = new MyObj(); + myObj.Id = 1; + myObj.Test = MyEnum.One; + db.Insert(myObj); + + myObj = db.Single(new { Id = 1 }); + + Assert.That(myObj.Id, Is.EqualTo(1)); + Assert.That(myObj.Test, Is.Not.EqualTo(null)); + Assert.That(myObj.Test, Is.EqualTo(MyEnum.One)); + } + } + + [Test] + public void CanSaveNullableEnum_with_specific_id_select_with_type() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var exists = db.SingleById(1); + if (exists != null) + { + db.DeleteById(1); + } + } + + using (var con = OpenDbConnection()) + { + + var myObj = new MyObj(); + myObj.Id = 1; + myObj.Test = MyEnum.One; + con.Insert(myObj); + + myObj = con.Single(x => x.Id == 1); + + Assert.That(myObj.Id, Is.EqualTo(1)); + Assert.That(myObj.Test, Is.Not.EqualTo(null)); + Assert.That(myObj.Test, Is.EqualTo(MyEnum.One)); + } + } + + [Test] + public void ShouldUseEnumName_in_Sql_TableAlias() + { + using var db = OpenDbConnection(); + var q = db.From(); + var stateType = StateType.完好; + q.Or((x) => Sql.TableAlias(x.State, nameof(LinkResult)) == StateType.离线); + q.Or((x) => x.State == StateType.离线); + q.Or((x) => Sql.TableAlias(x.State, nameof(LinkResult)) == stateType); + q.And((x) => Sql.TableAlias(x.Age, nameof(LinkResult)) > 18); + q.And((x) => Sql.TableAlias(x.SomeIntEnum, nameof(LinkResult)) == SomeIntEnum.One); + q.And((x) => x.SomeIntEnum== SomeIntEnum.One); + + var sql = q.ToMergedParamsSelectStatement(); + Assert.That(q.Params[0].Value, Is.EqualTo(nameof(StateType.离线))); + Assert.That(q.Params[1].Value, Is.EqualTo(nameof(StateType.离线))); + Assert.That(q.Params[2].Value, Is.EqualTo(nameof(StateType.完好))); + Assert.That(q.Params[3].Value, Is.EqualTo(18)); + Assert.That(q.Params[4].Value, Is.EqualTo((int)SomeIntEnum.One)); + Assert.That(q.Params[5].Value, Is.EqualTo((int)SomeIntEnum.One)); + } + } + + public class EntityMonitor + { + [Alias("文1")] + public StateType State { get; set; } + + public int Age { get; set; } + + public SomeIntEnum SomeIntEnum { get; set; } + } + + public class LinkResult : EntityMonitor + { + + } + + public class ChnStateResult : EntityMonitor + { + + } + + public enum StateType + { + 完好, + 离线 + } + + public enum SomeEnum : long + { + Value1 = 2147483648, + Value2, + Value3 + } + + [EnumAsInt] + public enum SomeIntEnum + { + Zero = 0, + One = 1, + Two = 2 + } + + [EnumAsInt] + public enum MyEnum : int + { + Zero = 0, + One = 1 + } + + public class MyObj + { + public int Id { get; set; } + public MyEnum? Test { get; set; } + } + + public class TypeWithEnum + { + public int Id { get; set; } + public SomeEnum EnumValue { get; set; } + public SomeIntEnum IntEnum { get; set; } + } + + public class TypeWithNullableEnum + { + public int Id { get; set; } + public SomeEnum? EnumValue { get; set; } + public SomeIntEnum? IntEnum { get; set; } + } +} diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/AdditiveExpressionsTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/AdditiveExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/AdditiveExpressionsTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/AdditiveExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/Author.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/Author.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/Author.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/Author.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/AuthorUseCase.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/AuthorUseCase.cs new file mode 100644 index 000000000..99ec7f51d --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/AuthorUseCase.cs @@ -0,0 +1,360 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.MySql.Tests.Expressions +{ + public class AuthorUseCase : OrmLiteTestBase + { + private List authors; + + public AuthorUseCase() + { + authors = new List(); + authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); + authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); + authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); + authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); + authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); + authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); + authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); + authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); + authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); + authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); + authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); + authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); + authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); + authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico", LastActivity = DateTime.Today }); + } + + [SetUp] + public void Setup() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.SaveAll(authors); + } + } + + [Test] + public void AuthorUsesCases() + { + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + + using (var db = OpenDbConnection()) + { + int year = DateTime.Today.AddYears(-20).Year; + var lastDay = new DateTime(year, 12, 31); + int expected = 5; + + ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + List result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(db.From().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + Assert.AreEqual(expected, result.Count); + Author a = new Author() { Birthday = lastDay }; + result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); + Assert.AreEqual(expected, result.Count); + + // select authors from London, Berlin and Madrid : 6 + expected = 6; + //Sql.In can take params object[] + var city = "Berlin"; + ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); + Assert.AreEqual(expected, result.Count); + + // select authors from Bogota and Cartagena : 7 + expected = 7; + //... or Sql.In can take List + city = "Bogota"; + List cities = new List(); + cities.Add(city); + cities.Add("Cartagena"); + ev.Where().Where(rn => Sql.In(rn.City, cities)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); + Assert.AreEqual(expected, result.Count); + + + // select authors which name starts with A + expected = 3; + ev.Where().Where(rn => rn.Name.StartsWith("A")); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.StartsWith("A")); + Assert.AreEqual(expected, result.Count); + + // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) + expected = 3; + var name = "GARZON"; + ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); + Assert.AreEqual(expected, result.Count); + + // select authors which name ends with garzon + //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters + //in the string. + //An underscore ("_") in the LIKE pattern matches any single character in the string. + //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). + expected = 3; + ev.Where().Where(rn => rn.Name.EndsWith("garzon")); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.EndsWith("garzon")); + Assert.AreEqual(expected, result.Count); + + + // select authors which name contains Benedict + expected = 2; + name = "Benedict"; + ev.Where().Where(rn => rn.Name.Contains(name)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.Contains("Benedict")); + Assert.AreEqual(expected, result.Count); + a.Name = name; + result = db.Select(rn => rn.Name.Contains(a.Name)); + Assert.AreEqual(expected, result.Count); + + + // select authors with Earnings <= 50 + expected = 3; + var earnings = 50; + ev.Where().Where(rn => rn.Earnings <= earnings); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Earnings <= 50); + Assert.AreEqual(expected, result.Count); + + // select authors with Rate = 10 and city=Mexio + expected = 1; + city = "Mexico"; + ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); + Assert.AreEqual(expected, result.Count); + + a.City = city; + result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); + Assert.AreEqual(expected, result.Count); + + // enough selecting, lets update; + // set Active=false where rate =0 + expected = 2; + var rate = 0; + ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); + var rows = db.UpdateOnlyFields(new Author() { Active = false }, ev); + Assert.AreEqual(expected, rows); + + // insert values only in Id, Name, Birthday, Rate and Active fields + expected = 4; + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + ev.Where().Where(rn => !rn.Active); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + + //update comment for City == null + expected = 2; + ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); + rows = db.UpdateOnlyFields(new Author() { Comments = "No comments" }, ev); + Assert.AreEqual(expected, rows); + + // delete where City is null + expected = 2; + rows = db.Delete(ev); + Assert.AreEqual(expected, rows); + + + // lets select all records ordered by Rate Descending and Name Ascending + expected = 14; + ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + var author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel", author.Name); + + // select only first 5 rows .... + expected = 5; + ev.Limit(5); // note: order is the same as in the last sentence + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + + + // and finally lets select only Name and City (name will be "UPPERCASED" ) + + ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); + Console.WriteLine(ev.SelectExpression); + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); + Console.WriteLine(ev.SelectExpression); + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + //paging : + ev.Limit(0, 4);// first page, page size=4; + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + ev.Limit(4, 4);// second page + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Jorge Garzon".ToUpper(), author.Name); + + ev.Limit(8, 4);// third page + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Rodger Contreras".ToUpper(), author.Name); + + // select distinct.. + ev.Limit().OrderBy(); // clear limit, clear order for postres + ev.SelectDistinct(r => r.City); + expected = 6; + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + + ev.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); + result = db.Select(ev); + var expectedResult = authors.Max(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + ev.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); + result = db.Select(ev); + expectedResult = authors.Max(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + var r1 = db.Single(ev); + Assert.AreEqual(expectedResult, r1.Birthday); + + var r2 = db.Scalar(e => Sql.Max(e.Birthday)); + Assert.AreEqual(expectedResult, r2); + + ev.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); + result = db.Select(ev); + expectedResult = authors.Min(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + ev.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); + result = db.Select(ev); + expectedResult = authors.Min(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + + ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + result = db.Select(ev); + var expectedStringResult = "Berlin"; + Assert.AreEqual(expectedStringResult, result[0].City); + + ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + result = db.Select(ev); + expectedStringResult = "Berlin"; + Assert.AreEqual(expectedStringResult, result[0].City); + + r1 = db.Single(ev); + Assert.AreEqual(expectedStringResult, r1.City); + + var expectedDecimal = authors.Max(e => e.Earnings); + Decimal? r3 = db.Scalar(e => Sql.Max(e.Earnings)); + Assert.AreEqual(expectedDecimal, r3.Value); + + var expectedString = authors.Max(e => e.Name); + string r4 = db.Scalar(e => Sql.Max(e.Name)); + Assert.AreEqual(expectedString, r4); + + var expectedDate = authors.Max(e => e.LastActivity); + DateTime? r5 = db.Scalar(e => Sql.Max(e.LastActivity)); + Assert.AreEqual(expectedDate, r5); + + var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); + DateTime? r51 = db.Scalar( + e => Sql.Max(e.LastActivity), + e => e.City == "Bogota"); + Assert.AreEqual(expectedDate51, r51); + + try + { + var expectedBool = authors.Max(e => e.Active); + bool r6 = db.Scalar(e => Sql.Max(e.Active)); + Assert.AreEqual(expectedBool, r6); + } + catch (Exception) + { + //???? + //if (dialect.Name == "PostgreSQL") + // Console.WriteLine("OK PostgreSQL: " + e.Message); + //else + // Console.WriteLine("************** FAILED *************** " + e.Message); + } + + // Tests for predicate overloads that make use of the expression visitor + author = db.Single(q => q.Name == "Jorge Garzon"); + + author = db.Single(q => q.Name == "Does not exist"); + Assert.IsNull(author); + + author = db.Single(q => q.City == "Bogota"); + Assert.AreEqual("Angel Colmenares", author.Name); + + a.City = "Bogota"; + author = db.Single(q => q.City == a.City); + Assert.AreEqual("Angel Colmenares", author.Name); + + // count test + + var expectedCount = authors.Count(); + long r7 = db.Scalar(e => Sql.Count(e.Id)); + Assert.AreEqual(expectedCount, r7); + + expectedCount = authors.Count(e => e.City == "Bogota"); + r7 = db.Scalar( + e => Sql.Count(e.Id), + e => e.City == "Bogota"); + Assert.AreEqual(expectedCount, r7); + + ev.Update();// all fields will be updated + // select and update + expected = 1; + var rr = db.Single(rn => rn.Name == "Luis garzon"); + rr.City = "Madrid"; + rr.Comments = "Updated"; + ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated + rows = db.UpdateOnlyFields(rr, ev); // == dbCmd.Update(rr) but it returns void + Assert.AreEqual(expected, rows); + + expected = 0; + ev.Where().Where(r => r.City == "Ciudad Gotica"); + rows = db.UpdateOnlyFields(rr, ev); + Assert.AreEqual(expected, rows); + + expected = db.Select(x => x.City == "Madrid").Count; + author = new Author() { Active = false }; + rows = db.UpdateOnlyFields(author, x => x.Active, x => x.City == "Madrid"); + Assert.AreEqual(expected, rows); + + expected = db.Select(x => x.Active == false).Count; + rows = db.Delete(x => x.Active == false); + Assert.AreEqual(expected, rows); + } + } + } +} diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/ConditionalExpressionTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/ConditionalExpressionTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/ConditionalExpressionTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/ConditionalExpressionTest.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/EqualityExpressionsTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/EqualityExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/EqualityExpressionsTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/EqualityExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/ExpressionsTestBase.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/ExpressionsTestBase.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/ExpressionsTestBase.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/ExpressionsTestBase.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/LogicalExpressionsTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/LogicalExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/LogicalExpressionsTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/LogicalExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/MultiplicativeExpressionsTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/MultiplicativeExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/MultiplicativeExpressionsTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/MultiplicativeExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/OrmLiteCountTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/OrmLiteCountTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/OrmLiteCountTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/OrmLiteCountTests.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/PrimaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/PrimaryExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/PrimaryExpressionsTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/PrimaryExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/RelationalExpressionsTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/RelationalExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/RelationalExpressionsTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/RelationalExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/StringFunctionTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/StringFunctionTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/StringFunctionTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/StringFunctionTests.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/TestType.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/TestType.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/TestType.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/TestType.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Expressions/UnaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Expressions/UnaryExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/Expressions/UnaryExpressionsTest.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Expressions/UnaryExpressionsTest.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/ForeignKeyAttributeTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/ForeignKeyAttributeTests.cs new file mode 100644 index 000000000..1808d0ec4 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/ForeignKeyAttributeTests.cs @@ -0,0 +1,179 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + [TestFixture] + public class ForeignKeyAttributeTests : OrmLiteTestBase + { + public ForeignKeyAttributeTests() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + } + } + + [Test] + public void CanCreateSimpleForeignKey() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteCascade() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void CascadesOnDelete() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + db.Save(new ReferencedType { Id = 1 }); + db.Save(new TypeWithOnDeleteCascade { RefId = 1 }); + + Assert.AreEqual(1, db.Select().Count); + Assert.AreEqual(1, db.Select().Count); + + db.Delete(r => r.Id == 1); + + Assert.AreEqual(0, db.Select().Count); + Assert.AreEqual(0, db.Select().Count); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteNoAction() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteRestrict() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [NUnit.Framework.Ignore("Not supported in MySQL")] + [Test] + public void CanCreateForeignWithOnDeleteSetDefault() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteSetNull() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + } + + public class ReferencedType + { + public int Id { get; set; } + } + + + public class TypeWithSimpleForeignKey + { + [AutoIncrement] + public int Id { get; set; } + [References(typeof(ReferencedType))] + public int RefId { get; set; } + } + + public class TypeWithOnDeleteCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteAndUpdateCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteNoAction + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteRestrict + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteSetDefault + { + [AutoIncrement] + public int Id { get; set; } + + [Default(typeof(int), "17")] + [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT")] + public int RefId { get; set; } + } + + public class TypeWithOnDeleteSetNull + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL")] + public int? RefId { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/Issues/CustomMappingIssue.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Issues/CustomMappingIssue.cs new file mode 100644 index 000000000..479978da9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/Issues/CustomMappingIssue.cs @@ -0,0 +1,100 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Logging; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.MySql.Tests.Issues +{ + [TestFixture, Explicit] + public class CustomMappingIssue + : OrmLiteTestBase + { + private string CreateChecksTableSql = @" +CREATE TABLE checks ( + check_id bigint(11) NOT NULL AUTO_INCREMENT, + room_state_id bigint(11) NOT NULL DEFAULT 0, + entry_stamp datetime DEFAULT NULL, + student_id int(11) NOT NULL DEFAULT 0, + reason varchar(60) DEFAULT NULL, + comments text DEFAULT NULL, + check_type_id bigint(20) NOT NULL DEFAULT 0, + check_dt datetime DEFAULT NULL, + grace tinyint(4) UNSIGNED NOT NULL DEFAULT 0, + curfew_dt datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + excused_by int(11) NOT NULL DEFAULT 0, + status char(1) NOT NULL DEFAULT '', + points int(11) NOT NULL DEFAULT 0, + check_class char(2) NOT NULL DEFAULT '', + leave_id int(11) NOT NULL DEFAULT 0, + night_of date NOT NULL DEFAULT '0000-00-00', + violation_dt datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + excused_reason varchar(255) NOT NULL DEFAULT '', + excused_dt datetime DEFAULT '0000-00-00 00:00:00', + imported tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (check_id), + INDEX check_class (check_class), + INDEX check_dt (check_dt), + INDEX check_type_id (check_type_id), + INDEX excused_by (excused_by), + INDEX leave_id (leave_id), + INDEX night_of (night_of), + INDEX status (status), + INDEX student_id (student_id) +)"; + + [Alias("checks")] + public class Check + { + [AutoIncrement] + [PrimaryKey] + public long check_id { get; set; } + public long room_state_id { get; set; } + public DateTime? entry_stamp { get; set; } + public int student_id { get; set; } + public string reason { get; set; } + public string comments { get; set; } + public long check_type_id { get; set; } + public DateTime? check_dt { get; set; } + public byte grace { get; set; } + public DateTime curfew_dt { get; set; } + public int excused_by { get; set; } + public string status { get; set; } + public int points { get; set; } + public string check_class { get; set; } + public int leave_id { get; set; } + public DateTime night_of { get; set; } + public DateTime violation_dt { get; set; } + public string excused_reason { get; set; } + public DateTime? excused_dt { get; set; } + public bool imported { get; set; } //tinyint(1) returned as `bool` + } + + [Test] + public void Does_map_to_checks_table() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + using (var db = OpenDbConnection()) + { + db.DropTable(); + + db.ExecuteSql(CreateChecksTableSql); + + db.Insert(new Check + { + room_state_id = 1, + student_id = 2, + reason = "reason", + grace = 1, + imported = false, + status = "s", + check_class = "ch", + excused_reason = "excused_reason", + }); + + db.Select().PrintDump(); + } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/Issues/SelectExpressionIssues.cs b/tests/ServiceStack.OrmLite.MySql.Tests/Issues/SelectExpressionIssues.cs similarity index 91% rename from src/ServiceStack.OrmLite.MySql.Tests/Issues/SelectExpressionIssues.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/Issues/SelectExpressionIssues.cs index b01ee51ec..512a3d122 100644 --- a/src/ServiceStack.OrmLite.MySql.Tests/Issues/SelectExpressionIssues.cs +++ b/tests/ServiceStack.OrmLite.MySql.Tests/Issues/SelectExpressionIssues.cs @@ -65,10 +65,6 @@ public void Does_select_using_tags_collection() contacts = db.Select("Tags & @has = @has", new { has = AvailableFlags.glam }); db.GetLastSql().Print(); contacts.PrintDump(); - - contacts = db.SelectFmt("Tags & {0} = {0}", (int)AvailableFlags.glam); - db.GetLastSql().Print(); - contacts.PrintDump(); } } } diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/LocalizationTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/LocalizationTests.cs new file mode 100644 index 000000000..35dca5225 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/LocalizationTests.cs @@ -0,0 +1,63 @@ +using System; +using System.Globalization; +using System.Threading; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + [TestFixture] + public class LocalizationTests + : OrmLiteTestBase + { + private readonly CultureInfo CurrentCulture = Thread.CurrentThread.CurrentCulture; + private readonly CultureInfo CurrentUICulture = Thread.CurrentThread.CurrentUICulture; + + public LocalizationTests() + { + Thread.CurrentThread.CurrentCulture = new CultureInfo("vi-VN"); + Thread.CurrentThread.CurrentUICulture = new CultureInfo("vi-VN"); + + OrmLiteConfig.DialectProvider = MySqlConfig.DialectProvider; + } + + [OneTimeTearDown] + public void TestFixtureTearDown() + { + Thread.CurrentThread.CurrentCulture = CurrentCulture; + Thread.CurrentThread.CurrentUICulture = CurrentUICulture; + } + + public class Point + { + [AutoIncrement] + public int Id { get; set; } + public short Width { get; set; } + public float Height { get; set; } + public double Top { get; set; } + public decimal Left { get; set; } + } + + [Test] + public void Can_query_using_float_in_alernate_culuture() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + db.Insert(new Point { Width = 4, Height = 1.123f, Top = 3.456d, Left = 2.345m}); + + var points = db.Select("Height=@height", new { height = 1.123f }); + + Console.WriteLine(points.Dump()); + + Assert.That(points[0].Width, Is.EqualTo(4)); + Assert.That(points[0].Height, Is.EqualTo(1.123f)); + Assert.That(points[0].Top, Is.EqualTo(3.456d)); + Assert.That(points[0].Left, Is.EqualTo(2.345m)); + } + } + + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/MySqlAdminTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/MySqlAdminTests.cs similarity index 92% rename from src/ServiceStack.OrmLite.MySql.Tests/MySqlAdminTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/MySqlAdminTests.cs index ac89fc9b2..180f13c38 100644 --- a/src/ServiceStack.OrmLite.MySql.Tests/MySqlAdminTests.cs +++ b/tests/ServiceStack.OrmLite.MySql.Tests/MySqlAdminTests.cs @@ -25,7 +25,7 @@ public void Can_describe_a_table() { db.DropAndCreateTable(); - var info = db.SqlList("DESCRIBE author"); + var info = db.SqlList("DESCRIBE Author"); info.PrintDump(); } diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteBasicPersistenceProviderTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteBasicPersistenceProviderTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteBasicPersistenceProviderTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteBasicPersistenceProviderTests.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteComplexTypesTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteComplexTypesTests.cs similarity index 84% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteComplexTypesTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteComplexTypesTests.cs index 81fb0381f..0a99700eb 100644 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteComplexTypesTests.cs +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteComplexTypesTests.cs @@ -1,5 +1,4 @@ using System; -using System.Configuration; using System.Linq; using NUnit.Framework; using ServiceStack.Common.Tests.Models; @@ -10,13 +9,9 @@ namespace ServiceStack.OrmLite.MySql.Tests [TestFixture] public class OrmLiteComplexTypesTests : OrmLiteTestBase { - [TestFixtureSetUp] - public void TestFixtureSetUp() + public OrmLiteComplexTypesTests() { LogManager.LogFactory = new ConsoleLogFactory(); - - OrmLiteConfig.DialectProvider = MySqlDialectProvider.Instance; - ConnectionString = ConfigurationManager.ConnectionStrings["testDb"].ConnectionString; } [Test] diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteConnectionTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteConnectionTests.cs similarity index 97% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteConnectionTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteConnectionTests.cs index dc118ccc1..59ac272f9 100644 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteConnectionTests.cs +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteConnectionTests.cs @@ -6,7 +6,7 @@ namespace ServiceStack.OrmLite.MySql.Tests public class OrmLiteConnectionTests : OrmLiteTestBase { - [Test][Ignore] + // [Test] public void Can_create_connection_to_blank_database() { var connString = @"C:\Projects\PoToPe\trunk\website\src\Mflow.Intranet\Mflow.Intranet\App_Data\Exports\2009-10\MonthlySnapshot.mdf"; diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableTests.cs new file mode 100644 index 000000000..78c8355d0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableTests.cs @@ -0,0 +1,242 @@ +using System; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.MySql.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + public class MaxStringTest + { + public int Id { get; set; } + + [StringLength(int.MaxValue)] + public string MaxText { get; set; } + + [Text] + public string Text { get; set; } + + [CustomField("MEDIUMTEXT")] + public string MediumText { get; set; } + } + + [TestFixture] + public class OrmLiteCreateTableTests + : OrmLiteTestBase + { + [Test] + public void Can_create_table_with_MaxString_and_Custom_MediumText() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + //var sql = db.GetLastSql(); + //Assert.That(sql, Is.StringContaining("`MaxText` LONGTEXT NULL")); + //Assert.That(sql, Is.StringContaining("`MediumText` MEDIUMTEXT NULL")); + } + + [Test] + public void Can_create_ModelWithIdOnly_table() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_create_ModelWithOnlyStringFields_table() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_create_ModelWithLongIdAndStringFields_table() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_create_ModelWithFieldsOfDifferentTypes_table() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_preserve_ModelWithIdOnly_table() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + + db.Insert(new ModelWithIdOnly(1)); + db.Insert(new ModelWithIdOnly(2)); + + db.CreateTable(false); + + var rows = db.Select(); + + Assert.That(rows, Has.Count.EqualTo(2)); + } + + [Test] + public void Can_preserve_ModelWithIdAndName_table() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + + db.Insert(new ModelWithIdAndName(1)); + db.Insert(new ModelWithIdAndName(2)); + + db.CreateTable(false); + + var rows = db.Select(); + + Assert.That(rows, Has.Count.EqualTo(2)); + } + + [Test] + public void Can_overwrite_ModelWithIdOnly_table() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + + db.Insert(new ModelWithIdOnly(1)); + db.Insert(new ModelWithIdOnly(2)); + + db.CreateTable(true); + + var rows = db.Select(); + + Assert.That(rows, Has.Count.EqualTo(0)); + } + + [Test] + public void Can_create_multiple_tables() + { + using var db = OpenDbConnection(); + db.CreateTables(true, typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); + + db.Insert(new ModelWithIdOnly(1)); + db.Insert(new ModelWithIdOnly(2)); + + db.Insert(new ModelWithIdAndName(1)); + db.Insert(new ModelWithIdAndName(2)); + + var rows1 = db.Select(); + var rows2 = db.Select(); + + Assert.That(rows1, Has.Count.EqualTo(2)); + Assert.That(rows2, Has.Count.EqualTo(2)); + } + + [Test] + public void Can_create_ModelWithIdAndName_table_with_specified_DefaultStringLength() + { + OrmLiteConfig.DialectProvider.GetStringConverter().StringLength = 255; + var createTableSql = OrmLiteConfig.DialectProvider.ToCreateTableStatement(typeof(ModelWithIdAndName)); + + Console.WriteLine("createTableSql: " + createTableSql); + Assert.That(createTableSql.Contains("VARCHAR(255)"), Is.True); + } + + public class Signal + { + [AutoIncrement] + public int Id { get; set; } + public short Code { get; set; } + } + + [Test] + public void Does_DoesColumnExist() + { + using var db = OpenDbConnection(); + db.DropTable(); + var exists = db.ColumnExists(x => x.Code); + Assert.That(exists, Is.False); + + db.CreateTable(); + exists = db.ColumnExists(x => x.Code); + Assert.That(exists); + } + + [Test] + public void Can_create_table_with_custom_field_order() + { + using (var db = OpenDbConnection()) + { + var modelDefinition = typeof(ModelWithCustomFiledOrder).GetModelMetadata(); + db.DropAndCreateTable(); + var defs=db.SqlList<(string field,string type,string @null,string key,string @default,string extra)>("desc " + modelDefinition.Name); + Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Filed1),defs[0].field); + Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Filed3),defs[1].field); + Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Filed2), defs[2].field); + Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Id),defs[3].field); + } + } + + [Test] + public void Can_create_table_without_custom_field_order() + { + using (var db = OpenDbConnection()) + { + var modelDefinition = typeof(ModelWithoutCustomFiledOrder).GetModelMetadata(); + db.DropAndCreateTable(); + var defs = db.SqlList<(string field, string type, string @null, string key, string @default, string extra)>("desc " + modelDefinition.Name); + Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Id), defs[0].field); + Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Filed1), defs[1].field); + Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Filed2), defs[2].field); + Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Filed3), defs[3].field); + } + } + + [Test] + public void model_definition_without_custom_order() + { + var modelDefinition = typeof(ModelWithoutCustomFiledOrder).GetModelMetadata(); + Assert.AreEqual(4, modelDefinition.FieldDefinitions.Count); + Assert.AreEqual(0, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Id)).Order); + Assert.AreEqual(1, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed1)).Order); + Assert.AreEqual(2, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed2)).Order); + Assert.AreEqual(3, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed3)).Order); + } + + [Test] + public void model_definition_with_custom_order() + { + var modelDefinition = typeof(ModelWithCustomFiledOrder).GetModelMetadata(); + Assert.AreEqual(4, modelDefinition.FieldDefinitions.Count); + Assert.AreEqual(100, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Id)).Order); + Assert.AreEqual(5, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed1)).Order); + Assert.AreEqual(13, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed2)).Order); + Assert.AreEqual(8, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed3)).Order); + } + + public class ModelWithoutCustomFiledOrder + { + [PrimaryKey] + [AutoIncrement] + public int Id { get; set; } + + public int Filed1 { get; set; } + public string Filed2 { get; set; } + public float Filed3 { get; set; } + } + + public class ModelWithCustomFiledOrder + { + [PrimaryKey] + [AutoIncrement] + [CustomField(Order = 100)] + public int Id { get; set; } + + [CustomField(Order = 5)] + public int Filed1 { get; set; } + [CustomField(Order = 13)] + public string Filed2 { get; set; } + [CustomField(Order = 8)] + public float Filed3 { get; set; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithIndexesTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithIndexesTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithIndexesTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithIndexesTests.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithNamingStrategyTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithNamingStrategyTests.cs new file mode 100644 index 000000000..f6d08825f --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableWithNamingStrategyTests.cs @@ -0,0 +1,234 @@ +using System; +using System.Diagnostics; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + + [TestFixture] + public class OrmLiteCreateTableWithNamigStrategyTests + : OrmLiteTestBase + { + + [Test] + public void Can_create_TableWithNamigStrategy_table_prefix() + { + using (new TemporaryNamingStrategy(new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void Can_create_TableWithNamigStrategy_table_lowered() + { + using (new TemporaryNamingStrategy(new LowercaseNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + + [Test] + public void Can_create_TableWithNamigStrategy_table_nameUnderscoreCoumpound() + { + using (new TemporaryNamingStrategy(new UnderscoreSeparatedCompoundNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void Can_get_data_from_TableWithNamigStrategy_with_GetById() + { + using (new TemporaryNamingStrategy(new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id= "999", AlbumId = "112", AlbumName="ElectroShip", Name = "MyNameIsBatman"}; + + db.Save(m); + var modelFromDb = db.SingleById("999"); + + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + + + [Test] + public void Can_get_data_from_TableWithNamigStrategy_with_query_by_example() + { + using (new TemporaryNamingStrategy(new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + + + [Test] + public void Can_get_data_from_TableWithNamigStrategy_AfterChangingNamingStrategy() + { + using (new TemporaryNamingStrategy(new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + + modelFromDb = db.SingleById("998"); + Assert.AreEqual(m.Name, modelFromDb.Name); + + } + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + + modelFromDb = db.SingleById("998"); + Assert.AreEqual(m.Name, modelFromDb.Name); + } + + using (new TemporaryNamingStrategy(new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + + modelFromDb = db.SingleById("998"); + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + } + + public class TemporaryNamingStrategy : IDisposable + { + private readonly IOrmLiteDialectProvider _dialectProvider; + private readonly INamingStrategy _previous; + private bool _disposed; + + public TemporaryNamingStrategy(INamingStrategy temporary) + { + _dialectProvider = OrmLiteConfig.DialectProvider; + _previous = _dialectProvider.NamingStrategy; + _dialectProvider.NamingStrategy = temporary; + } + +#if DEBUG + ~TemporaryNamingStrategy() + { + Debug.Assert(_disposed, "TemporaryNamingStrategy was not disposed of - previous naming strategy was not restored"); + } +#endif + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + _dialectProvider.NamingStrategy = _previous; + +#if DEBUG + GC.SuppressFinalize(this); +#endif + } + } + } + public class PrefixNamingStrategy : OrmLiteNamingStrategyBase + { + + public string TablePrefix { get; set; } + + public string ColumnPrefix { get; set; } + + public override string GetTableName(string name) + { + return TablePrefix + name; + } + + public override string GetColumnName(string name) + { + return ColumnPrefix + name; + } + + } + + public class LowercaseNamingStrategy : OrmLiteNamingStrategyBase + { + + public override string GetTableName(string name) + { + return name.ToLower(); + } + + public override string GetColumnName(string name) + { + return name.ToLower(); + } + + } + + public class UnderscoreSeparatedCompoundNamingStrategy : OrmLiteNamingStrategyBase + { + + public override string GetTableName(string name) + { + return toUnderscoreSeparatedCompound(name); + } + + public override string GetColumnName(string name) + { + return toUnderscoreSeparatedCompound(name); + } + + + string toUnderscoreSeparatedCompound(string name) + { + + string r = char.ToLower(name[0]).ToString(); + + for (int i = 1; i < name.Length; i++) + { + char c = name[i]; + if (char.IsUpper(name[i])) + { + r += "_"; + r += char.ToLower(name[i]); + } + else + { + r += name[i]; + } + } + return r; + } + + } + +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteDeleteTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteDeleteTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteDeleteTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteDeleteTests.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteGetScalarTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteGetScalarTests.cs new file mode 100644 index 000000000..99a15cdaf --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteGetScalarTests.cs @@ -0,0 +1,239 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + [TestFixture] + public class OrmLiteGetScalarTests:OrmLiteTestBase + { + + [Test] + public void Can_get_scalar_value(){ + + List authors = new List(); + authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London", FloatProperty=10.25f, DoubleProperty=3.23 }); + authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota",FloatProperty=7.59f,DoubleProperty=4.23 }); + authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London",FloatProperty=15.5f,DoubleProperty=5.42 }); + authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota",FloatProperty=0.57f, DoubleProperty=8.76}); + authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=8.43f, DoubleProperty=7.35}); + authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=1.25f, DoubleProperty=0.3652}); + authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota", FloatProperty=1.5f, DoubleProperty=100.563}); + authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena", FloatProperty=3.5f,DoubleProperty=7.23 }); + authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena", FloatProperty=0.25f,DoubleProperty=9.23 }); + authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London", FloatProperty=9.95f,DoubleProperty=4.91 }); + authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin",FloatProperty=4.44f,DoubleProperty=6.41 }); + authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid", FloatProperty=6.67f, DoubleProperty=8.05 }); + authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid", FloatProperty=1.25f, DoubleProperty=3.99}); + authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, + City = "Mexico", + LastActivity= DateTime.Today, + NRate=5, + FloatProperty=1.25f, + NFloatProperty=3.15f, + DoubleProperty= 1.25, + NDoubleProperty= 8.25 + }); + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + db.DeleteAll(); + + db.InsertAll(authors); + + var expectedDate = authors.Max(e=>e.Birthday); + var r1 = db.Scalar( e => Sql.Max(e.Birthday) ); + Assert.That(expectedDate, Is.EqualTo(r1)); + + expectedDate = authors.Where(e=>e.City=="London").Max(e=>e.Birthday); + r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="London" ); + Assert.That(expectedDate, Is.EqualTo(r1)); + + r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="SinCity" ); + Assert.That( default(DateTime), Is.EqualTo(r1)); + + + var expectedNullableDate= authors.Max(e=>e.LastActivity); + DateTime? r2 = db.Scalar(e=> Sql.Max(e.LastActivity)); + Assert.That(expectedNullableDate, Is.EqualTo(r2)); + + expectedNullableDate= authors.Where(e=> e.City=="Bogota").Max(e=>e.LastActivity); + r2 = db.Scalar( + e=> Sql.Max(e.LastActivity), + e=> e.City=="Bogota" ); + Assert.That(expectedNullableDate, Is.EqualTo(r2)); + + r2 = db.Scalar( e => Sql.Max(e.LastActivity), e=>e.City=="SinCity" ); + Assert.That( default(DateTime?), Is.EqualTo(r2)); + + + var expectedDecimal= authors.Max(e=>e.Earnings); + decimal r3 = db.Scalar(e=> Sql.Max(e.Earnings)); + Assert.That(expectedDecimal, Is.EqualTo(r3)); + + expectedDecimal= authors.Where(e=>e.City=="London").Max(e=>e.Earnings); + r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="London"); + Assert.That(expectedDecimal, Is.EqualTo(r3)); + + r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="SinCity"); + Assert.That( default(decimal), Is.EqualTo(r3)); + + + var expectedNullableDecimal= authors.Max(e=>e.NEarnings); + decimal? r4 = db.Scalar(e=> Sql.Max(e.NEarnings)); + Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); + + expectedNullableDecimal= authors.Where(e=>e.City=="London").Max(e=>e.NEarnings); + r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="London"); + Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); + + r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="SinCity"); + Assert.That( default(decimal?), Is.EqualTo(r4)); + + + var expectedDouble =authors.Max(e=>e.DoubleProperty); + double r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty)); + Assert.That(expectedDouble, Is.EqualTo(r5)); + + expectedDouble =authors.Where(e=>e.City=="London").Max(e=>e.DoubleProperty); + r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="London"); + Assert.That(expectedDouble, Is.EqualTo(r5)); + + r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="SinCity"); + Assert.That(default(double),Is.EqualTo(r5)); + + + var expectedNullableDouble =authors.Max(e=>e.NDoubleProperty); + double? r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty)); + Assert.That(expectedNullableDouble, Is.EqualTo(r6)); + + + expectedNullableDouble =authors.Where(e=>e.City=="London").Max(e=>e.NDoubleProperty); + r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="London"); + Assert.That(expectedNullableDouble, Is.EqualTo(r6)); + + r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="SinCity"); + Assert.That(default(double?),Is.EqualTo(r6)); + + + + var expectedFloat =authors.Max(e=>e.FloatProperty); + var r7 = db.Scalar(e=> Sql.Max(e.FloatProperty)); + Assert.That(expectedFloat, Is.EqualTo(r7)); + + expectedFloat =authors.Where(e=>e.City=="London").Max(e=>e.FloatProperty); + r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="London"); + Assert.That(expectedFloat, Is.EqualTo(r7)); + + r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="SinCity"); + Assert.That(default(float),Is.EqualTo(r7)); + + + var expectedNullableFloat =authors.Max(e=>e.NFloatProperty); + var r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty)); + Assert.That(expectedNullableFloat, Is.EqualTo(r8)); + + expectedNullableFloat =authors.Where(e=>e.City=="London").Max(e=>e.NFloatProperty); + r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="London"); + Assert.That(expectedNullableFloat, Is.EqualTo(r8)); + + r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="SinCity"); + Assert.That(default(float?),Is.EqualTo(r8)); + + + var expectedString=authors.Min(e=>e.Name); + var r9 = db.Scalar(e=> Sql.Min(e.Name)); + Assert.That(expectedString, Is.EqualTo(r9)); + + expectedString=authors.Where(e=>e.City=="London").Min(e=>e.Name); + r9 = db.Scalar(e=> Sql.Min(e.Name), e=>e.City=="London"); + Assert.That(expectedString, Is.EqualTo(r9)); + + r9 = db.Scalar(e=> Sql.Max(e.Name), e=>e.City=="SinCity"); + Assert.That(r9, Is.Null.Or.Empty); + + var expectedBool=authors.Min(e=>e.Active); + var r10 = db.Scalar(e=> Sql.Min(e.Active)); + Assert.That(expectedBool, Is.EqualTo(r10)); + + expectedBool=authors.Max(e=>e.Active); + r10 = db.Scalar(e=> Sql.Max(e.Active)); + Assert.That(expectedBool, Is.EqualTo(r10)); + + r10 = db.Scalar(e=> Sql.Max(e.Active), e=>e.City=="SinCity"); + Assert.IsFalse(r10); + + + + var expectedShort =authors.Max(e=>e.Rate); + var r11 = db.Scalar(e=> Sql.Max(e.Rate)); + Assert.That(expectedShort, Is.EqualTo(r11)); + + expectedShort =authors.Where(e=>e.City=="London").Max(e=>e.Rate); + r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="London"); + Assert.That(expectedShort, Is.EqualTo(r11)); + + r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="SinCity"); + Assert.That(default(short),Is.EqualTo(r7)); + + + var expectedNullableShort =authors.Max(e=>e.NRate); + var r12 = db.Scalar(e=> Sql.Max(e.NRate)); + Assert.That(expectedNullableShort, Is.EqualTo(r12)); + + expectedNullableShort =authors.Where(e=>e.City=="London").Max(e=>e.NRate); + r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="London"); + Assert.That(expectedNullableShort, Is.EqualTo(r12)); + + r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="SinCity"); + Assert.That(default(short?),Is.EqualTo(r12)); + + } + + } + + } + + + public class Author + { + public Author(){} + + [AutoIncrement] + [Alias("AuthorID")] + public Int32 Id { get; set;} + + [Index(Unique = true)] + [StringLength(40)] + public string Name { get; set;} + + public DateTime Birthday { get; set;} + public DateTime? LastActivity { get; set;} + public decimal Earnings { get; set;} + public decimal? NEarnings { get; set;} + + public bool Active { get; set; } + + [StringLength(80)] + [Alias("JobCity")] + public string City { get; set;} + + [StringLength(80)] + [Alias("Comment")] + public string Comments { get; set;} + + public short Rate{ get; set;} + public short? NRate{ get; set;} + public float FloatProperty { get; set;} + public float? NFloatProperty { get; set;} + public double DoubleProperty { get; set;} + public double? NDoubleProperty { get; set;} + + } + + +} + diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteInsertTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteInsertTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteInsertTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteInsertTests.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteQueryTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteQueryTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteQueryTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteQueryTests.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveStringValueTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveStringValueTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveStringValueTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveStringValueTests.cs diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteSaveTests.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteSelectTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteSelectTests.cs new file mode 100644 index 000000000..e4d2d2b92 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteSelectTests.cs @@ -0,0 +1,307 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + [TestFixture] + public class OrmLiteSelectTests + : OrmLiteTestBase + { + + [Test] + public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var row = db.SingleById(1); + + Assert.That(row.Id, Is.EqualTo(1)); + } + } + + [Test] + public void Can_GetById_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var row = db.SingleById("id-1"); + + Assert.That(row.Id, Is.EqualTo("id-1")); + } + } + + [Test] + public void Can_GetByIds_int_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var rows = db.SelectByIds(rowIds); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_GetByIds_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var rows = db.SelectByIds(rowIds); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; + + db.Insert(filterRow); + + var rows = db.Select("AlbumName = @AlbumName", new { filterRow.AlbumName }); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } + + [Test] + public void Can_select_scalar_value() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var count = db.Scalar("SELECT COUNT(*) FROM ModelWithIdAndName"); + + Assert.That(count, Is.EqualTo(n)); + } + } + + [Test] + public void Can_loop_each_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var dbRowIds = new List(); + foreach (var row in db.SelectLazy()) + { + dbRowIds.Add(row.Id); + } + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; + + db.Insert(filterRow); + + var dbRowIds = new List(); + var rows = db.SelectLazy("AlbumName = @AlbumName", new { filterRow.AlbumName }); + foreach (var row in rows) + { + dbRowIds.Add(row.Id); + } + + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } + + [Test] + public void Can_GetFirstColumn() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var ids = db.Column("SELECT Id FROM ModelWithIdAndName"); + + Assert.That(ids.Count, Is.EqualTo(n)); + } + } + + [Test] + public void Can_GetFirstColumnDistinct() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var ids = db.ColumnDistinct("SELECT Id FROM ModelWithIdAndName"); + + Assert.That(ids.Count, Is.EqualTo(n)); + } + } + + [Test] + public void Can_GetLookup() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => { + var row = ModelWithIdAndName.Create(x); + row.Name = x % 2 == 0 ? "OddGroup" : "EvenGroup"; + db.Insert(row); + }); + + var lookup = db.Lookup("SELECT Name, Id FROM ModelWithIdAndName"); + + Assert.That(lookup, Has.Count.EqualTo(2)); + Assert.That(lookup["OddGroup"], Has.Count.EqualTo(3)); + Assert.That(lookup["EvenGroup"], Has.Count.EqualTo(2)); + } + } + + [Test] + public void Can_GetDictionary() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var dictionary = db.Dictionary("SELECT Id, Name FROM ModelWithIdAndName"); + + Assert.That(dictionary, Has.Count.EqualTo(5)); + + //Console.Write(dictionary.Dump()); + } + } + + [Test] + public void Can_Select_subset_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var rows = db.Select("SELECT Id, Name FROM ModelWithFieldsOfDifferentTypes"); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_Select_Into_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var rows = db.Select(typeof(ModelWithFieldsOfDifferentTypes)); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_Select_In_for_string_value() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var selectInNames = new[] { "Name1", "Name2" }; + var rows = db.Select("Name IN ({0})".Fmt(selectInNames.SqlInParams()), + new { values = selectInNames.SqlInValues() }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + + rows = db.Select("Name IN (@p1, @p2)", new { p1 = "Name1", p2 = "Name2" }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteTestBase.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteTestBase.cs new file mode 100644 index 000000000..02d3f5d26 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteTestBase.cs @@ -0,0 +1,42 @@ +using System; +using System.Data; +using ServiceStack.Configuration; +using ServiceStack.Logging; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + public class MySqlConfig + { + public static readonly IOrmLiteDialectProvider DialectProvider = +#if !MYSQLCONNECTOR + MySqlDialectProvider.Instance; +#else + MySqlConnectorDialectProvider.Instance; +#endif + public static string ConnectionString = "Server=localhost;Database=test;UID=root;Password=test"; + } + + public class OrmLiteTestBase + { + protected string ConnectionString { get; set; } + + public OrmLiteTestBase() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + OrmLiteConfig.DialectProvider = MySqlConfig.DialectProvider; + ConnectionString = ConfigUtils.GetAppSetting("AppDb", MySqlConfig.ConnectionString); + } + + public void Log(string text) + { + Console.WriteLine(text); + } + + public virtual IDbConnection OpenDbConnection(string connString = null) + { + connString = connString ?? ConnectionString; + return connString.OpenDbConnection(); + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteTransactionTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteTransactionTests.cs similarity index 89% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteTransactionTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteTransactionTests.cs index 1818c283d..52a653c3d 100644 --- a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteTransactionTests.cs +++ b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteTransactionTests.cs @@ -15,7 +15,7 @@ public void Transaction_commit_persists_data_to_the_db() db.CreateTable(true); db.Insert(new ModelWithIdAndName(1)); - using (var dbTrans = db.BeginTransaction()) + using (var dbTrans = db.OpenTransaction()) { db.Insert(new ModelWithIdAndName(2)); db.Insert(new ModelWithIdAndName(3)); @@ -39,9 +39,9 @@ public void Transaction_rollsback_if_not_committed() db.CreateTable(true); db.Insert(new ModelWithIdAndName(1)); - using (var dbTrans = db.BeginTransaction()) + using (var dbTrans = db.OpenTransaction()) { - db.Insert(new ModelWithIdAndName(2)); + db.Insert(new ModelWithIdAndName(2)); db.Insert(new ModelWithIdAndName(3)); var rowsInTrans = db.Select(); @@ -64,9 +64,9 @@ public void Transaction_rollsback_transactions_to_different_tables() db.Insert(new ModelWithIdAndName(1)); - using (var dbTrans = db.BeginTransaction()) + using (var dbTrans = db.OpenTransaction()) { - db.Insert(new ModelWithIdAndName(2)); + db.Insert(new ModelWithIdAndName(2)); db.Insert(ModelWithFieldsOfDifferentTypes.Create(3)); db.Insert(ModelWithOnlyStringFields.Create("id3")); @@ -92,9 +92,9 @@ public void Transaction_commits_inserts_to_different_tables() db.Insert(new ModelWithIdAndName(1)); - using (var dbTrans = db.BeginTransaction()) + using (var dbTrans = db.OpenTransaction()) { - db.Insert(new ModelWithIdAndName(2)); + db.Insert(new ModelWithIdAndName(2)); db.Insert(ModelWithFieldsOfDifferentTypes.Create(3)); db.Insert(ModelWithOnlyStringFields.Create("id3")); diff --git a/src/ServiceStack.OrmLite.MySql.Tests/OrmLiteUpdateTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteUpdateTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/OrmLiteUpdateTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteUpdateTests.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/ServiceStack.OrmLite.MySql.Tests.csproj b/tests/ServiceStack.OrmLite.MySql.Tests/ServiceStack.OrmLite.MySql.Tests.csproj new file mode 100644 index 000000000..a555062e5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/ServiceStack.OrmLite.MySql.Tests.csproj @@ -0,0 +1,45 @@ + + + + net472 + + portable + ServiceStack.OrmLite.MySql.Tests + Library + ServiceStack.OrmLite.MySql.Tests + default + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.MySql.Tests/ShippersExample.cs b/tests/ServiceStack.OrmLite.MySql.Tests/ShippersExample.cs similarity index 80% rename from src/ServiceStack.OrmLite.MySql.Tests/ShippersExample.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/ShippersExample.cs index bacd77786..d172a140a 100644 --- a/src/ServiceStack.OrmLite.MySql.Tests/ShippersExample.cs +++ b/tests/ServiceStack.OrmLite.MySql.Tests/ShippersExample.cs @@ -1,9 +1,8 @@ - -using System.Configuration; using System.Data; using NUnit.Framework; using ServiceStack.DataAnnotations; using ServiceStack.Model; +using ServiceStack.OrmLite.Tests; namespace ServiceStack.OrmLite.MySql.Tests { @@ -12,10 +11,9 @@ public class ShippersExample { static ShippersExample() { - OrmLiteConfig.DialectProvider = MySqlDialectProvider.Instance; + OrmLiteConfig.DialectProvider = MySqlConfig.DialectProvider; } - [Alias("Shippers")] public class Shipper : IHasId @@ -62,11 +60,10 @@ public class ShipperTypeCount public int Total { get; set; } } - [Test] public void Shippers_UseCase() { - using (IDbConnection db = ConfigurationManager.ConnectionStrings["testDb"].ConnectionString.OpenDbConnection()) + using (IDbConnection db = MySqlConfig.ConnectionString.OpenDbConnection()) { db.DropTable(); db.DropTable(); @@ -77,7 +74,7 @@ public void Shippers_UseCase() int trainsTypeId, planesTypeId; //Playing with transactions - using (IDbTransaction dbTrans = db.BeginTransaction()) + using (IDbTransaction dbTrans = db.OpenTransaction()) { db.Insert(new ShipperType { Name = "Trains" }); trainsTypeId = (int)db.LastInsertId(); @@ -87,7 +84,7 @@ public void Shippers_UseCase() dbTrans.Commit(); } - using (IDbTransaction dbTrans = db.BeginTransaction(IsolationLevel.ReadCommitted)) + using (IDbTransaction dbTrans = db.OpenTransaction(IsolationLevel.ReadCommitted)) { db.Insert(new ShipperType { Name = "Automobiles" }); Assert.That(db.Select(), Has.Count.EqualTo(3)); @@ -102,10 +99,11 @@ public void Shippers_UseCase() db.Insert(new Shipper { CompanyName = "Planes R Us", Phone = "555-PLANES", ShipperTypeId = planesTypeId }); db.Insert(new Shipper { CompanyName = "We do everything!", Phone = "555-UNICORNS", ShipperTypeId = planesTypeId }); - var trainsAreUs = db.SingleFmt("ShipperTypeId = {0}", trainsTypeId); + var trainsAreUs = db.Single("ShipperTypeId = @id", new { id = trainsTypeId }); Assert.That(trainsAreUs.CompanyName, Is.EqualTo("Trains R Us")); - Assert.That(db.SelectFmt("CompanyName = {0} OR Phone = {1}", "Trains R Us", "555-UNICORNS"), Has.Count.EqualTo(2)); - Assert.That(db.SelectFmt("ShipperTypeId = {0}", planesTypeId), Has.Count.EqualTo(2)); + Assert.That(db.Select("CompanyName = @company OR Phone = @phone", + new { company = "Trains R Us", phone = "555-UNICORNS" }), Has.Count.EqualTo(2)); + Assert.That(db.Select("ShipperTypeId = @id", new { id = planesTypeId }), Has.Count.EqualTo(2)); //Lets update a record trainsAreUs.Phone = "666-TRAINS"; @@ -122,11 +120,11 @@ public void Shippers_UseCase() //Performing custom queries //Select only a subset from the table - var partialColumns = db.SelectFmt(typeof (Shipper), "ShipperTypeId = {0}", planesTypeId); + var partialColumns = db.Select(typeof(Shipper), "ShipperTypeId = @id", new { id = planesTypeId }); Assert.That(partialColumns, Has.Count.EqualTo(2)); //Select into another POCO class that matches sql - var rows = db.SelectFmt( + var rows = db.Select( "SELECT ShipperTypeId, COUNT(*) AS Total FROM Shippers GROUP BY ShipperTypeId ORDER BY COUNT(*)"); Assert.That(rows, Has.Count.EqualTo(2)); diff --git a/src/ServiceStack.OrmLite.MySql.Tests/SqlMapperTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/SqlMapperTests.cs similarity index 93% rename from src/ServiceStack.OrmLite.MySql.Tests/SqlMapperTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/SqlMapperTests.cs index 3926cea83..039beee38 100644 --- a/src/ServiceStack.OrmLite.MySql.Tests/SqlMapperTests.cs +++ b/tests/ServiceStack.OrmLite.MySql.Tests/SqlMapperTests.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using ServiceStack.DataAnnotations; using ServiceStack.OrmLite.MySql; +using ServiceStack.OrmLite.MySql.Tests; namespace ServiceStack.OrmLite.Tests { @@ -26,9 +27,7 @@ public class User public void SetUp() { //Setup SQL Server Connection Factory - dbFactory = new OrmLiteConnectionFactory( - ConfigurationManager.ConnectionStrings["testDb"].ConnectionString, - MySqlDialectProvider.Instance); + dbFactory = new OrmLiteConnectionFactory(MySqlConfig.ConnectionString, MySqlConfig.DialectProvider); using (var db = dbFactory.Open()) db.DropAndCreateTable(); diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/StringColumnTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/StringColumnTests.cs new file mode 100644 index 000000000..7c8565522 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/StringColumnTests.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; + +using System.Linq; +using System.Text; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.OrmLite.MySql.DataAnnotations; + +namespace ServiceStack.OrmLite.MySql.Tests +{ + [TestFixture] + public class StringColumnTests + : OrmLiteTestBase + { + [Test] + public void Can_create_primary_key_varchar_with_string_length_255() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_create_primary_key_varchar_without_setting_string_length() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_create_unique_key_on_varchar_without_setting_string_length() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + } + + [Test] + public void Can_store_and_retrieve_string_with_8000_characters_from_varchar_field() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + + var obj = new TypeWithStringId { + Id = "a", + Value = CreateString(8000) + }; + + Assert.AreEqual(8000, obj.Value.Length); + + db.Save(obj); + var target = db.SingleById(obj.Id); + + Assert.AreEqual(obj.Value, target.Value); + Assert.AreEqual(8000, obj.Value.Length); + } + + [Test] + public void Can_store_and_retrieve_string_with_8000_characters_from_text_field() + { + using var db = OpenDbConnection(); + db.CreateTable(true); + + var obj = new TypeWithTextField() { + Value = CreateString(8000) + }; + + Assert.AreEqual(8000, obj.Value.Length); + + db.Save(obj); + obj.Id = (int)db.LastInsertId(); + + var target = db.SingleById(obj.Id); + + Assert.AreEqual(obj.Value, target.Value); + Assert.AreEqual(8000, obj.Value.Length); + } + + class TypeWithUniqeKeyOnVarchar + { + public int Id { get; set; } + + [Index(true)] + public string Value { get; set; } + } + + class TypeWithUniqeKeyOnVarchar_256 + { + public int Id { get; set; } + + [StringLength(256)] + [Index(true)] + public string Value { get; set; } + } + + class TypeWithStringId : IHasStringId + { + public string Id { get; set; } + [StringLength(8000)] + public string Value { get; set; } + } + + class TypeWithUniqueIndexOnTextField + { + [AutoIncrement] + public int Id { get; set; } + + [Index(true)] + [Text] + public string Value { get; set; } + } + + class TypeWithTextField + { + [AutoIncrement] + public int Id { get; set; } + + [Text] + public string Value { get; set; } + } + + class TypeWithStringId_255 : IHasStringId + { + [StringLength(255)] + public string Id { get; set; } + public string Value { get; set; } + } + + class TypeWithStringId_256 : IHasStringId + { + [StringLength(256)] + public string Id { get; set; } + public string Value { get; set; } + } + + private static string CreateString(int length) + { + const string loremIpsum = + "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."; + + var retVal = ""; + + for (int i = 0; i < length / loremIpsum.Length; i++) + retVal += loremIpsum; + + return retVal + loremIpsum.Substring(0, length - retVal.Length); + } + } +} diff --git a/src/ServiceStack.OrmLite.MySql.Tests/TypeWithByteArrayFieldTests.cs b/tests/ServiceStack.OrmLite.MySql.Tests/TypeWithByteArrayFieldTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.MySql.Tests/TypeWithByteArrayFieldTests.cs rename to tests/ServiceStack.OrmLite.MySql.Tests/TypeWithByteArrayFieldTests.cs diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/UseCase/CustomerOrdersUseCase.cs b/tests/ServiceStack.OrmLite.MySql.Tests/UseCase/CustomerOrdersUseCase.cs new file mode 100644 index 000000000..c806fefdd --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/UseCase/CustomerOrdersUseCase.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.MySql.Tests.UseCase +{ + public enum PhoneType + { + Home, + Work, + Mobile, + } + + public enum AddressType + { + Home, + Work, + Other, + } + + public class Address + { + public string Line1 { get; set; } + public string Line2 { get; set; } + public string ZipCode { get; set; } + public string State { get; set; } + public string City { get; set; } + public string Country { get; set; } + } + + public class Customer + { + public Customer() + { + this.PhoneNumbers = new Dictionary(); + this.Addresses = new Dictionary(); + } + + [AutoIncrement] // Creates Auto primary key + public int Id { get; set; } + + public string FirstName { get; set; } + + public string LastName { get; set; } + + [Index(Unique = true)] // Creates Unique Index + public string Email { get; set; } + + public Dictionary PhoneNumbers { get; set; } + + public Dictionary Addresses { get; set; } + + public DateTime CreatedAt { get; set; } + } + + public class Order + { + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(Customer))] //Creates Foreign Key + public int CustomerId { get; set; } + + [References(typeof(Employee))] //Creates Foreign Key + public int EmployeeId { get; set; } + + public Address ShippingAddress { get; set; } //Blobbed (no Address table) + + public DateTime? OrderDate { get; set; } + + public DateTime? RequiredDate { get; set; } + + public DateTime? ShippedDate { get; set; } + + public int? ShipVia { get; set; } + + public decimal Freight { get; set; } + + public decimal Total { get; set; } + } + + public class OrderDetail + { + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(Order))] //Creates Foreign Key + public int OrderId { get; set; } + + public int ProductId { get; set; } + + public decimal UnitPrice { get; set; } + + public short Quantity { get; set; } + + public decimal Discount { get; set; } + } + + public class Employee + { + public int Id { get; set; } + + public string Name { get; set; } + } + + public class Product + { + public int Id { get; set; } + + public string Name { get; set; } + + public decimal UnitPrice { get; set; } + } + + [TestFixture] + public class CustomerOrdersUseCase + { + //Stand-alone class, No other configs, nothing but POCOs. + [Test] + public void Run() + { + //Setup SQL Server Connection Factory + var dbFactory = new OrmLiteConnectionFactory(MySqlConfig.ConnectionString, MySqlConfig.DialectProvider); + + //Non-intrusive: All extension methods hang off System.Data.* interfaces + IDbConnection db = dbFactory.OpenDbConnection(); + + //Re-Create all table schemas: + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + + db.Insert(new Employee { Id = 1, Name = "Employee 1" }); + db.Insert(new Employee { Id = 2, Name = "Employee 2" }); + var product1 = new Product { Id = 1, Name = "Product 1", UnitPrice = 10 }; + var product2 = new Product { Id = 2, Name = "Product 2", UnitPrice = 20 }; + db.Save(product1, product2); + + var customer = new Customer + { + FirstName = "Orm", + LastName = "Lite", + Email = "ormlite@servicestack.net", + PhoneNumbers = + { + { PhoneType.Home, "555-1234" }, + { PhoneType.Work, "1-800-1234" }, + { PhoneType.Mobile, "818-123-4567" }, + }, + Addresses = + { + { AddressType.Work, new Address { Line1 = "1 Street", Country = "US", State = "NY", City = "New York", ZipCode = "10101" } }, + }, + CreatedAt = DateTime.UtcNow, + }; + db.Insert(customer); + + var customerId = db.LastInsertId(); //Get Auto Inserted Id + customer = db.Single(new { customer.Email }); //Query + Assert.That(customer.Id, Is.EqualTo(customerId)); + + //Direct access to System.Data.Transactions: + using (var trans = db.OpenTransaction(IsolationLevel.ReadCommitted)) + { + var order = new Order + { + CustomerId = customer.Id, + EmployeeId = 1, + OrderDate = DateTime.UtcNow, + Freight = 10.50m, + ShippingAddress = new Address { Line1 = "3 Street", Country = "US", State = "NY", City = "New York", ZipCode = "12121" }, + }; + db.Save(order); //Inserts 1st time + + order.Id = (int)db.LastInsertId(); //Get Auto Inserted Id + + var orderDetails = new[] { + new OrderDetail + { + OrderId = order.Id, + ProductId = product1.Id, + Quantity = 2, + UnitPrice = product1.UnitPrice, + }, + new OrderDetail + { + OrderId = order.Id, + ProductId = product2.Id, + Quantity = 2, + UnitPrice = product2.UnitPrice, + Discount = .15m, + } + }; + + db.Insert(orderDetails); + + order.Total = orderDetails.Sum(x => x.UnitPrice * x.Quantity * x.Discount) + order.Freight; + + db.Save(order); //Updates 2nd Time + + trans.Commit(); + } + } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/UseCase/SimpleUseCase.cs b/tests/ServiceStack.OrmLite.MySql.Tests/UseCase/SimpleUseCase.cs new file mode 100644 index 000000000..bc4bc6bd6 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/UseCase/SimpleUseCase.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.MySql.Tests.UseCase +{ + [TestFixture] + public class SimpleUseCase + { + public SimpleUseCase() + { + //Inject your database provider here + OrmLiteConfig.DialectProvider = MySqlConfig.DialectProvider; + } + + public class UserWithIndex + { + public long Id { get; set; } + + [ServiceStack.DataAnnotations.Index] + public string Name { get; set; } + + public DateTime CreatedDate { get; set; } + } + + [Test] + public void Simple_CRUD_example() + { + using (var db = MySqlConfig.ConnectionString.OpenDbConnection()) + { + db.CreateTable(true); + + db.Insert(new UserWithIndex { Id = 1, Name = "A", CreatedDate = DateTime.Now }); + db.Insert(new UserWithIndex { Id = 2, Name = "B", CreatedDate = DateTime.Now }); + db.Insert(new UserWithIndex { Id = 3, Name = "B", CreatedDate = DateTime.Now }); + + var rowsB = db.Select("Name = @name", new { name = "B" }); + + Assert.That(rowsB, Has.Count.EqualTo(2)); + + var rowIds = rowsB.ConvertAll(x => x.Id); + Assert.That(rowIds, Is.EquivalentTo(new List { 2, 3 })); + + rowsB.ForEach(x => db.Delete(x)); + + rowsB = db.Select("Name = @name", new { name = "B" }); + Assert.That(rowsB, Has.Count.EqualTo(0)); + + var rowsLeft = db.Select(); + Assert.That(rowsLeft, Has.Count.EqualTo(1)); + + Assert.That(rowsLeft[0].Name, Is.EqualTo("A")); + } + } + + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.MySql.Tests/app.config b/tests/ServiceStack.OrmLite.MySql.Tests/app.config new file mode 100644 index 000000000..f1a42de12 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySql.Tests/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/ServiceStack.OrmLite.MySqlConnector.Tests/ServiceStack.OrmLite.MySqlConnector.Tests.csproj b/tests/ServiceStack.OrmLite.MySqlConnector.Tests/ServiceStack.OrmLite.MySqlConnector.Tests.csproj new file mode 100644 index 000000000..14b35b4ff --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySqlConnector.Tests/ServiceStack.OrmLite.MySqlConnector.Tests.csproj @@ -0,0 +1,165 @@ + + + + net472;net6.0 + portable + ServiceStack.OrmLite.MySqlConnector.Tests + Library + ServiceStack.OrmLite.MySqlMySqlConnector.Tests + default + + + + + BooleanTests.cs + + + CustomSqlTests.cs + + + DateTimeColumnTest.cs + + + EnumTests.cs + + + + + + + + + + + + + + + + + ForeignKeyAttributeTests.cs + + + + + LocalizationTests.cs + + + MySqlAdminTests.cs + + + OrmLiteBasicPersistenceProviderTests.cs + + + OrmLiteComplexTypesTests.cs + + + OrmLiteConnectionTests.cs + + + OrmLiteCreateTableTests.cs + + + OrmLiteCreateTableWithIndexesTests.cs + + + OrmLiteCreateTableWithNamingStrategyTests.cs + + + OrmLiteDeleteTests.cs + + + OrmLiteGetScalarTests.cs + + + OrmLiteInsertTests.cs + + + OrmLiteQueryTests.cs + + + OrmLiteSaveStringValueTests.cs + + + OrmLiteSaveTests.cs + + + OrmLiteSelectTests.cs + + + OrmLiteTestBase.cs + + + OrmLiteTransactionTests.cs + + + OrmLiteUpdateTests.cs + + + ShippersExample.cs + + + SqlMapperTests.cs + + + StringColumnTests.cs + + + TypeWithByteArrayFieldTests.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(DefineConstants);MYSQLCONNECTOR + + + + + + + diff --git a/tests/ServiceStack.OrmLite.MySqlConnector.Tests/app.config b/tests/ServiceStack.OrmLite.MySqlConnector.Tests/app.config new file mode 100644 index 000000000..159ffe803 --- /dev/null +++ b/tests/ServiceStack.OrmLite.MySqlConnector.Tests/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/DateTimeColumnTest.cs b/tests/ServiceStack.OrmLite.Oracle.Tests/DateTimeColumnTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.Oracle.Tests/DateTimeColumnTest.cs rename to tests/ServiceStack.OrmLite.Oracle.Tests/DateTimeColumnTest.cs diff --git a/tests/ServiceStack.OrmLite.Oracle.Tests/ForeignKeyAttributeTests.cs b/tests/ServiceStack.OrmLite.Oracle.Tests/ForeignKeyAttributeTests.cs new file mode 100644 index 000000000..41ee1c47a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Oracle.Tests/ForeignKeyAttributeTests.cs @@ -0,0 +1,300 @@ +using System; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixture] + public class ForeignKeyAttributeTests : OrmLiteTestBase + { + [OneTimeSetUp] + public void Setup() + { + using (var dbConn = OpenDbConnection()) + { + DropTables(dbConn); + + dbConn.DropAndCreateTable(); + } + } + + private void DropTables(IDbConnection dbConnection) + { + if (dbConnection.TableExists("TWODUC")) dbConnection.DropTable(); + if (dbConnection.TableExists("TWODSN")) dbConnection.DropTable(); + if (dbConnection.TableExists("TWODDF")) dbConnection.DropTable(); + if (dbConnection.TableExists("TWODNR")) dbConnection.DropTable(); + if (dbConnection.TableExists("TWODNA")) dbConnection.DropTable(); + if (dbConnection.TableExists("TWODC")) dbConnection.DropTable(); + if (dbConnection.TableExists("TWSKF")) dbConnection.DropTable(); + if (dbConnection.TableExists("TWONFKI")) dbConnection.DropTable(); + } + + [Test] + public void CanCreateSimpleForeignKey() + { + using (var dbConnection = OpenDbConnection()) + { + dbConnection.DropAndCreateTable(); + } + } + + [Test] + public void ForeignWithOnDeleteCascadeCreatesOk() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropAndCreateTable(); + } + } + + [Test] + public void ForeignWithOnDeleteCascadeWorks() + { + using (var dbConnection = OpenDbConnection()) + { + dbConnection.DropAndCreateTable(); + + dbConnection.Save(new ReferencedType { Id = 1 }); + dbConnection.Save(new TypeWithOnDeleteCascade { RefId = 1 }); + + Assert.AreEqual(1, dbConnection.Select().Count); + Assert.AreEqual(1, dbConnection.Select().Count); + + dbConnection.Delete(r => r.Id == 1); + + Assert.AreEqual(0, dbConnection.Select().Count); + Assert.AreEqual(0, dbConnection.Select().Count); + } + } + + [Test] + public void ForeignWithOnDeleteCascadeAndOnUpdateCascadeCreatesOk() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropAndCreateTable(); + } + } + + [Test] + public void ForeignWithOnDeleteNoActionCreatesOk() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropAndCreateTable(); + } + } + + [Test] + public void ForeignWithOnDeleteNoActionThrowsException() + { + using (var dbConnection = OpenDbConnection()) + { + dbConnection.CreateTableIfNotExists(); + + dbConnection.Save(new ReferencedType { Id = 1 }); + dbConnection.Save(new TypeWithOnDeleteNoAction { RefId = 1 }); + + Assert.AreEqual(1, dbConnection.Select().Count); + Assert.AreEqual(1, dbConnection.Select().Count); + + // Do not want to require reference to dll with exception definition so use catch + Assert.Catch(() => dbConnection.Delete(r => r.Id == 1)); + } + } + + [Test] + public void ForeignWithOnDeleteRestrictCreatesOk() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropAndCreateTable(); + } + } + + [Test] + public void ForeignWithOnDeleteRestrictThrowsException() + { + using (var dbConnection = OpenDbConnection()) + { + dbConnection.CreateTableIfNotExists(); + + dbConnection.Save(new ReferencedType { Id = 1 }); + dbConnection.Save(new TypeWithOnDeleteRestrict { RefId = 1 }); + + Assert.AreEqual(1, dbConnection.Select().Count); + Assert.AreEqual(1, dbConnection.Select().Count); + + // Do not want to require reference to dll with exception definition so use catch + Assert.Catch(() => dbConnection.Delete(r => r.Id == 1)); + } + } + + [Test] + public void ForeignWithOnDeleteSetDefaultCreatesOk() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropAndCreateTable(); + } + } + + [Test] + public void ForeignWithOnDeleteSetDefaultThrowsException() + { + using (var dbConnection = OpenDbConnection()) + { + dbConnection.CreateTableIfNotExists(); + + dbConnection.Save(new ReferencedType { Id = 1 }); + dbConnection.Save(new TypeWithOnDeleteSetDefault { RefId = 1 }); + + Assert.AreEqual(1, dbConnection.Select().Count); + Assert.AreEqual(1, dbConnection.Select().Count); + + // Do not want to require reference to dll with exception definition so use catch + Assert.Catch(() => dbConnection.Delete(r => r.Id == 1)); + } + } + + [Test] + public void ForeignWithOnDeleteSetNullCreatesOk() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropAndCreateTable(); + } + } + + [Test] + public void ForeignWithOnDeleteSetNullWorks() + { + using (var dbConnection = OpenDbConnection()) + { + DropTables(dbConnection); + + dbConnection.CreateTableIfNotExists(); + + dbConnection.Save(new ReferencedType { Id = 1 }); + dbConnection.Save(new TypeWithOnDeleteSetNull { RefId = 1 }); + + Assert.AreEqual(1, dbConnection.Select().Count); + Assert.AreEqual(1, dbConnection.Select().Count); + + dbConnection.Delete(r => r.Id == 1); + + Assert.AreEqual(0, dbConnection.Select().Count); + var row = dbConnection.Select().First(); + Assert.That(row.RefId, Is.Null); + } + } + + [Test, NUnit.Framework.Ignore("Base implementation does not allow provider override so cannot work in Oracle")] + public void CanDropForeignKey() + { + using (var dbConnection = OpenDbConnection()) + { + dbConnection.DropAndCreateTable(); + dbConnection.DropForeignKey("FK_DNA"); + } + } + + [Test] + public void CanAddForeignKey() + { + using (var dbConnection = OpenDbConnection()) + { + dbConnection.DropAndCreateTable(); + dbConnection.AddForeignKey( + t => t.RefId, tr => tr.Id, OnFkOption.NoAction, OnFkOption.Cascade, "FK_ADDED"); + } + } + } + + public class ReferencedType + { + public int Id { get; set; } + } + + [Alias("TWSKF")] + public class TypeWithSimpleForeignKey + { + [AutoIncrement] + public int Id { get; set; } + [References(typeof(ReferencedType))] + public int RefId { get; set; } + } + + [Alias("TWODC")] + public class TypeWithOnDeleteCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", ForeignKeyName = "FK_DC")] + public int? RefId { get; set; } + } + + [Alias("TWODUC")] + public class TypeWithOnDeleteAndUpdateCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE", ForeignKeyName = "FK_DC_UC")] + public int? RefId { get; set; } + } + + [Alias("TWODNA")] + public class TypeWithOnDeleteNoAction + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION", ForeignKeyName = "FK_DNA")] + public int? RefId { get; set; } + } + + [Alias("TWODNR")] + public class TypeWithOnDeleteRestrict + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT", ForeignKeyName = "FK_DR")] + public int? RefId { get; set; } + } + + [Alias("TWODDF")] + public class TypeWithOnDeleteSetDefault + { + [AutoIncrement] + public int Id { get; set; } + + [Default(typeof(int), "17")] + [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT", ForeignKeyName = "FK_DDF")] + public int RefId { get; set; } + } + + [Alias("TWODSN")] + public class TypeWithOnDeleteSetNull + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL", ForeignKeyName = "FK_SN")] + public int? RefId { get; set; } + } + + [Alias("TWONFKI")] + public class TypeWithNoForeignKeyInitially + { + [AutoIncrement] + public int Id { get; set; } + + public int? RefId { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Oracle.Tests/OracleParamTests.cs b/tests/ServiceStack.OrmLite.Oracle.Tests/OracleParamTests.cs new file mode 100644 index 000000000..502669a8e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Oracle.Tests/OracleParamTests.cs @@ -0,0 +1,1206 @@ +using System; +using System.Collections.Generic; +//using System.ComponentModel.Composition; +//using System.ComponentModel.Composition.Hosting; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixture] + public class OracleParamTests : OrmLiteTestBase + { + private void DropAndCreateTables(IDbConnection db) + { + if (db.TableExists("ParamRelBO")) + db.DropTable(); + + db.CreateTable(true); + db.CreateTable(true); + db.CreateTable(true); + db.CreateTable(true); + } + + [Test] + public void ORA_ParamTestInsert() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + var dateTimeNow =new DateTime( DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); + + db.Insert(new ParamTestBo { Id = 1, Double = 0.001, Int = 100, Info = "One", NullableBool = null, DateTime = dateTimeNow }); + db.Insert(new ParamTestBo { Id = 2, Double = 0.002, Int = 200, Info = "Two", NullableBool = true, DateTime = dateTimeNow }); + db.Insert(new ParamTestBo { Id = 3, Double = 0.003, Int = 300, Info = "Three", NullableBool = false, DateTime = dateTimeNow.AddDays(23) }); + db.Insert(new ParamTestBo { Id = 4, Double = 0.004, Int = 400, Info = "Four", NullableBool = null }); + db.Insert(new ParamTestBo { Id = 5, Double = 0.005, Int = 500, Info = "Five", NullableBool = null, UInt = uint.MaxValue}); + + var bo1 = db.Select(q => q.Id == 1).Single(); + var bo2 = db.Select(q => q.Id == 2).Single(); + var bo3 = db.Select(q => q.Id == 3).Single(); + var bo4 = db.Select(q => q.Id == 4).Single(); + var bo5 = db.Select(q => q.Id == 5).Single(); + + Assert.AreEqual(1, bo1.Id); + Assert.AreEqual(2, bo2.Id); + Assert.AreEqual(3, bo3.Id); + Assert.AreEqual(4, bo4.Id); + Assert.AreEqual(5, bo5.Id); + + Assert.AreEqual(0.001, bo1.Double); + Assert.AreEqual(0.002, bo2.Double); + Assert.AreEqual(0.003, bo3.Double); + Assert.AreEqual(0.004, bo4.Double); + Assert.AreEqual(0.005, bo5.Double); + + Assert.AreEqual(100, bo1.Int); + Assert.AreEqual(200, bo2.Int); + Assert.AreEqual(300, bo3.Int); + Assert.AreEqual(400, bo4.Int); + Assert.AreEqual(500, bo5.Int); + + Assert.AreEqual("One", bo1.Info); + Assert.AreEqual("Two", bo2.Info); + Assert.AreEqual("Three", bo3.Info); + Assert.AreEqual("Four", bo4.Info); + Assert.AreEqual("Five", bo5.Info); + + Assert.AreEqual(null, bo1.NullableBool); + Assert.AreEqual(true, bo2.NullableBool); + Assert.AreEqual(false, bo3.NullableBool); + Assert.AreEqual(null, bo4.NullableBool); + Assert.AreEqual(null, bo5.NullableBool); + + Assert.AreEqual(dateTimeNow, bo1.DateTime); + Assert.AreEqual(dateTimeNow, bo2.DateTime); + Assert.AreEqual(dateTimeNow.AddDays(23), bo3.DateTime); + Assert.AreEqual(null, bo4.DateTime); + Assert.AreEqual(null, bo5.DateTime); + + Assert.AreEqual(null, bo1.UInt); + Assert.AreEqual(null, bo2.UInt); + Assert.AreEqual(null, bo3.UInt); + Assert.AreEqual(null, bo4.UInt); + Assert.AreEqual(uint.MaxValue, bo5.UInt); + } + } + + [Test] + public void ORA_ParamTestUpdate() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + var bo1 = new ParamTestBo { Id = 1, Double = 0.001, Int = 100, Info = "One", NullableBool = true }; + var bo2 = new ParamTestBo { Id = 2, Double = 0.002, Int = 200, Info = "Two", NullableBool = true, DateTime = DateTime.Now }; + db.Insert(bo1); + db.Insert(bo2); + + bo1.Double = 0.01; + bo1.Int = 10000; + bo1.Info = "OneUpdated"; + bo1.NullableBool = null; + bo1.DateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); + + db.Update(bo1); + + var bo1Check = db.SingleById(1); + + Assert.AreEqual(bo1.Double, bo1Check.Double); + Assert.AreEqual(bo1.Int, bo1Check.Int); + Assert.AreEqual(bo1.Info, bo1Check.Info); + Assert.AreEqual(bo1.DateTime, bo1Check.DateTime); + + + Assert.GreaterOrEqual(DateTime.Now, bo2.DateTime); + + bo2.Info = "TwoUpdated"; + bo2.Int = 9923; + bo2.NullableBool = false; + bo2.DateTime = DateTime.Now.AddDays(10); + + db.Update(bo2); + + var bo2Check = db.SingleById(2); + + Assert.Less(DateTime.Now, bo2.DateTime); + Assert.AreEqual("TwoUpdated", bo2Check.Info); + Assert.AreEqual(9923, bo2Check.Int); + Assert.AreEqual(false, bo2Check.NullableBool); + } + } + + [Test] + public void ORA_ParamTestDelete() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + db.Insert(new ParamTestBo { Id = 1 }); + db.Insert(new ParamTestBo { Id = 2 }); + db.Insert(new ParamTestBo { Id = 3 }); + + Assert.IsNotNull(db.Select(q => q.Id == 1).FirstOrDefault()); + Assert.IsNotNull(db.Select(q => q.Id == 2).FirstOrDefault()); + Assert.IsNotNull(db.Select(q => q.Id == 3).FirstOrDefault()); + + db.DeleteById(1); + db.DeleteById(2); + db.DeleteById(3); + + Assert.IsNull(db.Select(q => q.Id == 1).FirstOrDefault()); + Assert.IsNull(db.Select(q => q.Id == 2).FirstOrDefault()); + Assert.IsNull(db.Select(q => q.Id == 3).FirstOrDefault()); + } + } + + [Test] + public void ORA_ParamTestGetById() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + db.Insert(new ParamTestBo { Id = 1, Info = "Item1" }); + db.Insert(new ParamTestBo { Id = 2, Info = "Item2" }); + db.Insert(new ParamTestBo { Id = 3, Info = "Item3" }); + + Assert.AreEqual("Item1", db.SingleById(1).Info); + Assert.AreEqual("Item2", db.SingleById(2).Info); + Assert.AreEqual("Item3", db.SingleById(3).Info); + } + } + + [Test] + public void ORA_ParamTestSelectLambda() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + LoadParamTestBo(db); + + //select multiple items + Assert.AreEqual(3, db.Select(q => q.NullableBool == null).Count); + Assert.AreEqual(1, db.Select(q => q.NullableBool == true).Count); + Assert.AreEqual(1, db.Select(q => q.NullableBool == false).Count); + Assert.AreEqual(1, db.Select(q => q.UInt == uint.MaxValue).Count); + Assert.AreEqual(4, db.Select(q => q.UInt == null).Count); + + Assert.AreEqual(1, db.Select(q => q.Info == "Two").Count); + Assert.AreEqual(1, db.Select(q => q.Int == 300).Count); + Assert.AreEqual(1, db.Select(q => q.Double == 0.003).Count); + } + } + + private void LoadParamTestBo(IDbConnection db) + { + db.Insert(new ParamTestBo { Id = 1, Double = 0.001, Int = 100, Info = "One", NullableBool = null }); + db.Insert(new ParamTestBo { Id = 2, Double = 0.002, Int = 200, Info = "Two", NullableBool = true }); + db.Insert(new ParamTestBo { Id = 3, Double = 0.003, Int = 300, Info = "Three", NullableBool = false }); + db.Insert(new ParamTestBo { Id = 4, Double = 0.004, Int = 400, Info = "Four", NullableBool = null }); + db.Insert(new ParamTestBo { Id = 5, Double = 0.005, Int = 500, Info = "Five", NullableBool = null, UInt = uint.MaxValue}); + } + + [Test] + public void ORA_ParamTestSelectLambda2() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + LoadParamTestBo(db); + LoadParamRelBo(db); + + Assert.AreEqual(8, db.Select(q => q.Info == "T1").Count); + Assert.AreEqual(2, db.Select(q => q.Info == "T2").Count); + + Assert.AreEqual(3, db.Select(q => q.Info == "T1" && (q.PtId == 2 || q.PtId == 3) ).Count); + } + } + + private void LoadParamRelBo(IDbConnection db) + { + db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 1, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 2, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 2, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 3, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 4, Info = "T1" }); + db.Insert(new ParamRelBo { PtId = 3, Info = "T2" }); + db.Insert(new ParamRelBo { PtId = 4, Info = "T2" }); + } + + [Test] + public void ORA_ParamTestSelectLambdaComplex() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + LoadParamTestBo(db); + LoadParamRelBo(db); + + Assert.AreEqual(10, db.Select(q => Sql.In(q.Info, "T1", "T2")).Count); + Assert.AreEqual(10, db.Select(q => q.Info.StartsWith("T")).Count); + Assert.AreEqual(8, db.Select(q => q.Info.EndsWith("1")).Count); + Assert.AreEqual(10, db.Select(q => q.Info.Contains("T")).Count); + } + } + + [Test] + public void ORA_ParamByteTest() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + db.DeleteAll(); + var bo1 = new ParamByteBo { Id = 1, Data = new byte[] { 1, 25, 43, 3, 1, 66, 82, 23, 11, 44, 66, 22, 52, 62, 76, 19, 30, 91, 4 } }; + + db.Insert(bo1); + var bo1Check = db.Select(s => s.Id == bo1.Id).Single(); + + Assert.AreEqual(bo1.Id, bo1Check.Id); + Assert.AreEqual(bo1.Data, bo1Check.Data); + + db.DeleteAll(); + } + } + + [Test] + public void ORA_ReservedNameLevelAsAlias_Test() + { + using (var db = OpenDbConnection()) + { + DropAndCreateTables(db); + + var row = new ParamLevelAsAlias { Id = 2, ApprovalLevel = 212218 }; + db.Insert(row); + + row.ApprovalLevel = 676; + db.Update(row); + } + } + + //[ImportMany(typeof(IParam))] +// ReSharper disable UnassignedField.Compiler + private IEnumerable _reservedNameParams => typeof(IParam).Assembly.GetExportedTypes() + .Where(x => x.HasInterface(typeof(IParam))).Select(x => Activator.CreateInstance(x) as IParam).ToArray(); +// ReSharper restore UnassignedField.Compiler + + [Test] + public void ORA_ReservedNames_Test() + { + ResolveReservedNameParameters(); + using (var db = OpenDbConnection()) + { + foreach (var param in _reservedNameParams) + { + try + { + db.CreateTable(true, param.GetType()); + param.Id = 123; + param.SetValue(1000); + param.InsertDb(db); + param.SetValue(2343); + param.UpdateDb(db); + } + catch (Exception ex) + { + throw new Exception( + string.Format("Unable to process Oracle parameter of type: {0}", param.GetType()), ex); + } + } + } + } + + private void ResolveReservedNameParameters() + { +// var catalog = new AssemblyCatalog(typeof(IParam).Assembly); +// var container = new CompositionContainer(catalog); +// container.ComposeParts(this); + } + + //[InheritedExport] + public interface IParam + { + int Id { get; set; } + void InsertDb(IDbConnection db); + void UpdateDb(IDbConnection db); + void SetValue(int value); + } + + public abstract class Param: IParam + { + public int Id { get; set; } + public abstract void SetValue(int value); + public abstract T GetObject(); + public void InsertDb(IDbConnection db) { db.Insert(GetObject()); } + public void UpdateDb(IDbConnection db) { db.Update(GetObject()); } + } + + public class ParamComment : Param + { + public int Comment { get; set; } + public override void SetValue(int value) { Comment = value; } + public override ParamComment GetObject() { return this; } + } + + public class ParamOrder : Param + { + public int Order { get; set; } + public override void SetValue(int value) { Order = value; } + public override ParamOrder GetObject() { return this; } + } + + public class ParamLeft : Param + { + public int Left { get; set; } + public override void SetValue(int value) { Left = value; } + public override ParamLeft GetObject() { return this; } + } + + public class ParamUser : Param + { + public int User { get; set; } + public override void SetValue(int value) { User = value; } + public override ParamUser GetObject() { return this; } + } + + public class ParamPassword : Param + { + public int Password { get; set; } + public override void SetValue(int value) { Password = value; } + public override ParamPassword GetObject() { return this; } + } + + public class ParamActive : Param + { + public int Active { get; set; } + public override void SetValue(int value) { Active = value; } + public override ParamActive GetObject() { return this; } + } + + public class ParamDouble : Param + { + public int Double { get; set; } + public override void SetValue(int value) { Double = value; } + public override ParamDouble GetObject() { return this; } + } + + public class ParamFloat : Param + { + public int Float { get; set; } + public override void SetValue(int value) { Float = value; } + public override ParamFloat GetObject() { return this; } + } + + public class ParamDecimal : Param + { + public int Decimal { get; set; } + public override void SetValue(int value) { Decimal = value; } + public override ParamDecimal GetObject() { return this; } + } + + public class ParamString : Param + { + public int String { get; set; } + public override void SetValue(int value) { String = value; } + public override ParamString GetObject() { return this; } + } + + public class ParamDate : Param + { + public int Date { get; set; } + public override void SetValue(int value) { Date = value; } + public override ParamDate GetObject() { return this; } + } + + public class ParamDateTime : Param + { + public int DateTime { get; set; } + public override void SetValue(int value) { DateTime = value; } + public override ParamDateTime GetObject() { return this; } + } + + public class ParamType : Param + { + public int Type { get; set; } + public override void SetValue(int value) { Type = value; } + public override ParamType GetObject() { return this; } + } + + public class ParamTimestamp : Param + { + public int Timestamp { get; set; } + public override void SetValue(int value) { Timestamp = value; } + public override ParamTimestamp GetObject() { return this; } + } + + public class ParamIndex : Param + { + public int Index { get; set; } + public override void SetValue(int value) { Index = value; } + public override ParamIndex GetObject() { return this; } + } + + public class ParamAccess : Param + { + public int Access { get; set; } + public override void SetValue(int value) { Access = value; } + public override ParamAccess GetObject() { return this; } + } + + public class ParamDefault : Param + { + public int Default { get; set; } + public override void SetValue(int value) { Default = value; } + public override ParamDefault GetObject() { return this; } + } + + public class ParamInteger : Param + { + public int Integer { get; set; } + public override void SetValue(int value) { Integer = value; } + public override ParamInteger GetObject() { return this; } + } + + public class ParamOnline : Param + { + public int Online { get; set; } + public override void SetValue(int value) { Online = value; } + public override ParamOnline GetObject() { return this; } + } + + public class ParamStart : Param + { + public int Start { get; set; } + public override void SetValue(int value) { Start = value; } + public override ParamStart GetObject() { return this; } + } + + public class ParamAdd : Param + { + public int Add { get; set; } + public override void SetValue(int value) { Add = value; } + public override ParamAdd GetObject() { return this; } + } + + public class ParamDelete : Param + { + public int Delete { get; set; } + public override void SetValue(int value) { Delete = value; } + public override ParamDelete GetObject() { return this; } + } + + public class ParamIntersect : Param + { + public int Intersect { get; set; } + public override void SetValue(int value) { Intersect = value; } + public override ParamIntersect GetObject() { return this; } + } + + public class ParamOption : Param + { + public int Option { get; set; } + public override void SetValue(int value) { Option = value; } + public override ParamOption GetObject() { return this; } + } + + public class ParamSuccessful : Param + { + public int Successful { get; set; } + public override void SetValue(int value) { Successful = value; } + public override ParamSuccessful GetObject() { return this; } + } + + public class ParamDesc : Param + { + public int Desc { get; set; } + public override void SetValue(int value) { Desc = value; } + public override ParamDesc GetObject() { return this; } + } + + public class ParamAll : Param + { + public int All { get; set; } + public override void SetValue(int value) { All = value; } + public override ParamAll GetObject() { return this; } + } + + public class ParamInto : Param + { + public int Into { get; set; } + public override void SetValue(int value) { Into = value; } + public override ParamInto GetObject() { return this; } + } + + public class ParamLevel : Param + { + public int Level { get; set; } + public override void SetValue(int value) { Level = value; } + public override ParamLevel GetObject() { return this; } + } + + public class ParamOr : Param + { + public int Or { get; set; } + public override void SetValue(int value) { Or = value; } + public override ParamOr GetObject() { return this; } + } + + public class ParamSynonym : Param + { + public int Synonym { get; set; } + public override void SetValue(int value) { Synonym = value; } + public override ParamSynonym GetObject() { return this; } + } + + public class ParamAlter : Param + { + public int Alter { get; set; } + public override void SetValue(int value) { Alter = value; } + public override ParamAlter GetObject() { return this; } + } + + public class ParamDistinct : Param + { + public int Distinct { get; set; } + public override void SetValue(int value) { Distinct = value; } + public override ParamDistinct GetObject() { return this; } + } + + public class ParamIs : Param + { + public int Is { get; set; } + public override void SetValue(int value) { Is = value; } + public override ParamIs GetObject() { return this; } + } + + public class ParamSysdate : Param + { + public int Sysdate { get; set; } + public override void SetValue(int value) { Sysdate = value; } + public override ParamSysdate GetObject() { return this; } + } + + public class ParamAnd : Param + { + public int And { get; set; } + public override void SetValue(int value) { And = value; } + public override ParamAnd GetObject() { return this; } + } + + public class ParamDrop : Param + { + public int Drop { get; set; } + public override void SetValue(int value) { Drop = value; } + public override ParamDrop GetObject() { return this; } + } + + public class ParamPctFree : Param + { + public int PctFree { get; set; } + public override void SetValue(int value) { PctFree = value; } + public override ParamPctFree GetObject() { return this; } + } + + public class ParamTable : Param + { + public int Table { get; set; } + public override void SetValue(int value) { Table = value; } + public override ParamTable GetObject() { return this; } + } + + public class ParamAny : Param + { + public int Any { get; set; } + public override void SetValue(int value) { Any = value; } + public override ParamAny GetObject() { return this; } + } + + public class ParamElse : Param + { + public int Else { get; set; } + public override void SetValue(int value) { Else = value; } + public override ParamElse GetObject() { return this; } + } + + public class ParamLike : Param + { + public int Like { get; set; } + public override void SetValue(int value) { Like = value; } + public override ParamLike GetObject() { return this; } + } + + public class ParamPrior : Param + { + public int Prior { get; set; } + public override void SetValue(int value) { Prior = value; } + public override ParamPrior GetObject() { return this; } + } + + public class ParamThen : Param + { + public int Then { get; set; } + public override void SetValue(int value) { Then = value; } + public override ParamThen GetObject() { return this; } + } + + public class ParamAs : Param + { + public int As { get; set; } + public override void SetValue(int value) { As = value; } + public override ParamAs GetObject() { return this; } + } + + public class ParamExclusive : Param + { + public int Exclusive { get; set; } + public override void SetValue(int value) { Exclusive = value; } + public override ParamExclusive GetObject() { return this; } + } + + public class ParamLock : Param + { + public int Lock { get; set; } + public override void SetValue(int value) { Lock = value; } + public override ParamLock GetObject() { return this; } + } + + public class ParamPrivileges : Param + { + public int Privileges { get; set; } + public override void SetValue(int value) { Privileges = value; } + public override ParamPrivileges GetObject() { return this; } + } + + public class ParamTo : Param + { + public int To { get; set; } + public override void SetValue(int value) { To = value; } + public override ParamTo GetObject() { return this; } + } + + public class ParamAsc : Param + { + public int Asc { get; set; } + public override void SetValue(int value) { Asc = value; } + public override ParamAsc GetObject() { return this; } + } + + public class ParamExists : Param + { + public int Exists { get; set; } + public override void SetValue(int value) { Exists = value; } + public override ParamExists GetObject() { return this; } + } + + public class ParamLong : Param + { + public int Long { get; set; } + public override void SetValue(int value) { Long = value; } + public override ParamLong GetObject() { return this; } + } + + public class ParamPublic : Param + { + public int Public { get; set; } + public override void SetValue(int value) { Public = value; } + public override ParamPublic GetObject() { return this; } + } + + public class ParamTrigger : Param + { + public int Trigger { get; set; } + public override void SetValue(int value) { Trigger = value; } + public override ParamTrigger GetObject() { return this; } + } + + public class ParamAudit : Param + { + public int Audit { get; set; } + public override void SetValue(int value) { Audit = value; } + public override ParamAudit GetObject() { return this; } + } + + public class ParamFile : Param + { + public int File { get; set; } + public override void SetValue(int value) { File = value; } + public override ParamFile GetObject() { return this; } + } + + public class ParamMaxExtents : Param + { + public int MaxExtents { get; set; } + public override void SetValue(int value) { MaxExtents = value; } + public override ParamMaxExtents GetObject() { return this; } + } + + public class ParamRaw : Param + { + public int Raw { get; set; } + public override void SetValue(int value) { Raw = value; } + public override ParamRaw GetObject() { return this; } + } + + public class ParamUid : Param + { + public int Uid { get; set; } + public override void SetValue(int value) { Uid = value; } + public override ParamUid GetObject() { return this; } + } + + public class ParamBetween : Param + { + public int Between { get; set; } + public override void SetValue(int value) { Between = value; } + public override ParamBetween GetObject() { return this; } + } + + public class ParamMinus : Param + { + public int Minus { get; set; } + public override void SetValue(int value) { Minus = value; } + public override ParamMinus GetObject() { return this; } + } + + public class ParamRename : Param + { + public int Rename { get; set; } + public override void SetValue(int value) { Rename = value; } + public override ParamRename GetObject() { return this; } + } + + public class ParamUnion : Param + { + public int Union { get; set; } + public override void SetValue(int value) { Union = value; } + public override ParamUnion GetObject() { return this; } + } + + public class ParamBy : Param + { + public int By { get; set; } + public override void SetValue(int value) { By = value; } + public override ParamBy GetObject() { return this; } + } + + public class ParamFor : Param + { + public int For { get; set; } + public override void SetValue(int value) { For = value; } + public override ParamFor GetObject() { return this; } + } + + public class ParamMlsLabel : Param + { + public int MlsLabel { get; set; } + public override void SetValue(int value) { MlsLabel = value; } + public override ParamMlsLabel GetObject() { return this; } + } + + public class ParamResource : Param + { + public int Resource { get; set; } + public override void SetValue(int value) { Resource = value; } + public override ParamResource GetObject() { return this; } + } + + public class ParamUnique : Param + { + public int Unique { get; set; } + public override void SetValue(int value) { Unique = value; } + public override ParamUnique GetObject() { return this; } + } + + public class ParamChar : Param + { + public int Char { get; set; } + public override void SetValue(int value) { Char = value; } + public override ParamChar GetObject() { return this; } + } + + public class ParamFrom : Param + { + public int From { get; set; } + public override void SetValue(int value) { From = value; } + public override ParamFrom GetObject() { return this; } + } + + public class ParamMode : Param + { + public int Mode { get; set; } + public override void SetValue(int value) { Mode = value; } + public override ParamMode GetObject() { return this; } + } + + public class ParamRevoke : Param + { + public int Revoke { get; set; } + public override void SetValue(int value) { Revoke = value; } + public override ParamRevoke GetObject() { return this; } + } + + public class ParamUpdate : Param + { + public int Update { get; set; } + public override void SetValue(int value) { Update = value; } + public override ParamUpdate GetObject() { return this; } + } + + public class ParamCheck : Param + { + public int Check { get; set; } + public override void SetValue(int value) { Check = value; } + public override ParamCheck GetObject() { return this; } + } + + public class ParamGrant : Param + { + public int Grant { get; set; } + public override void SetValue(int value) { Grant = value; } + public override ParamGrant GetObject() { return this; } + } + + public class ParamModify : Param + { + public int Modify { get; set; } + public override void SetValue(int value) { Modify = value; } + public override ParamModify GetObject() { return this; } + } + + public class ParamRow : Param + { + public int Row { get; set; } + public override void SetValue(int value) { Row = value; } + public override ParamRow GetObject() { return this; } + } + + public class ParamCluster : Param + { + public int Cluster { get; set; } + public override void SetValue(int value) { Cluster = value; } + public override ParamCluster GetObject() { return this; } + } + + public class ParamGroup : Param + { + public int Group { get; set; } + public override void SetValue(int value) { Group = value; } + public override ParamGroup GetObject() { return this; } + } + + public class ParamNoAudit : Param + { + public int NoAudit { get; set; } + public override void SetValue(int value) { NoAudit = value; } + public override ParamNoAudit GetObject() { return this; } + } + + public class ParamRowId : Param + { + public int RowId { get; set; } + public override void SetValue(int value) { RowId = value; } + public override ParamRowId GetObject() { return this; } + } + + public class ParamValidate : Param + { + public int Validate { get; set; } + public override void SetValue(int value) { Validate = value; } + public override ParamValidate GetObject() { return this; } + } + + public class ParamColumn : Param + { + public int Column { get; set; } + public override void SetValue(int value) { Column = value; } + public override ParamColumn GetObject() { return this; } + } + + public class ParamHaving : Param + { + public int Having { get; set; } + public override void SetValue(int value) { Having = value; } + public override ParamHaving GetObject() { return this; } + } + + public class ParamNoCompress : Param + { + public int NoCompress { get; set; } + public override void SetValue(int value) { NoCompress = value; } + public override ParamNoCompress GetObject() { return this; } + } + + public class ParamRowNum : Param + { + public int RowNum { get; set; } + public override void SetValue(int value) { RowNum = value; } + public override ParamRowNum GetObject() { return this; } + } + + public class ParamValues : Param + { + public int Values { get; set; } + public override void SetValue(int value) { Values = value; } + public override ParamValues GetObject() { return this; } + } + + public class ParamIdentified : Param + { + public int Identified { get; set; } + public override void SetValue(int value) { Identified = value; } + public override ParamIdentified GetObject() { return this; } + } + + public class ParamNot : Param + { + public int Not { get; set; } + public override void SetValue(int value) { Not = value; } + public override ParamNot GetObject() { return this; } + } + + public class ParamRows : Param + { + public int Rows { get; set; } + public override void SetValue(int value) { Rows = value; } + public override ParamRows GetObject() { return this; } + } + + public class ParamVarchar : Param + { + public int Varchar { get; set; } + public override void SetValue(int value) { Varchar = value; } + public override ParamVarchar GetObject() { return this; } + } + + public class ParamCompress : Param + { + public int Compress { get; set; } + public override void SetValue(int value) { Compress = value; } + public override ParamCompress GetObject() { return this; } + } + + public class ParamImmediate : Param + { + public int Immediate { get; set; } + public override void SetValue(int value) { Immediate = value; } + public override ParamImmediate GetObject() { return this; } + } + + public class ParamNoWait : Param + { + public int NoWait { get; set; } + public override void SetValue(int value) { NoWait = value; } + public override ParamNoWait GetObject() { return this; } + } + + public class ParamSelect : Param + { + public int Select { get; set; } + public override void SetValue(int value) { Select = value; } + public override ParamSelect GetObject() { return this; } + } + + public class ParamVarchar2 : Param + { + public int Varchar2 { get; set; } + public override void SetValue(int value) { Varchar2 = value; } + public override ParamVarchar2 GetObject() { return this; } + } + + public class ParamConnect : Param + { + public int Connect { get; set; } + public override void SetValue(int value) { Connect = value; } + public override ParamConnect GetObject() { return this; } + } + + public class ParamIn : Param + { + public int In { get; set; } + public override void SetValue(int value) { In = value; } + public override ParamIn GetObject() { return this; } + } + + public class ParamNull : Param + { + public int Null { get; set; } + public override void SetValue(int value) { Null = value; } + public override ParamNull GetObject() { return this; } + } + + public class ParamSession : Param + { + public int Session { get; set; } + public override void SetValue(int value) { Session = value; } + public override ParamSession GetObject() { return this; } + } + + public class ParamView : Param + { + public int View { get; set; } + public override void SetValue(int value) { View = value; } + public override ParamView GetObject() { return this; } + } + + public class ParamCreate : Param + { + public int Create { get; set; } + public override void SetValue(int value) { Create = value; } + public override ParamCreate GetObject() { return this; } + } + + public class ParamIncrement : Param + { + public int Increment { get; set; } + public override void SetValue(int value) { Increment = value; } + public override ParamIncrement GetObject() { return this; } + } + + public class ParamNumber : Param + { + public int Number { get; set; } + public override void SetValue(int value) { Number = value; } + public override ParamNumber GetObject() { return this; } + } + + public class ParamSet : Param + { + public int Set { get; set; } + public override void SetValue(int value) { Set = value; } + public override ParamSet GetObject() { return this; } + } + + public class ParamWhenever : Param + { + public int Whenever { get; set; } + public override void SetValue(int value) { Whenever = value; } + public override ParamWhenever GetObject() { return this; } + } + + public class ParamCurrent : Param + { + public int Current { get; set; } + public override void SetValue(int value) { Current = value; } + public override ParamCurrent GetObject() { return this; } + } + + public class ParamOf : Param + { + public int Of { get; set; } + public override void SetValue(int value) { Of = value; } + public override ParamOf GetObject() { return this; } + } + + public class ParamShare : Param + { + public int Share { get; set; } + public override void SetValue(int value) { Share = value; } + public override ParamShare GetObject() { return this; } + } + + public class ParamWhere : Param + { + public int Where { get; set; } + public override void SetValue(int value) { Where = value; } + public override ParamWhere GetObject() { return this; } + } + + public class ParamInitial : Param + { + public int Initial { get; set; } + public override void SetValue(int value) { Initial = value; } + public override ParamInitial GetObject() { return this; } + } + + public class ParamOffline : Param + { + public int Offline { get; set; } + public override void SetValue(int value) { Offline = value; } + public override ParamOffline GetObject() { return this; } + } + + public class ParamSize : Param + { + public int Size { get; set; } + public override void SetValue(int value) { Size = value; } + public override ParamSize GetObject() { return this; } + } + + public class ParamWith : Param + { + public int With { get; set; } + public override void SetValue(int value) { With = value; } + public override ParamWith GetObject() { return this; } + } + + public class ParamInsert : Param + { + public int Insert { get; set; } + public override void SetValue(int value) { Insert = value; } + public override ParamInsert GetObject() { return this; } + } + + public class ParamOn : Param + { + public int On { get; set; } + public override void SetValue(int value) { On = value; } + public override ParamOn GetObject() { return this; } + } + + public class ParamSmallint : Param + { + public int Smallint { get; set; } + public override void SetValue(int value) { Smallint = value; } + public override ParamSmallint GetObject() { return this; } + } + + public class ParamTestBo + { + public int Id { get; set; } + public string Info { get; set; } + public int Int { get; set; } + public double Double { get; set; } + public bool? NullableBool { get; set; } + public DateTime? DateTime { get; set; } + public uint? UInt { get; set; } + } + + public class ParamRelBo + { + [Sequence("SEQ_PARAMTESTREL_ID")] + [PrimaryKey] + [Alias("ParamRel_Id")] + public int Id { get; set; } + [ForeignKey(typeof(ParamTestBo))] + public int PtId { get; set; } + + [Alias("InfoStr")] + public string Info { get; set; } + } + + public class ParamByteBo + { + public int Id { get; set; } + public byte[] Data { get; set; } + } + + public class ParamLevelAsAlias + { + public int Id { get; set; } + + [Alias("Level")] + public int ApprovalLevel { get; set; } + } + } +} diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/OracleSyntaxTests.cs b/tests/ServiceStack.OrmLite.Oracle.Tests/OracleSyntaxTests.cs similarity index 82% rename from src/ServiceStack.OrmLite.Oracle.Tests/OracleSyntaxTests.cs rename to tests/ServiceStack.OrmLite.Oracle.Tests/OracleSyntaxTests.cs index 869eff9cb..e724c4628 100644 --- a/src/ServiceStack.OrmLite.Oracle.Tests/OracleSyntaxTests.cs +++ b/tests/ServiceStack.OrmLite.Oracle.Tests/OracleSyntaxTests.cs @@ -13,7 +13,7 @@ public void can_generate_correct_paging_if_first_column_must_be_quoted() using(var db = OpenDbConnection()) { db.CreateTable(true); - var noRows = db.Select(ev => ev.Limit(100)); + var noRows = db.Select(db.From().Limit(100)); Assert.AreEqual(0, noRows.Count()); @@ -21,7 +21,7 @@ public void can_generate_correct_paging_if_first_column_must_be_quoted() db.Insert(new FirstColMustBeQuoted { COMMENT = "row #" + i }); } - var hundredRows = db.Select(ev => ev.Limit(100)); + var hundredRows = db.Select(db.From().Limit(100)); Assert.AreEqual(100, hundredRows.Count()); } } @@ -32,7 +32,7 @@ public void can_generate_correct_paging_if_first_column_dont_have_to_be_quoted() using(var db = OpenDbConnection()) { db.CreateTable(true); - var noRows = db.Select(ev => ev.Limit(100)); + var noRows = db.Select(db.From().Limit(100)); Assert.AreEqual(0, noRows.Count()); @@ -40,7 +40,7 @@ public void can_generate_correct_paging_if_first_column_dont_have_to_be_quoted() db.Insert(new FirstColNoQuotes { COMMENT = "row #" + i }); } - var hundredRows = db.Select(ev => ev.Limit(100)); + var hundredRows = db.Select(db.From().Limit(100)); Assert.AreEqual(100, hundredRows.Count()); } } @@ -51,7 +51,7 @@ public void can_generate_correct_paging_if_TABLE_NAME_must_be_quoted_and_first_c using(var db = OpenDbConnection()) { db.CreateTable(true); - var noRows = db.Select(ev => ev.Limit(100)); + var noRows = db.Select(db.From().Limit(100)); Assert.AreEqual(0, noRows.Count()); @@ -59,7 +59,7 @@ public void can_generate_correct_paging_if_TABLE_NAME_must_be_quoted_and_first_c db.Insert(new COMMENT_first { COMMENT = "COMMENT row #" + i }); } - var hundredRows = db.Select(ev => ev.Limit(100)); + var hundredRows = db.Select(db.From().Limit(100)); Assert.AreEqual(100, hundredRows.Count()); } } @@ -70,7 +70,7 @@ public void can_generate_correct_paging_if_TABLE_NAME_must_be_quoted_and_first_c using(var db = OpenDbConnection()) { db.CreateTable(true); - var noRows = db.Select(ev => ev.Limit(100)); + var noRows = db.Select(db.From().Limit(100)); Assert.AreEqual(0, noRows.Count()); @@ -78,7 +78,7 @@ public void can_generate_correct_paging_if_TABLE_NAME_must_be_quoted_and_first_c db.Insert(new COMMENT_other { COMMENT = "COMMENT row #" + i }); } - var hundredRows = db.Select(ev => ev.Limit(100)); + var hundredRows = db.Select(db.From().Limit(100)); Assert.AreEqual(100, hundredRows.Count()); } } diff --git a/src/ServiceStack.OrmLite.Oracle.Tests/OrmLiteExecuteNonQueryTests.cs b/tests/ServiceStack.OrmLite.Oracle.Tests/OrmLiteExecuteNonQueryTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.Oracle.Tests/OrmLiteExecuteNonQueryTests.cs rename to tests/ServiceStack.OrmLite.Oracle.Tests/OrmLiteExecuteNonQueryTests.cs diff --git a/tests/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj b/tests/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj new file mode 100644 index 000000000..eb58b0658 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Oracle.Tests/ServiceStack.OrmLite.Oracle.Tests.csproj @@ -0,0 +1,52 @@ + + + net472 + + ServiceStack.OrmLite.Oracle.Tests + ServiceStack.OrmLite.Oracle.Tests + default + + + + $(DefineConstants);NETCORE_SUPPORT;NETCORE + + + + $(DefineConstants);NET45 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Oracle.Tests/app.config b/tests/ServiceStack.OrmLite.Oracle.Tests/app.config new file mode 100644 index 000000000..f21d477fa --- /dev/null +++ b/tests/ServiceStack.OrmLite.Oracle.Tests/app.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/CreatePostgreSQLTablesTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/CreatePostgreSQLTablesTests.cs new file mode 100644 index 000000000..350c13c92 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/CreatePostgreSQLTablesTests.cs @@ -0,0 +1,131 @@ +using System; +using Npgsql; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class CreatePostgreSQLTablesTests : OrmLiteProvidersTestBase + { + public CreatePostgreSQLTablesTests(DialectContext context) : base(context) {} + + [Test] + public void DropAndCreateTable_DropsTableAndCreatesTable() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.CreateTable(); + db.Insert(new TestData { Id = Guid.NewGuid() }); + db.DropAndCreateTable(); + db.Insert(new TestData { Id = Guid.NewGuid() }); + } + } + + + [Test] + public void can_create_tables_after_UseUnicode_or_DefaultStringLength_changed() + { + //first one passes + _reCreateTheTable(); + + //all of these pass now: + var stringConverter = DialectProvider.GetStringConverter(); + stringConverter.UseUnicode = true; + _reCreateTheTable(); + + stringConverter.UseUnicode = false; + _reCreateTheTable(); + + stringConverter.StringLength = 98765; + + _reCreateTheTable(); + } + + private void _reCreateTheTable() + { + using(var db = OpenDbConnection()) { + db.CreateTable(true); + } + } + + private class CreatePostgreSQLTablesTests_dummy_table + { + [AutoIncrement] + public int Id { get; set; } + + public String StringNoExplicitLength { get; set; } + + [StringLength(100)] + public String String100Characters { get; set; } + } + + [Test] + public void can_create_same_table_in_multiple_schemas_based_on_conn_string_search_path() + { + NpgsqlConnectionStringBuilder builder; + var schema1 = "postgres_schema_1"; + var schema2 = "postgres_schema_2"; + using (var db = OpenDbConnection()) + { + builder = new NpgsqlConnectionStringBuilder(db.ConnectionString); + CreateSchemaIfNotExists(db, schema1); + CreateSchemaIfNotExists(db, schema2); + + builder.SearchPath = schema1; + DbFactory.RegisterConnection(schema1, builder.ToString(), DialectProvider); + builder.SearchPath = schema2; + DbFactory.RegisterConnection(schema2, builder.ToString(), DialectProvider); + } + + using (var dbS1 = DbFactory.OpenDbConnection(schema1)) + { + dbS1.DropTable(); + dbS1.CreateTable(); + Assert.That(dbS1.Count(), Is.EqualTo(0)); + dbS1.DropTable(); + } + + using (var dbS2 = DbFactory.OpenDbConnection(schema2)) + { + dbS2.DropTable(); + dbS2.CreateTable(); + Assert.That(dbS2.Count(), Is.EqualTo(0)); + dbS2.DropTable(); + } + + } + + public class TestData + { + [PrimaryKey] + public Guid Id { get; set; } + + public string Name { get; set; } + + public string Surname { get; set; } + } + + private void CreateSchemaIfNotExists(System.Data.IDbConnection db, string name) + { + string createSchemaSQL = @"DO $$ +BEGIN + + IF NOT EXISTS( + SELECT 1 + FROM INFORMATION_SCHEMA.SCHEMATA + WHERE SCHEMA_NAME = '{0}' + ) + THEN + EXECUTE 'CREATE SCHEMA ""{0}""'; + END IF; + +END +$$;" + .Fmt(name); + db.ExecuteSql(createSchemaSQL); + } + } +} diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/CustomSqlTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/CustomSqlTests.cs new file mode 100644 index 000000000..0e1007f02 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/CustomSqlTests.cs @@ -0,0 +1,64 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + + public class CustomSqlUser + { + [AutoIncrement] + public int Id { get; set; } + + public string Email { get; set; } + + [CustomInsert("crypt({0}, gen_salt('bf'))"), + CustomUpdate("crypt({0}, gen_salt('bf'))")] + public string Password { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class CustomSqlTests : OrmLiteProvidersTestBase + { + public CustomSqlTests(DialectContext context) : base(context) { } + + [Test] + public void Can_insert_CustomInsert() + { + OrmLiteUtils.PrintSql(); + + using var db = OpenDbConnection(); + // db.ExecuteSql("CREATE extension pgcrypto"); + db.DropAndCreateTable(); + + var user = new CustomSqlUser { + Email = "user@email.com", + Password = "secret" + }; + db.Insert(user); + + var escapedSecret = db.Dialect().GetQuotedValue("secret"); + var q = db.From() + .Where(x => x.Password == Sql.Custom($"crypt({escapedSecret}, password)")); + var row = db.Single(q); + Assert.That(row.Email, Is.EqualTo(user.Email)); + + row = db.Single(db.From() + .Where(x => x.Password == Sql.Custom("crypt({0}, password)"),"secret")); + Assert.That(row.Email, Is.EqualTo(user.Email)); + + row = db.Single(db.From() + .Where("password = crypt({0}, password)", "secret")); + Assert.That(row.Email, Is.EqualTo(user.Email)); + + db.UpdateOnly(() => new CustomSqlUser {Password = "newsecret"}, + where: x => x.Email == user.Email); + + q = db.From() + .Where(x => x.Password == Sql.Custom("crypt('newsecret', password)")); + row = db.Single(q); + Assert.That(row.Email, Is.EqualTo(user.Email)); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/EnumTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/EnumTests.cs new file mode 100644 index 000000000..4cb504ca5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/EnumTests.cs @@ -0,0 +1,107 @@ +using System.Linq; +using System.Runtime.InteropServices.ComTypes; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class EnumTests : OrmLiteProvidersTestBase + { + public EnumTests(DialectContext context) : base(context) {} + + [Test] + public void CanCreateTable() + { + OpenDbConnection().CreateTable(true); + } + + [Test] + public void CanStoreEnumValue() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + } + } + + [Test] + public void CanGetEnumValue() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; + con.Save(obj); + var target = con.SingleById(obj.Id); + Assert.AreEqual(obj.Id, target.Id); + Assert.AreEqual(obj.EnumValue, target.EnumValue); + } + } + + [Test] + public void CanQueryByEnumValue_using_select_with_expression() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Select(q => q.EnumValue == SomeEnum.Value1); + + Assert.AreEqual(2, target.Count()); + } + } + + [Test] + public void CanQueryByEnumValue_using_select_with_string() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Select("\"enum_value\" = @value", new { value = SomeEnum.Value1 }); + + Assert.AreEqual(2, target.Count()); + } + } + + [Ignore("Where using anon type needs to be fixed")] + [Test] + public void CanQueryByEnumValue_using_where_with_AnonType() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Where(new { EnumValue = SomeEnum.Value1 }); + + Assert.AreEqual(2, target.Count()); + } + } + + } + + public enum SomeEnum + { + Value1, + Value2, + Value3 + } + + public class TypeWithEnum + { + public int Id { get; set; } + public SomeEnum EnumValue { get; set; } + } + +} diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AdditiveExpressionsTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AdditiveExpressionsTest.cs new file mode 100644 index 000000000..ab99b5c38 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AdditiveExpressionsTest.cs @@ -0,0 +1,154 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class AdditiveExpressionsTest : ExpressionsTestBase + { + public AdditiveExpressionsTest(DialectContext context) : base(context) {} + + [Test] + public void Can_select_constant_add_expression() + { + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 4 + 3); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_constant_subtract_expression() + { + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 10 - 3); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_variable_add_expression() + { +// ReSharper disable ConvertToConstant.Local + var a = 4; + var b = 3; +// ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == a + b); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_variable_subtract_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = 10; + var b = 3; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == a - b); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_method_add_expression() + { + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == GetValue(4) + GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_method_subtract_expression() + { + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == GetValue(10) - GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/Author.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/Author.cs similarity index 100% rename from src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/Author.cs rename to tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/Author.cs diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AuthorUseCase.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AuthorUseCase.cs new file mode 100644 index 000000000..010769568 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/AuthorUseCase.cs @@ -0,0 +1,500 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class AuthorUseCase : OrmLiteProvidersTestBase + { + private List authors; + + public AuthorUseCase(DialectContext context) : base(context) + { + authors = new List + { + new Author + { + Name = "Demis Bellot", + Birthday = DateTime.Today.AddYears(-20), + Active = true, + Earnings = 99.9m, + Comments = "CSharp books", + Rate = 10, + City = "London" + }, + new Author + { + Name = "Angel Colmenares", + Birthday = DateTime.Today.AddYears(-25), + Active = true, + Earnings = 50.0m, + Comments = "CSharp books", + Rate = 5, + City = "Bogota" + }, + new Author + { + Name = "Adam Witco", + Birthday = DateTime.Today.AddYears(-20), + Active = true, + Earnings = 80.0m, + Comments = "Math Books", + Rate = 9, + City = "London" + }, + new Author + { + Name = "Claudia Espinel", + Birthday = DateTime.Today.AddYears(-23), + Active = true, + Earnings = 60.0m, + Comments = "Cooking books", + Rate = 10, + City = "Bogota" + }, + new Author + { + Name = "Libardo Pajaro", + Birthday = DateTime.Today.AddYears(-25), + Active = true, + Earnings = 80.0m, + Comments = "CSharp books", + Rate = 9, + City = "Bogota" + }, + new Author + { + Name = "Jorge Garzon", + Birthday = DateTime.Today.AddYears(-28), + Active = true, + Earnings = 70.0m, + Comments = "CSharp books", + Rate = 9, + City = "Bogota" + }, + new Author + { + Name = "Alejandro Isaza", + Birthday = DateTime.Today.AddYears(-20), + Active = true, + Earnings = 70.0m, + Comments = "Java books", + Rate = 0, + City = "Bogota" + }, + new Author + { + Name = "Wilmer Agamez", + Birthday = DateTime.Today.AddYears(-20), + Active = true, + Earnings = 30.0m, + Comments = "Java books", + Rate = 0, + City = "Cartagena" + }, + new Author + { + Name = "Rodger Contreras", + Birthday = DateTime.Today.AddYears(-25), + Active = true, + Earnings = 90.0m, + Comments = "CSharp books", + Rate = 8, + City = "Cartagena" + }, + new Author + { + Name = "Chuck Benedict", + Birthday = DateTime.Today.AddYears(-22), + Active = true, + Earnings = 85.5m, + Comments = "CSharp books", + Rate = 8, + City = "London" + }, + new Author + { + Name = "James Benedict II", + Birthday = DateTime.Today.AddYears(-22), + Active = true, + Earnings = 85.5m, + Comments = "Java books", + Rate = 5, + City = "Berlin" + }, + new Author + { + Name = "Ethan Brown", + Birthday = DateTime.Today.AddYears(-20), + Active = true, + Earnings = 45.0m, + Comments = "CSharp books", + Rate = 5, + City = "Madrid" + }, + new Author + { + Name = "Xavi Garzon", + Birthday = DateTime.Today.AddYears(-22), + Active = true, + Earnings = 75.0m, + Comments = "CSharp books", + Rate = 9, + City = "Madrid" + }, + new Author + { + Name = "Luis garzon", + Birthday = DateTime.Today.AddYears(-22), + Active = true, + Earnings = 85.0m, + Comments = "CSharp books", + Rate = 10, + City = "Mexico", + LastActivity = DateTime.Today + } + }; + } + + [SetUp] + public void Setup() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.SaveAll(authors); + } + } + + [Test] + public void AuthorUsesCases() + { + var ev = DialectProvider.SqlExpression(); + + using (var db = OpenDbConnection()) + { + int year = DateTime.Today.AddYears(-20).Year; + var lastDay = new DateTime(year, 12, 31); + int expected = 5; + + ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + List result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(db.From().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + Assert.AreEqual(expected, result.Count); + Author a = new Author { Birthday = lastDay }; + result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); + Assert.AreEqual(expected, result.Count); + + // select authors from London, Berlin and Madrid : 6 + expected = 6; + //Sql.In can take params object[] + var city = "Berlin"; + ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); + Assert.AreEqual(expected, result.Count); + + // select authors from Bogota and Cartagena : 7 + expected = 7; + //... or Sql.In can take List + city = "Bogota"; + List cities = new List(); + cities.Add(city); + cities.Add("Cartagena"); + ev.Where().Where(rn => Sql.In(rn.City, cities)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); + Assert.AreEqual(expected, result.Count); + + + // select authors which name starts with A + expected = 3; + ev.Where().Where(rn => rn.Name.StartsWith("A")); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.StartsWith("A")); + Assert.AreEqual(expected, result.Count); + + // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) + expected = 3; + var name = "GARZON"; + ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); + Assert.AreEqual(expected, result.Count); + + // select authors which name ends with garzon + //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters + //in the string. + //An underscore ("_") in the LIKE pattern matches any single character in the string. + //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). + //case-sensitivity matching depends on PostgreSQL underlying OS. + +#if NETCORE + expected = 1; +#else + expected = 3; +#endif + + ev.Where().Where(rn => rn.Name.EndsWith("garzon")); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.EndsWith("garzon")); + Assert.AreEqual(expected, result.Count); + + + // select authors which name contains Benedict + expected = 2; + name = "Benedict"; + ev.Where().Where(rn => rn.Name.Contains(name)); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Name.Contains("Benedict")); + Assert.AreEqual(expected, result.Count); + a.Name = name; + result = db.Select(rn => rn.Name.Contains(a.Name)); + Assert.AreEqual(expected, result.Count); + + + // select authors with Earnings <= 50 + expected = 3; + var earnings = 50; + ev.Where().Where(rn => rn.Earnings <= earnings); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Earnings <= 50); + Assert.AreEqual(expected, result.Count); + + // select authors with Rate = 10 and city=Mexio + expected = 1; + city = "Mexico"; + ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); + Assert.AreEqual(expected, result.Count); + + a.City = city; + result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); + Assert.AreEqual(expected, result.Count); + + // enough selecting, lets update; + // set Active=false where rate =0 + expected = 2; + var rate = 0; + ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); + var rows = db.UpdateOnlyFields(new Author { Active = false }, ev); + Assert.AreEqual(expected, rows); + + // insert values only in Id, Name, Birthday, Rate and Active fields + expected = 4; + db.InsertOnly(new Author { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + db.InsertOnly(new Author { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + ev.Where().Where(rn => !rn.Active); + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + + //update comment for City == null + expected = 2; + ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); + rows = db.UpdateOnlyFields(new Author { Comments = "No comments" }, ev); + Assert.AreEqual(expected, rows); + + // delete where City is null + expected = 2; + rows = db.Delete(ev); + Assert.AreEqual(expected, rows); + + + // lets select all records ordered by Rate Descending and Name Ascending + expected = 14; + ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + var author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel", author.Name); + + // select only first 5 rows .... + expected = 5; + ev.Limit(5); // note: order is the same as in the last sentence + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + + + // and finally lets select only Name and City (name will be "UPPERCASED" ) + + ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); + Console.WriteLine(ev.SelectExpression); + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); + Console.WriteLine(ev.SelectExpression); + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + //paging : + ev.Limit(0, 4);// first page, page size=4; + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + ev.Limit(4, 4);// second page + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Jorge Garzon".ToUpper(), author.Name); + + ev.Limit(8, 4);// third page + result = db.Select(ev); + author = result.FirstOrDefault(); + Assert.AreEqual("Rodger Contreras".ToUpper(), author.Name); + + // select distinct.. + ev.Limit().OrderBy(); // clear limit, clear order for postres + ev.SelectDistinct(r => r.City); + expected = 6; + result = db.Select(ev); + Assert.AreEqual(expected, result.Count); + + ev.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); + result = db.Select(ev); + var expectedResult = authors.Max(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + ev.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); + result = db.Select(ev); + expectedResult = authors.Max(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + var r1 = db.Single(ev); + Assert.AreEqual(expectedResult, r1.Birthday); + + var r2 = db.Scalar(e => Sql.Max(e.Birthday)); + Assert.AreEqual(expectedResult, r2); + + ev.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); + result = db.Select(ev); + expectedResult = authors.Min(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + ev.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); + result = db.Select(ev); + expectedResult = authors.Min(r => r.Birthday); + Assert.AreEqual(expectedResult, result[0].Birthday); + + + ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + result = db.Select(ev); + var expectedStringResult = "Berlin"; + Assert.AreEqual(expectedStringResult, result[0].City); + + ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + result = db.Select(ev); + expectedStringResult = "Berlin"; + Assert.AreEqual(expectedStringResult, result[0].City); + + r1 = db.Single(ev); + Assert.AreEqual(expectedStringResult, r1.City); + + var expectedDecimal = authors.Max(e => e.Earnings); + Decimal? r3 = db.Scalar(e => Sql.Max(e.Earnings)); + Assert.AreEqual(expectedDecimal, r3.Value); + + var expectedString = authors.Max(e => e.Name); + string r4 = db.Scalar(e => Sql.Max(e.Name)); + Assert.AreEqual(expectedString, r4); + + var expectedDate = authors.Max(e => e.LastActivity); + DateTime? r5 = db.Scalar(e => Sql.Max(e.LastActivity)); + Assert.AreEqual(expectedDate, r5); + + var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); + DateTime? r51 = db.Scalar( + e => Sql.Max(e.LastActivity), + e => e.City == "Bogota"); + Assert.AreEqual(expectedDate51, r51); + + try + { + var expectedBool = authors.Max(e => e.Active); + bool r6 = db.Scalar(e => Sql.Max(e.Active)); + Assert.AreEqual(expectedBool, r6); + } + catch (Exception) + { + //???? + //if (dialect.Name == "PostgreSQL") + // Console.WriteLine("OK PostgreSQL: " + e.Message); + //else + // Console.WriteLine("************** FAILED *************** " + e.Message); + } + + + + // Tests for predicate overloads that make use of the expression visitor + author = db.Single(q => q.Name == "Jorge Garzon"); + + author = db.Single(q => q.Name == "Does not exist"); + Assert.IsNull(author); + + author = db.Single(q => q.City == "Bogota"); + Assert.AreEqual("Angel Colmenares", author.Name); + + a.City = "Bogota"; + author = db.Single(q => q.City == a.City); + Assert.AreEqual("Angel Colmenares", author.Name); + + // count test + + var expectedCount = authors.Count(); + long r7 = db.Scalar(e => Sql.Count(e.Id)); + Assert.AreEqual(expectedCount, r7); + + expectedCount = authors.Count(e => e.City == "Bogota"); + r7 = db.Scalar( + e => Sql.Count(e.Id), + e => e.City == "Bogota"); + Assert.AreEqual(expectedCount, r7); + + ev.Update();// all fields will be updated + // select and update + expected = 1; + var rr = db.Single(rn => rn.Name == "Luis garzon"); + rr.City = "Madrid"; + rr.Comments = "Updated"; + ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated + rows = db.UpdateOnlyFields(rr, ev); // == dbCmd.Update(rr) but it returns void + Assert.AreEqual(expected, rows); + + expected = 0; + ev.Where().Where(r => r.City == "Ciudad Gotica"); + rows = db.UpdateOnlyFields(rr, ev); + Assert.AreEqual(expected, rows); + + expected = db.Select(x => x.City == "Madrid").Count; + author = new Author { Active = false }; + rows = db.UpdateOnlyFields(author, x => x.Active, x => x.City == "Madrid"); + Assert.AreEqual(expected, rows); + + expected = db.Select(x => x.Active == false).Count; + rows = db.Delete(x => x.Active == false); + Assert.AreEqual(expected, rows); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ConditionalExpressionTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ConditionalExpressionTest.cs new file mode 100644 index 000000000..6dc0d2e53 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ConditionalExpressionTest.cs @@ -0,0 +1,155 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class ConditionalExpressionTest : ExpressionsTestBase + { + public ConditionalExpressionTest(DialectContext context) : base(context) {} + + [Test] + public void Can_select_conditional_and_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn > 2 && q.IntColumn < 4); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_conditional_or_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 3 || q.IntColumn < 0); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_evaluated_conditional_and_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = 10; + var b = 5; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == (a >= b && a > 0)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_evaluated_conditional_or_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = 10; + var b = 5; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 3 || a > b); + + Assert.IsNotNull(actual); + Assert.AreEqual(11, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_evaluated_invalid_conditional_or_valid_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = true; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => !q.BoolColumn || a); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + [Test] + public void Can_select_evaluated_conditional_and_valid_expression() + { + var model = new + { + StringValue = "4" + }; + + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.BoolColumn && q.StringColumn == model.StringValue); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/EqualityExpressionsTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/EqualityExpressionsTest.cs new file mode 100644 index 000000000..e199a96f5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/EqualityExpressionsTest.cs @@ -0,0 +1,290 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class EqualityExpressionsTest : ExpressionsTestBase + { + public EqualityExpressionsTest(DialectContext context) : base(context) {} + + [Test] + public void Can_select_equals_constant_int_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 3); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_equals_variable_int_expression() + { +// ReSharper disable ConvertToConstant.Local + var columnValue = 3; +// ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = columnValue, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == columnValue); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_equals_int_method_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_not_equals_constant_int_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn != 3); + + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } + } + + [Test] + public void Can_select_not_equals_variable_int_expression() + { + // ReSharper disable ConvertToConstant.Local + var columnValue = 3; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = columnValue, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn != columnValue); + + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } + } + + [Test] + public void Can_select_not_equals_int_method_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn != GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } + } + + [Test] + public void Can_select_equals_constant_bool_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + // ReSharper disable RedundantBoolCompare + var actual = con.Select(q => q.BoolColumn == true); + // ReSharper restore RedundantBoolCompare + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_equals_constant_bool_expression2() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + // ReSharper disable RedundantBoolCompare + var actual = con.Select(q => q.BoolColumn); + // ReSharper restore RedundantBoolCompare + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_equals_variable_bool_expression() + { + // ReSharper disable ConvertToConstant.Local + var columnValue = true; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == columnValue); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_equals_bool_method_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == GetValue(true)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_equals_null_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test", + NullableCol = new TestType { StringColumn = "sometext" } + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.NullableCol == null); + + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 10); + CollectionAssert.DoesNotContain(actual, expected); + } + } + + [Test] + public void Can_select_not_equals_null_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test", + NullableCol = new TestType { StringColumn = "sometext" } + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.NullableCol != null); + + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ExpressionsTestBase.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ExpressionsTestBase.cs new file mode 100644 index 000000000..1cb513764 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/ExpressionsTestBase.cs @@ -0,0 +1,66 @@ +using System; +using System.Linq; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + public class ExpressionsTestBase : OrmLiteProvidersTestBase + { + public ExpressionsTestBase(DialectContext context) : base(context) {} + + [SetUp] + public void Setup() + { + OpenDbConnection().CreateTable(true); + } + + public T GetValue(T item) + { + return item; + } + + protected void EstablishContext(int numberOfRandomObjects) + { + OrmLiteConfig.ClearCache(); + EstablishContext(numberOfRandomObjects, null); + } + + protected void EstablishContext(int numberOfRandomObjects, params TestType[] obj) + { + if (obj == null) + obj = new TestType[0]; + + using (var con = OpenDbConnection()) + { + foreach (var t in obj) + { + con.Insert(t); + } + + var random = new Random((int)(DateTime.UtcNow.Ticks ^ (DateTime.UtcNow.Ticks >> 4))); + for (var i = 0; i < numberOfRandomObjects; i++) + { + TestType o = null; + + while (o == null) + { + int intVal = random.Next(); + + o = new TestType + { + BoolColumn = random.Next()%2 == 0, + IntColumn = intVal, + StringColumn = Guid.NewGuid().ToString() + }; + + if (obj.Any(x => x.IntColumn == intVal)) + o = null; + } + + con.Insert(o); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/LogicalExpressionsTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/LogicalExpressionsTest.cs new file mode 100644 index 000000000..320f638f8 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/LogicalExpressionsTest.cs @@ -0,0 +1,161 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class LogicalExpressionsTest : ExpressionsTestBase + { + public LogicalExpressionsTest(DialectContext context) : base(context) {} + + // Unlikely + // OpenDbConnection().Select(q => q.BoolColumn == (true & false)); + + [Test] + public void Can_select_logical_and_variable_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = true; + var b = false; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == (a & b)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_logical_or_variable_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = true; + var b = false; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == (a | b)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_logical_xor_variable_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = true; + var b = false; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == (a ^ b)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_logical_and_method_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == (GetValue(true) & GetValue(false))); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_logical_or_method_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == (GetValue(true) | GetValue(false))); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_logical_xor_method_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == (GetValue(true) ^ GetValue(false))); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/MultiplicativeExpressionsTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/MultiplicativeExpressionsTest.cs new file mode 100644 index 000000000..1fa2449f9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/MultiplicativeExpressionsTest.cs @@ -0,0 +1,224 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class MultiplicativeExpressionsTest : ExpressionsTestBase + { + public MultiplicativeExpressionsTest(DialectContext context) : base(context) {} + + [Test] + public void Can_select_constant_multiply_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 4*3); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_constant_divide_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 36/3); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_constant_modulo_expression() + { + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == 37%10); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_variable_multiply_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = 4; + var b = 3; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == a*b); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_variable_divide_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = 36; + var b = 3; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == a/b); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_variablemodulo_expression() + { + // ReSharper disable ConvertToConstant.Local + var a = 37; + var b = 10; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == a%b); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_method_multiply_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == GetValue(4)*GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_method_divide_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == GetValue(36)/GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_method_modulo_expression() + { + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == GetValue(37)%GetValue(10)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/OrmLiteCountTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/OrmLiteCountTests.cs new file mode 100644 index 000000000..0b2468497 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/OrmLiteCountTests.cs @@ -0,0 +1,113 @@ +using System; + +using System.Data; +using System.Linq.Expressions; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteCountTests : OrmLiteProvidersTestBase + { + public OrmLiteCountTests(DialectContext context) : base(context) {} + + [Test] + public void CanDoCountWithInterface() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + db.DeleteAll(); + + db.Insert(new CountTestTable { Id = 1, StringValue = "Your string value" }); + + var count = db.Scalar(e => Sql.Count(e.Id)); + + Assert.That(count, Is.EqualTo(1)); + + count = Count(db); + + Assert.That(count, Is.EqualTo(1)); + + count = CountByColumn(db); + + Assert.That(count, Is.EqualTo(0)); + + } + } + + [Test] + public void CanDoCountWithInterfaceAndPredicate() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + db.DeleteAll(); + db.Insert(new CountTestTable { Id = 1, StringValue = "Your string value" }); + + Expression> exp = q => q.Id == 2; + var count = Count(db, exp); + Assert.That(count, Is.EqualTo(0)); + + + exp = q => q.Id == 1; + count = Count(db, exp); + Assert.That(count, Is.EqualTo(1)); + + exp = q => q.CountColumn == null; + count = Count(db, exp); + Assert.That(count, Is.EqualTo(1)); + + exp = q => q.CountColumn == null; + count = CountByColumn(db, exp); + Assert.That(count, Is.EqualTo(0)); + } + } + + long Count(IDbConnection db) where T : IHasId + { + return db.Scalar(e => Sql.Count(e.Id)); + } + + + long CountByColumn(IDbConnection db) where T : IHasCountColumn + { + return db.Scalar(e => Sql.Count(e.CountColumn)).Value; + } + + + int Count(IDbConnection db, Expression> predicate) where T : IHasId + { + return db.Scalar(e => Sql.Count(e.Id), predicate); + } + + int CountByColumn(IDbConnection db, Expression> predicate) where T : IHasCountColumn + { + return db.Scalar(e => Sql.Count(e.CountColumn), predicate).Value; + } + + } + + public interface IHasCountColumn + { + int? CountColumn { get; set; } + } + + + public class CountTestTable : IHasId, IHasCountColumn + { + public CountTestTable() { } + #region IHasId implementation + public int Id { get; set; } + [StringLength(40)] + public string StringValue { get; set; } + #endregion + + #region IHasCountColumn implementation + public int? CountColumn { get; set; } + #endregion + } +} diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/PrimaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/PrimaryExpressionsTest.cs new file mode 100644 index 000000000..20b4571c5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/PrimaryExpressionsTest.cs @@ -0,0 +1,408 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class PrimaryExpressionsTest : ExpressionsTestBase + { + public PrimaryExpressionsTest(DialectContext context) : base(context) {} + + private static class TestClass + { + public static int StaticProperty { get { return 12; } } + public static int _staticField = 12; + } + + private class TestClass + { + public static T StaticMethod(T value) + { + return value; + } + + public T Property { get; set; } + + public T _field; + + public T Mehtod() + { + return _field; + } + + public TestClass(T value) + { + Property = value; + _field = value; + } + } + + private struct TestStruct + { + public T Property { get { return _field; } } + + public T _field; + + public T Mehtod() + { + return _field; + } + + public TestStruct(T value) + { + _field = value; + } + } + + #region int + + [Test] + public void Can_select_int_property_expression() + { + var tmp = new TestClass(12); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == tmp.Property); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_int_field_expression() + { + var tmp = new TestClass(12); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == tmp._field); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_int_method_expression() + { + var tmp = new TestClass(12); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == tmp.Mehtod()); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_static_int_property_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass.StaticProperty); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_static_int_field_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == TestClass._staticField); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_static_int_method_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == TestClass.StaticMethod(12)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_int_new_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == new TestClass(12).Property); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_struct_int_field_expression() + { + var tmp = new TestStruct(12); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == tmp._field); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_struct_int_property_expression() + { + var tmp = new TestStruct(12); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == tmp.Property); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_struct_int_method_expression() + { + var tmp = new TestStruct(12); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == tmp.Mehtod()); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + #endregion int + + + #region bool + + [Test] + public void Can_select_bool_property_expression() + { + var tmp = new TestClass(false); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == tmp.Property); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_bool_field_expression() + { + var tmp = new TestClass(false); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == tmp._field); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_bool_method_expression() + { + var tmp = new TestClass(false); + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == tmp.Mehtod()); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_static_bool_method_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.BoolColumn == TestClass.StaticMethod(false)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_bool_new_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == new TestClass(false).Property); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } + } + + #endregion bool + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/RelationalExpressionsTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/RelationalExpressionsTest.cs new file mode 100644 index 000000000..975c4ec62 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/RelationalExpressionsTest.cs @@ -0,0 +1,98 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class RelationalExpressionsTest : ExpressionsTestBase + { + public RelationalExpressionsTest(DialectContext context) : base(context) {} + + [Test] + public void Can_select_greater_than_expression() + { + var expected = new TestType() + { + IntColumn = 1, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn > 1); + + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } + } + + [Test] + public void Can_select_greater_or_equal_than_expression() + { + var expected = new TestType() + { + IntColumn = 1, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn >= 1); + + Assert.IsNotNull(actual); + Assert.AreEqual(11, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_smaller_than_expression() + { + var expected = new TestType() + { + IntColumn = 1, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn < 1); + + Assert.IsNotNull(actual); + Assert.AreEqual(0, actual.Count); + } + } + + [Test] + public void Can_select_smaller_or_equal_than_expression() + { + var expected = new TestType() + { + IntColumn = 1, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn <= 1); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/StringFunctionTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/StringFunctionTests.cs new file mode 100644 index 000000000..bcb485951 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/StringFunctionTests.cs @@ -0,0 +1,263 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class StringFunctionTests : ExpressionsTestBase + { + public StringFunctionTests(DialectContext context) : base(context) {} + + [Test] + public void Can_select_using_contains() + { + var stringVal = "stringValue"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = stringVal + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_contains_with_quote_in_string() + { + var stringVal = "string'ContainingAQuote"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = stringVal + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_contains_with_double_quote_in_string() + { + var stringVal = "string\"ContainingAQuote"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = stringVal + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_contains_with_backtick_in_string() + { + var stringVal = "string`ContainingAQuote"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = stringVal + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_startsWith() + { + var prefix = "prefix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = prefix + "asdfasdfasdf" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_startsWith_with_quote_in_string() + { + var prefix = "prefix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = prefix + "'asdfasdfasdf" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_startsWith_with_double_quote_in_string() + { + var prefix = "prefix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = prefix + "\"asdfasdfasdf" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_startsWith_with_backtick_in_string() + { + var prefix = "prefix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = prefix + "`asdfasdfasdf" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_endsWith() + { + var postfix = "postfix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "asdfasdfasdf" + postfix + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_endsWith_with_quote_in_string() + { + var postfix = "postfix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "asdfasd'fasdf" + postfix + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_endsWith_with_double_quote_in_string() + { + var postfix = "postfix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "asdfasd\"fasdf" + postfix + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_using_endsWith_with_backtick_in_string() + { + var postfix = "postfix"; + + var expected = new TestType() + { + IntColumn = 7, + BoolColumn = true, + StringColumn = "asdfasd`fasdf" + postfix + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } +} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/TestType.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/TestType.cs similarity index 100% rename from src/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/TestType.cs rename to tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/TestType.cs diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/UnaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/UnaryExpressionsTest.cs new file mode 100644 index 000000000..6283862d6 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Expressions/UnaryExpressionsTest.cs @@ -0,0 +1,247 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Expressions +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class UnaryExpressionsTest : ExpressionsTestBase + { + public UnaryExpressionsTest(DialectContext context) : base(context) {} + + [Test] + public void Can_select_unary_plus_constant_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == +12); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_minus_constant_expression() + { + var expected = new TestType() + { + IntColumn = -12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == -12); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_not_constant_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == !true); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_not_constant_expression2() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => !q.BoolColumn); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_plus_variable_expression() + { + // ReSharper disable ConvertToConstant.Local + var intVal = +12; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == intVal); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_minus_variable_expression() + { + // ReSharper disable ConvertToConstant.Local + var intVal = -12; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = -12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == intVal); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_not_variable_expression() + { + // ReSharper disable ConvertToConstant.Local + var boolVal = true; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == !boolVal); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_cast_variable_expression() + { + // ReSharper disable ConvertToConstant.Local + object intVal = 12; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == (int) intVal); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_not_method_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.BoolColumn == !GetValue(true)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_unary_cast_method_expression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; + + EstablishContext(10, expected); + + using (var con = OpenDbConnection()) + { + var actual = con.Select(q => q.IntColumn == (int) GetValue((object) 12)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/ForeignKeyAttributeTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/ForeignKeyAttributeTests.cs new file mode 100644 index 000000000..0ee308b61 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/ForeignKeyAttributeTests.cs @@ -0,0 +1,196 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class ForeignKeyAttributeTests : OrmLiteProvidersTestBase + { + public ForeignKeyAttributeTests(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void Setup() + { + DropTables(); + + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [OneTimeTearDown] + public void TearDown() + { + DropTables(); + } + + private void DropTables() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + } + } + + [Test] + public void CanCreateSimpleForeignKey() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteCascade() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CascadesOnDelete() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + + dbConn.Save(new ReferencedType { Id = 1 }); + dbConn.Save(new TypeWithOnDeleteCascade { RefId = 1 }); + + Assert.AreEqual(1, dbConn.Select().Count); + Assert.AreEqual(1, dbConn.Select().Count); + + dbConn.Delete(r => r.Id == 1); + + Assert.AreEqual(0, dbConn.Select().Count); + Assert.AreEqual(0, dbConn.Select().Count); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteNoAction() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteRestrict() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteSetDefault() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteSetNull() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + } + + public class ReferencedType + { + public int Id { get; set; } + } + + + public class TypeWithSimpleForeignKey + { + [AutoIncrement] + public int Id { get; set; } + [References(typeof(ReferencedType))] + public int RefId { get; set; } + } + + public class TypeWithOnDeleteCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteAndUpdateCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteNoAction + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteRestrict + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteSetDefault + { + [AutoIncrement] + public int Id { get; set; } + + [Default(typeof(int), "17")] + [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT")] + public int RefId { get; set; } + } + + public class TypeWithOnDeleteSetNull + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL")] + public int? RefId { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/CustomSqlIssue.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/CustomSqlIssue.cs new file mode 100644 index 000000000..163ec6611 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/CustomSqlIssue.cs @@ -0,0 +1,202 @@ +using System; +using System.Data; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; +using System.Collections.Generic; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Issues +{ + [Alias("color")] + public class ColorModel + { + public string Color { get; set; } + public string Value { get; set; } + } + + public class ColorJsonModel + { + public int Id { get; set; } + public string ColorJson { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteModelArrayTests : OrmLiteProvidersTestBase + { + public OrmLiteModelArrayTests(DialectContext context) : base(context) {} + + [Test] + public void test_model_with_array_to_json() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ColorModel { Color = "red", Value = "#f00" }); + db.Insert(new ColorModel { Color = "green", Value = "#0f0" }); + db.Insert(new ColorModel { Color = "blue", Value = "#00f" }); + db.Insert(new ColorModel { Color = "cyan", Value = "#0ff" }); + db.Insert(new ColorModel { Color = "magenta", Value = "#f0f" }); + db.Insert(new ColorModel { Color = "yellow", Value = "#ff0" }); + db.Insert(new ColorModel { Color = "black", Value = "#000" }); + + const string sql = @"SELECT 1::integer AS id + , json_agg(color.*) AS color_json + FROM color;"; + + var results = db.Select(sql); + + //results.PrintDump(); + + Assert.That(results.Count, Is.EqualTo(1)); + + foreach (var result in results) + { + Assert.That(result.Id, Is.EqualTo(1)); + Assert.That(result.ColorJson, Is.Not.Null); + } + + } + } + + [Test] + public void test_model_with_array_and_json() + { + //OrmLiteConfig.DeoptimizeReader = true; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ColorModel { Color = "red", Value = "#f00" }); + db.Insert(new ColorModel { Color = "green", Value = "#0f0" }); + db.Insert(new ColorModel { Color = "blue", Value = "#00f" }); + db.Insert(new ColorModel { Color = "cyan", Value = "#0ff" }); + db.Insert(new ColorModel { Color = "magenta", Value = "#f0f" }); + db.Insert(new ColorModel { Color = "yellow", Value = "#ff0" }); + db.Insert(new ColorModel { Color = "black", Value = "#000" }); + + // SQL contains array and json aggs. + // We usually have ARRAY fields defined in the db, but when + // retrieved we json-ize them. In otherwords the array exists in the tables/views. + // We use SELECT.* which would contain the ARRAY field. + // Array fields are not used in any of our models and should not cause the other + // fields in the model to not be populated. + const string sql = @"SELECT 1::integer AS id + , json_agg(color.*) AS color_json + , array_agg(color.*) AS color_array + FROM color;"; + + var results = db.Select(sql); + + Assert.That(results.Count, Is.EqualTo(1)); + + foreach (var result in results) + { + result.ColorJson.Print(); + Assert.That(result.Id, Is.EqualTo(1)); + Assert.That(result.ColorJson, Is.Not.Null); + } + } + } + + [Alias("my_table")] + public class MyModel + { + public int MyModelId { get; set; } + public string Name { get; set; } + public string Type { get; set; } + public string NewField { get; set; } + } + + public class MyNewModel + { + public int MyModelId { get; set; } + public string Name { get; set; } + public string Type { get; set; } + public string NewField { get; set; } + public int RenamedId { get; set; } + } + + [Test] + public void test_model_with_simple_array_and_duplicate_fields() + { + using (var db = OpenDbConnection()) + { + + db.DropAndCreateTable(); + + db.Insert(new MyModel { MyModelId = 100, Name = "Test Name", NewField = "New Field", Type = "My Type" }); + db.Insert(new MyModel { MyModelId = 200, Name = "Tester Name 2", NewField = "New Field 2", Type = "My Type 2" }); + + const string sql = @" + SELECT *, t2.my_model_id AS renamed_id + FROM ( + SELECT * + FROM my_table + CROSS JOIN (SELECT ARRAY[1,2,3,4] AS int_array) AS c + ) AS t1 + INNER JOIN my_table AS t2 ON t1.my_model_id = t2.my_model_id;"; + + var results = db.Select(sql); + + Assert.That(results.Count, Is.GreaterThan(1)); + + foreach (var result in results) + { + Console.WriteLine("{0} - {1} - {2}".Fmt(result.MyModelId, result.Name, result.RenamedId)); + Assert.That(result.MyModelId, Is.Not.EqualTo(0)); + Assert.That(result.RenamedId, Is.Not.EqualTo(0)); + Assert.That(result.Name, Is.Not.Empty); + } + + } + } + + [Test] + public void test_model_with_complex_array_and_duplicate_fields() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ColorModel { Color = "red", Value = "#f00" }); + db.Insert(new ColorModel { Color = "green", Value = "#0f0" }); + db.Insert(new ColorModel { Color = "blue", Value = "#00f" }); + db.Insert(new ColorModel { Color = "cyan", Value = "#0ff" }); + db.Insert(new ColorModel { Color = "magenta", Value = "#f0f" }); + db.Insert(new ColorModel { Color = "yellow", Value = "#ff0" }); + db.Insert(new ColorModel { Color = "black", Value = "#000" }); + + db.DropAndCreateTable(); + + db.Insert(new MyModel { MyModelId = 100, Name = "Test Name", NewField = "New Field", Type = "My Type" }); + db.Insert(new MyModel { MyModelId = 200, Name = "Tester Name 2", NewField = "New Field 2", Type = "My Type 2" }); + + const string sql = @" + SELECT *, t2.my_model_id AS renamed_id + FROM ( + SELECT * + FROM my_table + CROSS JOIN (SELECT array_agg(color.*) AS color_array FROM color) AS c + ) AS t1 + INNER JOIN my_table AS t2 ON t1.my_model_id = t2.my_model_id;"; + + var results = db.Select(sql); + + Assert.That(results.Count, Is.GreaterThan(1)); + + foreach (var result in results) + { + Console.WriteLine("{0} - {1} - {2}".Fmt(result.MyModelId, result.Name, result.RenamedId)); + Assert.That(result.MyModelId, Is.Not.EqualTo(0)); + Assert.That(result.RenamedId, Is.Not.EqualTo(0)); + Assert.That(result.Name, Is.Not.Empty); + } + } + } + + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/JsonDataTypeTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/JsonDataTypeTests.cs new file mode 100644 index 000000000..ffe16af02 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/JsonDataTypeTests.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Issues +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class JsonDataTypeTests : OrmLiteProvidersTestBase + { + public JsonDataTypeTests(DialectContext context) : base(context) {} + + [Test] + public void Can_save_and_restore_JSON_property() + { + using (new TemporaryNamingStrategy(DialectProvider, new OrmLiteNamingStrategyBase())) + { + var item = new LicenseCheckTemp + { + Body = new CheckHistory + { + List = { + new ItemHistory { AddedOn = DateTime.MaxValue, Note = "Test" } + } + } + }; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.GetLastSql().Print(); + db.Save(item); + } + + using (var db = OpenDbConnection()) + { + var items = db.Select(); + items.PrintDump(); + + foreach (var licenseCheck in items.OrderBy(x => x.Id)) + { + if (licenseCheck.Body != null && licenseCheck.Body.List.Any()) + { + foreach (var itemHistory in licenseCheck.Body.List) + { + "{0} : Note {1}".Print(itemHistory.AddedOn, itemHistory.Note); + } + } + } + } + } + } + } + + public class LicenseCheckTemp + { + [AutoIncrement] + public int Id { get; set; } + + [CustomField("json")] + public CheckHistory Body { get; set; } + } + + public class CheckHistory + { + public CheckHistory() + { + this.List = new List(); + } + + public List List { get; set; } + } + + public class ItemHistory + { + public string Note { get; set; } + + public DateTime AddedOn { get; set; } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/StoredProcNullableParams.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/StoredProcNullableParams.cs new file mode 100644 index 000000000..6c9514d84 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/Issues/StoredProcNullableParams.cs @@ -0,0 +1,256 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests.Issues +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class StoredProcNullableParams : OrmLiteProvidersTestBase + { + public StoredProcNullableParams(DialectContext context) : base(context) {} + /* + * Nullable Type tests + * NOTE: These test only test SqlList they should probably also test Select + */ + + private const string CreateFunction = @" + CREATE OR REPLACE FUNCTION f_service_stack_function_{0}( + v_{0} {0} + ) RETURNS TABLE ( + id int, + val {0} + ) AS + $BODY$ + BEGIN + -- generate rows 1 - 10, but with the same val to make it look like a table. + RETURN QUERY SELECT s AS id, v_{0} AS val FROM generate_series(1,10) s; + END; + $BODY$ + LANGUAGE plpgsql VOLATILE COST 100; + "; + + private const string DropFunction = "DROP FUNCTION IF EXISTS f_service_stack_function_{0}({0});"; + + + public class ServiceStackTypeFunctionResultNullableInt + { + public int Id { get; set; } + public int? Val { get; set; } + } + + [Test] + public void Can_execute_function_with_nullable_int_param() + { + using (var db = OpenDbConnection()) + { + const string pgTypeToTest = "int"; + int? testVal = null; + + // if function already exists drop before create (can't change result) + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + + db.ExecuteSql(CreateFunction.Fmt(pgTypeToTest)); + db.GetLastSql().Print(); + + // Fix: DbCommand.Parameter for NULL values defaults to NpgsqlTypes.NpgsqlDbType.Text should be NpgsqlTypes.NpgsqlDbType.Integer + + var sql = "SELECT * FROM f_service_stack_function_{0}(@paramValue);".Fmt(pgTypeToTest); + + var rows = db.SqlList( + sql, + new + { + paramValue = testVal + }); + + Assert.That(rows.Count, Is.EqualTo((10))); + Assert.That(rows[0].Val, Is.Null); + + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + } + } + + public class ServiceStackTypeFunctionResultNullableShort + { + public int Id { get; set; } + public short? Val { get; set; } + } + + [Test] + public void Can_execute_function_with_nullable_short_param() + { + using (var db = OpenDbConnection()) + { + const string pgTypeToTest = "smallint"; + short? testVal = null; + + // if function already exists drop before create (can't change result) + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + + db.ExecuteSql(CreateFunction.Fmt(pgTypeToTest)); + db.GetLastSql().Print(); + + // Fix: DbCommand.Parameter for NULL values defaults to NpgsqlTypes.NpgsqlDbType.Text should be NpgsqlTypes.NpgsqlDbType.Smallint + + var sql = "SELECT * FROM f_service_stack_function_{0}(@paramValue);".Fmt(pgTypeToTest); + + var rows = db.SqlList( + sql, + new + { + paramValue = testVal + }); + + Assert.That(rows.Count, Is.EqualTo((10))); + Assert.That(rows[0].Val, Is.Null); + + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + } + } + + public class ServiceStackTypeFunctionResultNullableLong + { + public int Id { get; set; } + public long? Val { get; set; } + } + + [Test] + public void Can_execute_function_with_nullable_long_param() + { + using (var db = OpenDbConnection()) + { + const string pgTypeToTest = "bigint"; + long? testVal = null; + + // if function already exists drop before create (can't change result) + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + + db.ExecuteSql(CreateFunction.Fmt(pgTypeToTest)); + db.GetLastSql().Print(); + + // Fix: DbCommand.Parameter for NULL values defaults to NpgsqlTypes.NpgsqlDbType.Text should be NpgsqlTypes.NpgsqlDbType.Bigint + + var sql = "SELECT * FROM f_service_stack_function_{0}(@paramValue);".Fmt(pgTypeToTest); + + var rows = db.SqlList( + sql, + new + { + paramValue = testVal + }); + + Assert.That(rows.Count, Is.EqualTo((10))); + Assert.That(rows[0].Val, Is.Null); + + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + } + } + + public class ServiceStackTypeFunctionResultInt + { + public int Id { get; set; } + public int Val { get; set; } + } + + [Test] + public void Can_execute_function_with_int_param() + { + using (var db = OpenDbConnection()) + { + const string pgTypeToTest = "int"; + const int testVal = 123; + + // if function already exists drop before create (can't change result) + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + + db.ExecuteSql(CreateFunction.Fmt(pgTypeToTest)); + db.GetLastSql().Print(); + + var sql = "SELECT * FROM f_service_stack_function_{0}(@paramValue);".Fmt(pgTypeToTest); + + var rows = db.SqlList( + sql, + new { + paramValue = testVal + }); + + Assert.That(rows.Count, Is.EqualTo((10))); + Assert.That(rows[0].Val, Is.EqualTo(testVal)); + + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + } + } + + public class ServiceStackTypeFunctionResultShort + { + public int Id { get; set; } + public short Val { get; set; } + } + + [Test] + public void Can_execute_function_with_short_param() + { + using (var db = OpenDbConnection()) + { + const string pgTypeToTest = "smallint"; + const short testVal = 123; + + // if function already exists drop before create (can't change result) + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + + db.ExecuteSql(CreateFunction.Fmt(pgTypeToTest)); + db.GetLastSql().Print(); + + var sql = "SELECT * FROM f_service_stack_function_{0}(@paramValue);".Fmt(pgTypeToTest); + + var rows = db.SqlList( + sql, new { + paramValue = testVal + }); + + Assert.That(rows.Count, Is.EqualTo((10))); + Assert.That(rows[0].Val, Is.EqualTo(testVal)); + + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + } + } + + public class ServiceStackTypeFunctionResultLong + { + public int Id { get; set; } + public long Val { get; set; } + } + + [Test] + public void Can_execute_function_with_long_param() + { + using (var db = OpenDbConnection()) + { + const string pgTypeToTest = "bigint"; + const long testVal = long.MaxValue - 100; + + // if function already exists drop before create (can't change result) + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + // Make sure there isn't an INT function to fallback to. + db.ExecuteSql(DropFunction.Fmt("int")); + + + db.ExecuteSql(CreateFunction.Fmt(pgTypeToTest)); + db.GetLastSql().Print(); + + var sql = "SELECT * FROM f_service_stack_function_{0}(@paramValue);".Fmt(pgTypeToTest); + + var rows = db.SqlList( + sql, + new { + paramValue = testVal + }); + + Assert.That(rows.Count, Is.EqualTo((10))); + Assert.That(rows[0].Val, Is.EqualTo(testVal)); + + db.ExecuteSql(DropFunction.Fmt(pgTypeToTest)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/NetCoreTestsRunner.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/NetCoreTestsRunner.cs new file mode 100644 index 000000000..461a21325 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/NetCoreTestsRunner.cs @@ -0,0 +1,48 @@ +//NUnitLite isn't recognized in VS2017 - shouldn't need NUnitLite with NUnit 3.5+ https://github.com/nunit/dotnet-test-nunit +#if NUNITLITE +using NUnitLite; +using NUnit.Common; +using System.Reflection; +using ServiceStack; +using ServiceStack.Text; +using System; +using System.Globalization; +using System.Threading; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + public class NetCoreTestsRunner + { + /// + /// The main program executes the tests. Output may be routed to + /// various locations, depending on the arguments passed. + /// + /// Run with --help for a full list of arguments supported + /// + public static int Main(string[] args) + { + var licenseKey = Environment.GetEnvironmentVariable("SERVICESTACK_LICENSE"); + if (licenseKey.IsNullOrEmpty()) + throw new ArgumentNullException("SERVICESTACK_LICENSE", "Add Environment variable for SERVICESTACK_LICENSE"); + + Licensing.RegisterLicense(licenseKey); + //"ActivatedLicenseFeatures: ".Print(LicenseUtils.ActivatedLicenseFeatures()); + + var postgreSqlDb = Environment.GetEnvironmentVariable("POSTGRESQL_DB"); + + if (!String.IsNullOrEmpty(postgreSqlDb)) + { + TestConfig.PostgreSqlDb = postgreSqlDb; + } + + CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); + JsConfig.InitStatics(); + + //JsonServiceClient client = new JsonServiceClient(); + var writer = new ExtendedTextWrapper(Console.Out); + return new AutoRun(((IReflectableType)typeof(NetCoreTestsRunner)).GetTypeInfo().Assembly).Execute(args, writer, Console.In); + } + } +} +#endif \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/NormalizeTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/NormalizeTests.cs new file mode 100644 index 000000000..a3813fbac --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/NormalizeTests.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; +using ServiceStack.OrmLite.Tests.UseCase; +using ServiceStack.Text; +using Customer = ServiceStack.OrmLite.Tests.Customer; +using Order = ServiceStack.OrmLite.Tests.Order; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + class NormalizeTests : OrmLiteProvidersTestBase + { + public NormalizeTests(DialectContext context) : base(context) {} + + [Test] + public void Can_create_and_populate_tables_without_quotes() + { + using (var db = OpenDbConnection()) + { + ((PostgreSqlDialectProvider) DialectProvider).Normalize = true; + + CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + + db.GetLastSql().Print(); + + var customer = new Customer + { + Name = "Customer 1", + PrimaryAddress = new CustomerAddress + { + AddressLine1 = "1 Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, + Orders = new[] { + new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, + new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, + }.ToList(), + }; + + db.Save(customer, references: true); + db.GetLastSql().Print(); + + var dbCustomer = db.SingleById(customer.Id); + Assert.That(dbCustomer.Name, Is.EqualTo(customer.Name)); + dbCustomer = db.SqlList("select * from Customer where Id = @Id", new { customer.Id })[0]; + Assert.That(dbCustomer.Name, Is.EqualTo(customer.Name)); + + var address = db.Single(x => x.CustomerId == customer.Id && x.Id == customer.PrimaryAddress.Id); + Assert.That(address.Country, Is.EqualTo("Australia")); + + var orders = db.Select(x => x.CustomerId == customer.Id); + var totalQty = orders.Sum(x => x.Qty); + Assert.That(totalQty, Is.EqualTo(3)); + + //PostgreSqlDialectProvider.Instance.Normalize = false; + } + } + } +} diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteBasicPersistenceProviderTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteBasicPersistenceProviderTests.cs similarity index 92% rename from src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteBasicPersistenceProviderTests.cs rename to tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteBasicPersistenceProviderTests.cs index ff18a4226..2cabf1f69 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteBasicPersistenceProviderTests.cs +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteBasicPersistenceProviderTests.cs @@ -2,14 +2,14 @@ using System.Linq; using NUnit.Framework; using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Tests; -namespace ServiceStack.OrmLite.Tests +namespace ServiceStack.OrmLite.PostgreSQL.Tests { - [TestFixture] - public class OrmLiteBasicPersistenceProviderTests - : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteBasicPersistenceProviderTests : OrmLiteProvidersTestBase { - public OrmLiteBasicPersistenceProviderTests() : base(Dialect.PostgreSql) { } + public OrmLiteBasicPersistenceProviderTests(DialectContext context) : base(context) {} [SetUp] public void SetUp() diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteCreateTableWithNamigStrategyTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteCreateTableWithNamigStrategyTests.cs new file mode 100644 index 000000000..fc5c43247 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteCreateTableWithNamigStrategyTests.cs @@ -0,0 +1,200 @@ +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteCreateTableWithNamingStrategyTests : OrmLiteProvidersTestBase + { + public OrmLiteCreateTableWithNamingStrategyTests(DialectContext context) : base(context) {} + + [Test] + public void Can_create_TableWithNamigStrategy_table_prefix() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void Can_create_TableWithNamigStrategy_table_lowered() + { + using (new TemporaryNamingStrategy(DialectProvider, new LowercaseNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + + [Test] + public void Can_create_TableWithNamigStrategy_table_nameUnderscoreCompound() + { + using (new TemporaryNamingStrategy(DialectProvider, new UnderscoreSeparatedCompoundNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } + + [Test] + public void Can_get_data_from_TableWithNamigStrategy_with_GetById() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "999", AlbumId = "112", AlbumName = "ElectroShip", Name = "MyNameIsBatman" }; + + db.Save(m); + var modelFromDb = db.SingleById("999"); + + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + + + [Test] + public void Can_get_data_from_TableWithNamigStrategy_with_query_by_example() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + + + [Test] + public void Can_get_data_from_TableWithNamigStrategy_AfterChangingNamingStrategy() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + + modelFromDb = db.SingleById("998"); + Assert.AreEqual(m.Name, modelFromDb.Name); + + } + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + + modelFromDb = db.SingleById("998"); + Assert.AreEqual(m.Name, modelFromDb.Name); + } + + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + ModelWithOnlyStringFields m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + + modelFromDb = db.SingleById("998"); + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + + } + + internal class PrefixNamingStrategy : OrmLiteNamingStrategyBase + { + + public string TablePrefix { get; set; } + + public string ColumnPrefix { get; set; } + + public override string GetTableName(string name) + { + return TablePrefix + name; + } + + public override string GetColumnName(string name) + { + return ColumnPrefix + name; + } + + } + + internal class LowercaseNamingStrategy : OrmLiteNamingStrategyBase + { + + public override string GetTableName(string name) + { + return name.ToLower(); + } + + public override string GetColumnName(string name) + { + return name.ToLower(); + } + + } + + internal class UnderscoreSeparatedCompoundNamingStrategy : OrmLiteNamingStrategyBase + { + + public override string GetTableName(string name) + { + return toUnderscoreSeparatedCompound(name); + } + + public override string GetColumnName(string name) + { + return toUnderscoreSeparatedCompound(name); + } + + + string toUnderscoreSeparatedCompound(string name) + { + + string r = char.ToLower(name[0]).ToString(); + + for (int i = 1; i < name.Length; i++) + { + char c = name[i]; + if (char.IsUpper(name[i])) + { + r += "_"; + r += char.ToLower(name[i]); + } + else + { + r += name[i]; + } + } + return r; + } + + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteDropTableWithNamingStrategyTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteDropTableWithNamingStrategyTests.cs new file mode 100644 index 000000000..da7074a6f --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteDropTableWithNamingStrategyTests.cs @@ -0,0 +1,24 @@ +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteDropTableWithNamingStrategyTests : OrmLiteProvidersTestBase + { + public OrmLiteDropTableWithNamingStrategyTests(DialectContext context) : base(context) {} + + [Test] + public void Can_drop_TableWithNamingStrategy_table_PostgreSqlNamingStrategy() + { + using (new TemporaryNamingStrategy(DialectProvider, new PostgreSqlNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + db.DropTable(); + Assert.False(db.TableExists("model_with_only_string_fields")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteExecuteProcedureTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteExecuteProcedureTests.cs new file mode 100644 index 000000000..39f9ed545 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteExecuteProcedureTests.cs @@ -0,0 +1,92 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; +using ServiceStack.Text; +using IgnoreAttribute = NUnit.Framework.IgnoreAttribute; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteExecuteProcedureTests : OrmLiteProvidersTestBase + { + public OrmLiteExecuteProcedureTests(DialectContext context) : base(context) {} + + private const string Create = @" + CREATE OR REPLACE FUNCTION f_service_stack( + v_string_values text[], + v_integer_values integer[] + ) RETURNS BOOLEAN AS + $BODY$ + BEGIN + IF v_string_values[1] <> 'ServiceStack' THEN + RAISE EXCEPTION 'Unexpected value in string array[1] %', v_string_values[1]; + END IF; + IF v_string_values[2] <> 'Thoughtfully Architected' THEN + RAISE EXCEPTION 'Unexpected value in string array[2] %', v_string_values[2]; + END IF; + IF v_integer_values[1] <> 1 THEN + RAISE EXCEPTION 'Unexpected value in integer array[1] %', v_integer_values[1]; + END IF; + IF v_integer_values[2] <> 2 THEN + RAISE EXCEPTION 'Unexpected value in integer array[2] %', v_integer_values[2]; + END IF; + IF v_integer_values[3] <> 3 THEN + RAISE EXCEPTION 'Unexpected value in integer array[3] %', v_integer_values[3]; + END IF; + RETURN TRUE; + END; + $BODY$ + LANGUAGE plpgsql VOLATILE COST 100; + "; + + private const string Drop = "DROP FUNCTION f_service_stack(text[], integer[]);"; + + [Alias("f_service_stack")] + public class ServiceStackFunctionWithAlias + { + [CustomField("text[]")] + [Alias("v_string_values")] + public string[] StringValues { get; set; } + [CustomField("integer[]")] + [Alias("v_integer_values")] + public int[] IntegerValues { get; set; } + } + + [Alias("f_service_stack")] + public class ServiceStackFunctionNoAlias + { + [CustomField("text[]")] + public string[] v_string_values { get; set; } + [CustomField("int[]")] + public int[] v_integer_values { get; set; } + } + + [Test] + public void Can_execute_stored_procedure_with_array_arguments() + { + using (var db = OpenDbConnection()) + { + db.ExecuteSql(Create); + db.GetLastSql().Print(); + + // Execute using [Alias()] attribute + db.ExecuteProcedure(new ServiceStackFunctionWithAlias + { + StringValues = new[] { "ServiceStack", "Thoughtfully Architected" }, + IntegerValues = new[] { 1, 2, 3 } + }); + db.GetLastSql().Print(); + + // Execute without using [Alias()] attribute + db.ExecuteProcedure(new ServiceStackFunctionNoAlias + { + v_string_values = new[] { "ServiceStack", "Thoughtfully Architected" }, + v_integer_values = new[] { 1, 2, 3 } + }); + db.GetLastSql().Print(); + + db.ExecuteSql(Drop); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteGetScalarTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteGetScalarTests.cs new file mode 100644 index 000000000..9cb25c9ac --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteGetScalarTests.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteGetScalarTests: OrmLiteProvidersTestBase + { + public OrmLiteGetScalarTests(DialectContext context) : base(context) {} + + [Test] + public void Can_get_scalar_value(){ + + List authors = new List(); + authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London", FloatProperty=10.25f, DoubleProperty=3.23 }); + authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota",FloatProperty=7.59f,DoubleProperty=4.23 }); + authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London",FloatProperty=15.5f,DoubleProperty=5.42 }); + authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota",FloatProperty=0.57f, DoubleProperty=8.76}); + authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=8.43f, DoubleProperty=7.35}); + authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota", FloatProperty=1.25f, DoubleProperty=0.3652}); + authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota", FloatProperty=1.5f, DoubleProperty=100.563}); + authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena", FloatProperty=3.5f,DoubleProperty=7.23 }); + authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena", FloatProperty=0.25f,DoubleProperty=9.23 }); + authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London", FloatProperty=9.95f,DoubleProperty=4.91 }); + authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin",FloatProperty=4.44f,DoubleProperty=6.41 }); + authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid", FloatProperty=6.67f, DoubleProperty=8.05 }); + authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid", FloatProperty=1.25f, DoubleProperty=3.99}); + authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, + City = "Mexico", + LastActivity= DateTime.Today, + NRate=5, + FloatProperty=1.25f, + NFloatProperty=3.15f, + DoubleProperty= 1.25, + NDoubleProperty= 8.25 + }); + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + db.DeleteAll(); + + db.InsertAll(authors); + + var expectedDate = authors.Max(e=>e.Birthday); + var r1 = db.Scalar( e => Sql.Max(e.Birthday) ); + Assert.That(expectedDate, Is.EqualTo(r1)); + + expectedDate = authors.Where(e=>e.City=="London").Max(e=>e.Birthday); + r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="London" ); + Assert.That(expectedDate, Is.EqualTo(r1)); + + r1 = db.Scalar( e => Sql.Max(e.Birthday), e=>e.City=="SinCity" ); + Assert.That( default(DateTime), Is.EqualTo(r1)); + + + var expectedNullableDate= authors.Max(e=>e.LastActivity); + DateTime? r2 = db.Scalar(e=> Sql.Max(e.LastActivity)); + Assert.That(expectedNullableDate, Is.EqualTo(r2)); + + expectedNullableDate= authors.Where(e=> e.City=="Bogota").Max(e=>e.LastActivity); + r2 = db.Scalar( + e=> Sql.Max(e.LastActivity), + e=> e.City=="Bogota" ); + Assert.That(expectedNullableDate, Is.EqualTo(r2)); + + r2 = db.Scalar( e => Sql.Max(e.LastActivity), e=>e.City=="SinCity" ); + Assert.That( default(DateTime?), Is.EqualTo(r2)); + + + var expectedDecimal= authors.Max(e=>e.Earnings); + decimal r3 = db.Scalar(e=> Sql.Max(e.Earnings)); + Assert.That(expectedDecimal, Is.EqualTo(r3)); + + expectedDecimal= authors.Where(e=>e.City=="London").Max(e=>e.Earnings); + r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="London"); + Assert.That(expectedDecimal, Is.EqualTo(r3)); + + r3 = db.Scalar(e=> Sql.Max(e.Earnings), e=>e.City=="SinCity"); + Assert.That( default(decimal), Is.EqualTo(r3)); + + + var expectedNullableDecimal= authors.Max(e=>e.NEarnings); + decimal? r4 = db.Scalar(e=> Sql.Max(e.NEarnings)); + Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); + + expectedNullableDecimal= authors.Where(e=>e.City=="London").Max(e=>e.NEarnings); + r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="London"); + Assert.That(expectedNullableDecimal, Is.EqualTo(r4)); + + r4 = db.Scalar(e=> Sql.Max(e.NEarnings), e=>e.City=="SinCity"); + Assert.That( default(decimal?), Is.EqualTo(r4)); + + + var expectedDouble =authors.Max(e=>e.DoubleProperty); + double r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty)); + Assert.That(expectedDouble, Is.EqualTo(r5)); + + expectedDouble =authors.Where(e=>e.City=="London").Max(e=>e.DoubleProperty); + r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="London"); + Assert.That(expectedDouble, Is.EqualTo(r5)); + + r5 = db.Scalar(e=> Sql.Max(e.DoubleProperty), e=>e.City=="SinCity"); + Assert.That(default(double),Is.EqualTo(r5)); + + + var expectedNullableDouble =authors.Max(e=>e.NDoubleProperty); + double? r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty)); + Assert.That(expectedNullableDouble, Is.EqualTo(r6)); + + + expectedNullableDouble =authors.Where(e=>e.City=="London").Max(e=>e.NDoubleProperty); + r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="London"); + Assert.That(expectedNullableDouble, Is.EqualTo(r6)); + + r6 = db.Scalar(e=> Sql.Max(e.NDoubleProperty), e=>e.City=="SinCity"); + Assert.That(default(double?),Is.EqualTo(r6)); + + + + var expectedFloat =authors.Max(e=>e.FloatProperty); + var r7 = db.Scalar(e=> Sql.Max(e.FloatProperty)); + Assert.That(expectedFloat, Is.EqualTo(r7)); + + expectedFloat =authors.Where(e=>e.City=="London").Max(e=>e.FloatProperty); + r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="London"); + Assert.That(expectedFloat, Is.EqualTo(r7)); + + r7 = db.Scalar(e=> Sql.Max(e.FloatProperty), e=>e.City=="SinCity"); + Assert.That(default(float),Is.EqualTo(r7)); + + + var expectedNullableFloat =authors.Max(e=>e.NFloatProperty); + var r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty)); + Assert.That(expectedNullableFloat, Is.EqualTo(r8)); + + expectedNullableFloat =authors.Where(e=>e.City=="London").Max(e=>e.NFloatProperty); + r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="London"); + Assert.That(expectedNullableFloat, Is.EqualTo(r8)); + + r8 = db.Scalar(e=> Sql.Max(e.NFloatProperty), e=>e.City=="SinCity"); + Assert.That(default(float?),Is.EqualTo(r8)); + + + var expectedString=authors.Min(e=>e.Name); + var r9 = db.Scalar(e=> Sql.Min(e.Name)); + Assert.That(expectedString, Is.EqualTo(r9)); + + expectedString=authors.Where(e=>e.City=="London").Min(e=>e.Name); + r9 = db.Scalar(e=> Sql.Min(e.Name), e=>e.City=="London"); + Assert.That(expectedString, Is.EqualTo(r9)); + + r9 = db.Scalar(e=> Sql.Max(e.Name), e=>e.City=="SinCity"); + Assert.That(r9, Is.Null.Or.Empty); + + //var expectedBool=authors.Min(e=>e.Active); + //var r10 = db.GetScalar(e=> Sql.Min(e.Active)); + //Assert.That(expectedBool, Is.EqualTo(r10)); + + //expectedBool=authors.Max(e=>e.Active); + //r10 = db.GetScalar(e=> Sql.Max(e.Active)); + //Assert.That(expectedBool, Is.EqualTo(r10)); + + //r10 = db.GetScalar(e=> Sql.Max(e.Active), e=>e.City=="SinCity"); + //Assert.IsFalse(r10); + + + + var expectedShort =authors.Max(e=>e.Rate); + var r11 = db.Scalar(e=> Sql.Max(e.Rate)); + Assert.That(expectedShort, Is.EqualTo(r11)); + + expectedShort =authors.Where(e=>e.City=="London").Max(e=>e.Rate); + r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="London"); + Assert.That(expectedShort, Is.EqualTo(r11)); + + r11 = db.Scalar(e=> Sql.Max(e.Rate), e=>e.City=="SinCity"); + Assert.That(default(short),Is.EqualTo(r7)); + + + var expectedNullableShort =authors.Max(e=>e.NRate); + var r12 = db.Scalar(e=> Sql.Max(e.NRate)); + Assert.That(expectedNullableShort, Is.EqualTo(r12)); + + expectedNullableShort =authors.Where(e=>e.City=="London").Max(e=>e.NRate); + r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="London"); + Assert.That(expectedNullableShort, Is.EqualTo(r12)); + + r12 = db.Scalar(e=> Sql.Max(e.NRate), e=>e.City=="SinCity"); + Assert.That(default(short?),Is.EqualTo(r12)); + + } + + } + + } + + + internal class Author + { + public Author(){} + + [AutoIncrement] + [Alias("AuthorID")] + public Int32 Id { get; set;} + + [Index(Unique = true)] + [StringLength(40)] + public string Name { get; set;} + + public DateTime Birthday { get; set;} + public DateTime? LastActivity { get; set;} + public decimal Earnings { get; set;} + public decimal? NEarnings { get; set;} + + public bool Active { get; set; } + + [StringLength(80)] + [Alias("JobCity")] + public string City { get; set;} + + [StringLength(80)] + [Alias("Comment")] + public string Comments { get; set;} + + public short Rate{ get; set;} + public short? NRate{ get; set;} + public float FloatProperty { get; set;} + public float? NFloatProperty { get; set;} + public double DoubleProperty { get; set;} + public double? NDoubleProperty { get; set;} + + } + + +} + diff --git a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteInsertTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteInsertTests.cs similarity index 80% rename from src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteInsertTests.cs rename to tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteInsertTests.cs index 5f976f48e..e44f4c145 100644 --- a/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteInsertTests.cs +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteInsertTests.cs @@ -3,14 +3,14 @@ using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; -namespace ServiceStack.OrmLite.Tests +namespace ServiceStack.OrmLite.PostgreSQL.Tests { - [TestFixture] - public class OrmLiteInsertTests - : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class OrmLiteInsertTests : OrmLiteProvidersTestBase { - public OrmLiteInsertTests() : base(Dialect.PostgreSql) { } + public OrmLiteInsertTests(DialectContext context) : base(context) {} [Test] public void Can_insert_into_ModelWithFieldsOfDifferentTypes_table() @@ -113,10 +113,10 @@ public void Can_retrieve_LastInsertId_from_inserted_table() var row2 = new ModelWithIdAndName1() { Name = "B", Id = 5 }; var row1LastInsertId = db.Insert(row1, selectIdentity: true); - Assert.That(db.GetLastSql(), Is.StringEnding(") RETURNING id")); + Assert.That(db.GetLastSql(), Does.Match("\\) RETURNING \"?[Ii]d")); var row2LastInsertId = db.Insert(row2, selectIdentity: true); - Assert.That(db.GetLastSql(), Is.StringEnding(") RETURNING id")); + Assert.That(db.GetLastSql(), Does.Match("\\) RETURNING \"?[Ii]d")); var insertedRow1 = db.SingleById(row1LastInsertId); var insertedRow2 = db.SingleById(row2LastInsertId); @@ -129,7 +129,7 @@ public void Can_retrieve_LastInsertId_from_inserted_table() [Test] public void Can_retrieve_LastInsertId_from_inserted_table_with_LastVal() { - PostgreSQL.PostgreSQLDialectProvider.Instance.UseReturningForLastInsertId = false; + PostgreSQL.PostgreSqlDialectProvider.Instance.UseReturningForLastInsertId = false; using (var db = OpenDbConnection()) { db.DropAndCreateTable(); @@ -138,10 +138,10 @@ public void Can_retrieve_LastInsertId_from_inserted_table_with_LastVal() var row2 = ModelWithIdAndName.Create(6); var row1LastInsertId = db.Insert(row1, selectIdentity: true); - Assert.That(db.GetLastSql(), Is.StringEnding("; SELECT LASTVAL()")); + Assert.That(db.GetLastSql(), Does.EndWith("; SELECT LASTVAL()")); var row2LastInsertId = db.Insert(row2, selectIdentity: true); - Assert.That(db.GetLastSql(), Is.StringEnding("; SELECT LASTVAL()")); + Assert.That(db.GetLastSql(), Does.EndWith("; SELECT LASTVAL()")); var insertedRow1 = db.SingleById(row1LastInsertId); var insertedRow2 = db.SingleById(row2LastInsertId); @@ -149,7 +149,7 @@ public void Can_retrieve_LastInsertId_from_inserted_table_with_LastVal() Assert.That(insertedRow1.Name, Is.EqualTo(row1.Name)); Assert.That(insertedRow2.Name, Is.EqualTo(row2.Name)); } - PostgreSQL.PostgreSQLDialectProvider.Instance.UseReturningForLastInsertId = true; + PostgreSQL.PostgreSqlDialectProvider.Instance.UseReturningForLastInsertId = true; } [Test] @@ -200,19 +200,22 @@ class ModelWithIdAndName1 public string Name { get; set; } } - public class PostgreSQLUpdateTests : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql), SetUICulture("en-US"), SetCulture("en-US")] + public class PostgreSQLUpdateTests : OrmLiteProvidersTestBase { - public PostgreSQLUpdateTests() - : base(Dialect.PostgreSql) - { - } + public PostgreSQLUpdateTests(DialectContext context) : base(context) {} [Test] public void Can_insert_datetimeoffsets_regardless_of_current_culture() { // datetimeoffset's default .ToString depends on culture, ensure we use one with MDY - var previousCulture = System.Threading.Thread.CurrentThread.CurrentCulture; - System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US"); +//#if NETCORE +// var previousCulture = CultureInfo.CurrentCulture; +// CultureInfo.CurrentCulture = new CultureInfo("en-US"); +//#else +// var previousCulture = System.Threading.Thread.CurrentThread.CurrentCulture; +// System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); +//#endif try { using (var db = OpenDbConnection()) @@ -239,7 +242,11 @@ public void Can_insert_datetimeoffsets_regardless_of_current_culture() } finally { - System.Threading.Thread.CurrentThread.CurrentCulture = previousCulture; +//#if NETCORE +// CultureInfo.CurrentCulture = previousCulture; +//#else +// System.Threading.Thread.CurrentThread.CurrentCulture = previousCulture; +//#endif } } diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLitePostgresFixtureSetup.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLitePostgresFixtureSetup.cs new file mode 100644 index 000000000..604756b11 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLitePostgresFixtureSetup.cs @@ -0,0 +1,11 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +[assembly: NonParallelizable] + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + public class OrmLitePostgresFixtureSetup : OrmLiteFixtureSetup + { + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteSelectTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteSelectTests.cs new file mode 100644 index 000000000..b75300330 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteSelectTests.cs @@ -0,0 +1,354 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Tests; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + [NonParallelizable] + public class OrmLiteSelectTests : OrmLiteProvidersTestBase + { + public OrmLiteSelectTests(DialectContext context) : base(context) {} + + [Test] + public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var row = db.SingleById(1); + + Assert.That(row.Id, Is.EqualTo(1)); + } + } + + [Test] + public void Can_GetById_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var row = db.SingleById("id-1"); + + Assert.That(row.Id, Is.EqualTo("id-1")); + } + } + + [Test] + public void Can_GetByIds_int_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var rows = db.SelectByIds(rowIds); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_GetByIds_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var rows = db.SelectByIds(rowIds); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; + + db.Insert(filterRow); + + var rows = db.Select("\"album_name\" = @AlbumName", new { filterRow.AlbumName }); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } + + [Test] + public void Can_select_scalar_value() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var count = db.Scalar("SELECT COUNT(*) FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); + + Assert.That(count, Is.EqualTo(n)); + } + } + + [Test] + public void Can_loop_each_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var dbRowIds = new List(); + foreach (var row in db.SelectLazy()) + { + dbRowIds.Add(row.Id); + } + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; + + db.Insert(filterRow); + db.GetLastSql().Print(); + + var dbRowIds = new List(); + var rows = db.SelectLazy("\"album_name\" = @AlbumName", new { filterRow.AlbumName }); + foreach (var row in rows) + { + dbRowIds.Add(row.Id); + } + + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } + + [Test] + public void Can_GetFirstColumn() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var ids = db.Column("SELECT \"id\" FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); + + Assert.That(ids.Count, Is.EqualTo(n)); + } + } + + [Test] + public void Can_GetFirstColumnDistinct() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var ids = db.ColumnDistinct("SELECT \"id\" FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); + + Assert.That(ids.Count, Is.EqualTo(n)); + } + } + + [Test] + public void Can_GetLookup() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => { + var row = ModelWithIdAndName.Create(x); + row.Name = x % 2 == 0 ? "OddGroup" : "EvenGroup"; + db.Insert(row); + }); + + var lookup = db.Lookup("SELECT \"name\", \"id\" FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); + + Assert.That(lookup, Has.Count.EqualTo(2)); + Assert.That(lookup["OddGroup"], Has.Count.EqualTo(3)); + Assert.That(lookup["EvenGroup"], Has.Count.EqualTo(2)); + } + } + + [Test] + public void Can_GetDictionary() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var dictionary = db.Dictionary("SELECT \"id\", \"name\" FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); + + Assert.That(dictionary, Has.Count.EqualTo(5)); + + //Console.Write(dictionary.Dump()); + } + } + + [Test] + public void Can_Select_subset_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var rows = db.Select("SELECT \"id\", \"name\" FROM " + + "ModelWithFieldsOfDifferentTypes".SqlTable(DialectProvider)); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_Query_ModelWithFieldsOfDifferentTypes_with_dictionary_parameters() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var rows = db.Select("SELECT * FROM {0} where \"id\" = :Id " + .Fmt("ModelWithFieldsOfDifferentTypes".SqlTable(DialectProvider)), + new Dictionary { {"Id", 3} }); + + Assert.AreEqual(rows.Count, 1); + Assert.AreEqual(rows[0].Id, 3); + } + } + + [Test] + public void Can_Select_Into_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var rowIds = new List(new[] { 1, 2, 3 }); + + rowIds.ForEach(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(x))); + + var rows = db.Select(typeof(ModelWithFieldsOfDifferentTypes)); + var dbRowIds = rows.ConvertAll(x => x.Id); + + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } + + [Test] + public void Can_Select_In_for_string_value() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var selectInNames = new[] { "Name1", "Name2" }; + var rows = db.Select("Name IN ({0})".Fmt(selectInNames.SqlInParams(DialectProvider)), + new { values = selectInNames.SqlInValues(DialectProvider) }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + + rows = db.Select("Name IN (@p1, @p2)", new { p1 = "Name1", p2 = "Name2" }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + } + } + + [Test] + public void Can_Select_With_Subquery() + { + const int n = 5; + + using (var db = OpenDbConnection()) + { + db.CreateTable(); + + n.Times(x => db.Insert(ModelWithFieldsOfDifferentTypes.Create(n))); + + var sql = @" + WITH max_id AS ( + SELECT 3 AS three) + SELECT * + FROM {0} + WHERE id <= (SELECT three FROM max_id)".Fmt("ModelWithFieldsOfDifferentTypes".SqlTable(DialectProvider)); + + var rows = db.SqlList(sql); + + Assert.That(rows.Count, Is.EqualTo((3))); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PgSqlTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PgSqlTests.cs new file mode 100644 index 000000000..3209ae186 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PgSqlTests.cs @@ -0,0 +1,32 @@ +using NpgsqlTypes; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + public class PgSqlTests + { + [Test] + public void Can_create_NpgsqlParameter() + { + Assert.That(PgSql.Param("p", 1).NpgsqlDbType, Is.EqualTo(NpgsqlDbType.Integer)); + Assert.That(PgSql.Param("p", "s").NpgsqlDbType, Is.EqualTo(NpgsqlDbType.Text)); + Assert.That(PgSql.Param("p", 'c').NpgsqlDbType, Is.EqualTo(NpgsqlDbType.Char)); + Assert.That(PgSql.Param("p", new [] { 1 }).NpgsqlDbType, + Is.EqualTo(NpgsqlDbType.Integer | NpgsqlDbType.Array)); + } + + [Test] + public void Does_PgSqlArray() + { + Assert.That(PgSql.Array((string[])null), Is.EqualTo("ARRAY[]")); + Assert.That(PgSql.Array(new string[0]), Is.EqualTo("ARRAY[]")); + Assert.That(PgSql.Array(new int[0]), Is.EqualTo("ARRAY[]")); + Assert.That(PgSql.Array(1,2,3), Is.EqualTo("ARRAY[1,2,3]")); + Assert.That(PgSql.Array("A","B","C"), Is.EqualTo("ARRAY['A','B','C']")); + Assert.That(PgSql.Array("A'B","C\"D"), Is.EqualTo("ARRAY['A''B','C\"D']")); + + Assert.That(PgSql.Array(new string[0], nullIfEmpty:true), Is.EqualTo("null")); + Assert.That(PgSql.Array(new[]{"A","B","C"}, nullIfEmpty:true), Is.EqualTo("ARRAY['A','B','C']")); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlArrayTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlArrayTests.cs new file mode 100644 index 000000000..e2a1878ce --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlArrayTests.cs @@ -0,0 +1,72 @@ +using System; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + public class ModelWithArrayType + { + public int Id { get; set; } + + [CustomField("integer[]")] + public int[] IntegerArray { get; set; } + + [CustomField("bigint[]")] + public long[] BigIntegerArray { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class PostgreSqlArrayTests : OrmLiteProvidersTestBase + { + public PostgreSqlArrayTests(DialectContext context) : base(context) {} + + [Test] + public void Can_save_integer_array() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.GetLastSql().Print(); + + var row = new ModelWithArrayType + { + Id = 1, + IntegerArray = new[] {1, 2, 3} + }; + db.Insert(row); + + var result = db.Select(); + + Assert.That(result.Count, Is.EqualTo(1)); + Assert.That(result[0].IntegerArray, Is.EqualTo(new[] { 1, 2, 3 })); + } + } + + [Test] + public void Can_save_big_integer_array() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.GetLastSql().Print(); + + var row = new ModelWithArrayType + { + Id = 2, + BigIntegerArray = new long[] { 1, 2, 3, 4 } + }; + db.Insert(row); + + var result = db.Select(); + + Assert.That(result.Count, Is.EqualTo(1)); + Assert.That(result[0].BigIntegerArray, Is.EqualTo(new[] { 1, 2, 3, 4 })); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlDataTypesTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlDataTypesTests.cs new file mode 100644 index 000000000..0d0043006 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlDataTypesTests.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + public class PostgreSqlTypes + { + public int Id { get; set; } + + //hstore + public Dictionary Dictionary { get; set; } + public IDictionary IDictionary { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class PostgreSqlDataTypesTests : OrmLiteProvidersTestBase + { + public PostgreSqlDataTypesTests(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void OneTimeSetup() + { + PostgreSqlDialectProvider.Instance.UseHstore = true; + using (var db = OpenDbConnection()) + { + db.ExecuteSql("CREATE EXTENSION IF NOT EXISTS hstore;"); + } + } + + [OneTimeTearDown] public void OneTimeTearDown() => PostgreSqlDialectProvider.Instance.UseHstore = false; + + [Test] + public void Does_save_string_dictionary_in_hstore_columns() + { + using (var db = OpenDbConnection()) + { + var sb = OrmLiteUtils.CaptureSql(); + + db.DropAndCreateTable(); + + Assert.That(OrmLiteUtils.UnCaptureSqlAndFree(sb), Does.Contain("hstore")); + + db.Insert(new PostgreSqlTypes + { + Id = 1, + Dictionary = new Dictionary { {"A", "1"} }, + IDictionary = new Dictionary { {"B", "2"} }, + }); + + Assert.That(db.Single(db.From().Where("dictionary -> 'A' = '1'")).Id, + Is.EqualTo(1)); + + var q = db.From(); + Assert.That(db.Single(q.Where($"{q.Column(x => x.IDictionary)} -> 'B' = '2'")).Id, + Is.EqualTo(1)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlJsonTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlJsonTests.cs new file mode 100644 index 000000000..e7c04d9ab --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/PostgreSqlJsonTests.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + public class ModelWithJsonType + { + public int Id { get; set; } + + [PgSqlJson] + public ComplexType ComplexTypeJson { get; set; } + + [PgSqlJsonB] + public ComplexType ComplexTypeJsonb { get; set; } + } + + public class ComplexType + { + public int Id { get; set; } + public SubType SubType { get; set; } + } + + public class SubType + { + public string Name { get; set; } + } + + public class PgsqlData + { + [PrimaryKey] + public Guid Id { get; set; } + + public int[] Ints { get; set; } + public long[] Longs { get; set; } + public float[] Floats { get; set; } + public double[] Doubles { get; set; } + public decimal[] Decimals { get; set; } + public string[] Strings { get; set; } + public DateTime[] DateTimes { get; set; } + public DateTimeOffset[] DateTimeOffsets { get; set; } + + public List ListInts { get; set; } + public List ListLongs { get; set; } + public List ListFloats { get; set; } + public List ListDoubles { get; set; } + public List ListDecimals { get; set; } + public List ListStrings { get; set; } + public List ListDateTimes { get; set; } + public List ListDateTimeOffsets { get; set; } + } + + public class PgsqlDataAnnotated + { + [PrimaryKey] + public Guid Id { get; set; } + + [PgSqlIntArray] + public int[] Ints { get; set; } + [PgSqlBigIntArray] + public long[] Longs { get; set; } + [PgSqlFloatArray] + public float[] Floats { get; set; } + [PgSqlDoubleArray] + public double[] Doubles { get; set; } + [PgSqlDecimalArray] + public decimal[] Decimals { get; set; } + [PgSqlTextArray] + public string[] Strings { get; set; } + + [PgSqlTimestamp] + public DateTime[] DateTimes { get; set; } + + [PgSqlTimestampTz] + public DateTimeOffset[] DateTimeOffsets { get; set; } + + [PgSqlIntArray] + public List ListInts { get; set; } + [PgSqlBigIntArray] + public List ListLongs { get; set; } + [PgSqlFloatArray] + public List ListFloats { get; set; } + [PgSqlDoubleArray] + public List ListDoubles { get; set; } + [PgSqlDecimalArray] + public List ListDecimals { get; set; } + [PgSqlTextArray] + public List ListStrings { get; set; } + [PgSqlTimestamp] + public List ListDateTimes { get; set; } + [PgSqlTimestampTz] + public List ListDateTimeOffsets { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class PostgreSqlJsonTests : OrmLiteProvidersTestBase + { + public PostgreSqlJsonTests(DialectContext context) : base(context) {} + + [Test] + public void Can_save_complex_types_as_JSON() + { + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.GetLastSql().Print(); + + var row = new ModelWithJsonType + { + Id = 1, + ComplexTypeJson = new ComplexType + { + Id = 2, SubType = new SubType { Name = "SubType2" } + }, + ComplexTypeJsonb = new ComplexType + { + Id = 3, SubType = new SubType { Name = "SubType3" } + }, + }; + + db.Insert(row); + + var result = db.Single( + "complex_type_json->'SubType'->>'Name' = 'SubType2'"); + + db.GetLastSql().Print(); + + Assert.That(result.Id, Is.EqualTo(1)); + Assert.That(result.ComplexTypeJson.Id, Is.EqualTo(2)); + Assert.That(result.ComplexTypeJson.SubType.Name, Is.EqualTo("SubType2")); + + var results = db.Select( + "complex_type_jsonb->'SubType'->>'Name' = 'SubType3'"); + + Assert.That(results[0].ComplexTypeJsonb.Id, Is.EqualTo(3)); + Assert.That(results[0].ComplexTypeJsonb.SubType.Name, Is.EqualTo("SubType3")); + } + } + + [Test] + public void Does_save_PgSqlData() + { + OrmLiteUtils.PrintSql(); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + long UnixEpoch = 621355968000000000L; + var dateTimes = new DateTime[] { + new DateTime(UnixEpoch, DateTimeKind.Utc), + new DateTime(2001, 01, 01, 1, 1, 1, 1, DateTimeKind.Utc), + }; + var dateTimeOffsets = dateTimes.Select(x => new DateTimeOffset(x, TimeSpan.Zero)).ToArray(); + + var data = new PgsqlData + { + Id = Guid.NewGuid(), + Ints = new[] { 2, 4, 1 }, + Longs = new long[] { 2, 4, 1 }, + Floats = new float[] { 2, 4, 1 }, + Doubles = new double[] { 2, 4, 1 }, + Strings = new[] { "test string 1", "test string 2" }, + Decimals = new decimal[] { 2, 4, 1 }, + DateTimes = dateTimes, + DateTimeOffsets = dateTimeOffsets, + + ListInts = new[] { 2, 4, 1 }.ToList(), + ListLongs = new long[] { 2, 4, 1 }.ToList(), + ListFloats = new float[] { 2, 4, 1 }.ToList(), + ListDoubles = new double[] { 2, 4, 1 }.ToList(), + ListStrings = new[] { "test string 1", "test string 2" }.ToList(), + ListDecimals = new decimal[] { 2, 4, 1 }.ToList(), + ListDateTimes = dateTimes.ToList(), + ListDateTimeOffsets = dateTimeOffsets.ToList(), + }; + + db.Save(data); + + var row = db.Select()[0]; + Assert.That(row.Ints.EquivalentTo(data.Ints)); + Assert.That(row.Longs.EquivalentTo(data.Longs)); + Assert.That(row.Floats.EquivalentTo(data.Floats)); + Assert.That(row.Doubles.EquivalentTo(data.Doubles)); + Assert.That(row.Decimals.EquivalentTo(data.Decimals)); + Assert.That(row.ListInts.EquivalentTo(data.ListInts)); + Assert.That(row.ListLongs.EquivalentTo(data.ListLongs)); + Assert.That(row.ListFloats.EquivalentTo(data.ListFloats)); + Assert.That(row.ListDoubles.EquivalentTo(data.ListDoubles)); + Assert.That(row.ListDecimals.EquivalentTo(data.ListDecimals)); + Assert.That(row.Strings.EquivalentTo(data.Strings)); + Assert.That(row.ListStrings.EquivalentTo(data.ListStrings)); + } + + OrmLiteUtils.UnPrintSql(); + } + [Test] + public void Does_save_PgSqlDataAnnotated() + { + OrmLiteUtils.PrintSql(); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + long UnixEpoch = 621355968000000000L; + var dateTimes = new DateTime[] { + new DateTime(UnixEpoch, DateTimeKind.Utc), + new DateTime(2001, 01, 01, 1, 1, 1, 1, DateTimeKind.Utc), + }; + var dateTimeOffsets = dateTimes.Select(x => new DateTimeOffset(x, TimeSpan.Zero)).ToArray(); + + var data = new PgsqlDataAnnotated + { + Id = Guid.NewGuid(), + Ints = new[] { 2, 4, 1 }, + Longs = new long[] { 2, 4, 1 }, + Floats = new float[] { 2, 4, 1 }, + Doubles = new double[] { 2, 4, 1 }, + Strings = new[] { "test string 1", "test string 2" }, + Decimals = new decimal[] { 2, 4, 1 }, + DateTimes = dateTimes, + DateTimeOffsets = dateTimeOffsets, + + ListInts = new[] { 2, 4, 1 }.ToList(), + ListLongs = new long[] { 2, 4, 1 }.ToList(), + ListFloats = new float[] { 2, 4, 1 }.ToList(), + ListDoubles = new double[] { 2, 4, 1 }.ToList(), + ListStrings = new[] { "test string 1", "test string 2" }.ToList(), + ListDecimals = new decimal[] { 2, 4, 1 }.ToList(), + ListDateTimes = dateTimes.ToList(), + ListDateTimeOffsets = dateTimeOffsets.ToList(), + }; + + db.Save(data); + + var row = db.Select()[0]; + Assert.That(row.Ints.EquivalentTo(data.Ints)); + Assert.That(row.Longs.EquivalentTo(data.Longs)); + Assert.That(row.Floats.EquivalentTo(data.Floats)); + Assert.That(row.Doubles.EquivalentTo(data.Doubles)); + Assert.That(row.Decimals.EquivalentTo(data.Decimals)); + Assert.That(row.ListInts.EquivalentTo(data.ListInts)); + Assert.That(row.ListLongs.EquivalentTo(data.ListLongs)); + Assert.That(row.ListFloats.EquivalentTo(data.ListFloats)); + Assert.That(row.ListDoubles.EquivalentTo(data.ListDoubles)); + Assert.That(row.ListDecimals.EquivalentTo(data.ListDecimals)); + Assert.That(row.Strings.EquivalentTo(data.Strings)); + Assert.That(row.ListStrings.EquivalentTo(data.ListStrings)); + } + + OrmLiteUtils.UnPrintSql(); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/SchemaTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/SchemaTests.cs new file mode 100644 index 000000000..f2cdc2875 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/SchemaTests.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class SchemaTests : OrmLiteProvidersTestBase + { + public SchemaTests(DialectContext context) : base(context) {} + + [Alias("TestSchemaUser")] + [Schema("TestSchema")] + public class User + { + [AutoIncrement] + public int Id { get; set; } + + [Index] + public string Name { get; set; } + + public DateTime CreatedDate { get; set; } + } + + private void CreateSchemaIfNotExists() + { + const string createSchemaSQL = @"DO $$ +BEGIN + + IF NOT EXISTS( + SELECT 1 + FROM INFORMATION_SCHEMA.SCHEMATA + WHERE SCHEMA_NAME = 'TestSchema' + ) + THEN + EXECUTE 'CREATE SCHEMA ""TestSchema""'; + END IF; + +END +$$;"; + using (var db = OpenDbConnection()) + { + db.ExecuteSql(createSchemaSQL); + } + } + + [Test] + public void Can_Create_Tables_With_Schema_in_PostgreSQL() + { + using (var db = OpenDbConnection()) + { + CreateSchemaIfNotExists(); + db.DropAndCreateTable(); + + var tables = db.Single(@"SELECT '[' || n.nspname || '].[' || c.relname ||']' FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relname = 'test_schema_user' AND n.nspname = 'TestSchema'"); + + // PostgreSQL dialect should create the table in the schema + Assert. + That(tables.Contains("[TestSchema].[test_schema_user]")); + } + } + + [Test] + public void Can_Perform_CRUD_Operations_On_Table_With_Schema() + { + using (var db = OpenDbConnection()) + using (var dbCmd = db.CreateCommand()) + { + CreateSchemaIfNotExists(); + db.CreateTable(true); + + db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now }); + db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); + db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); + + var lastInsertId = db.LastInsertId(); + Assert.That(lastInsertId, Is.GreaterThan(0)); + + var rowsB = db.Select("\"name\" = @name", new { name = "B" }); + Assert.That(rowsB, Has.Count.EqualTo(2)); + + var rowIds = rowsB.ConvertAll(x => x.Id); + Assert.That(rowIds, Is.EquivalentTo(new List { 2, 3 })); + + rowsB.ForEach(x => db.Delete(x)); + + rowsB = db.Select("\"name\" = @name", new { name = "B" }); + Assert.That(rowsB, Has.Count.EqualTo(0)); + + var rowsLeft = db.Select(); + Assert.That(rowsLeft, Has.Count.EqualTo(1)); + + Assert.That(rowsLeft[0].Name, Is.EqualTo("A")); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/ServiceStack.OrmLite.PostgreSQL.Tests.csproj b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/ServiceStack.OrmLite.PostgreSQL.Tests.csproj new file mode 100644 index 000000000..cade4706c --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/ServiceStack.OrmLite.PostgreSQL.Tests.csproj @@ -0,0 +1,18 @@ + + + net472 + + portable + ServiceStack.OrmLite.PostgreSQL.Tests + Library + ServiceStack.OrmLite.PostgreSQL.Tests + default + + + + + + + + + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/TypeWithByteArrayFieldTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/TypeWithByteArrayFieldTests.cs new file mode 100644 index 000000000..c95598aab --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/TypeWithByteArrayFieldTests.cs @@ -0,0 +1,154 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class TypeWithByteArrayFieldTests : OrmLiteProvidersTestBase + { + public TypeWithByteArrayFieldTests(DialectContext context) : base(context) {} + + TypeWithByteArrayField getSampleObject() + { + var testByteArray = new byte[256]; + for(int i = 0; i < 256; i++) { testByteArray[i] = (byte)i; } + + return new TypeWithByteArrayField { Id = 1, Content = testByteArray }; + } + + [Test] + public void CanInsertAndSelectByteArray() + { + var orig = getSampleObject(); + + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + db.Save(orig); + + var target = db.SingleById(orig.Id); + + Assert.AreEqual(orig.Id, target.Id); + Assert.AreEqual(orig.Content, target.Content); + } + } + + [Test] + [NonParallelizable] + public void CanInsertAndSelectByteArray__manual_insert__manual_select() + { + var orig = getSampleObject(); + + using(var db = OpenDbConnection()) { + //insert and select manually - ok + db.CreateTable(true); + _insertManually(orig, db); + + _selectAndVerifyManually(orig, db); + } + } + + [Test] + public void CanInsertAndSelectByteArray__InsertParam_insert__manual_select() + { + var orig = getSampleObject(); + + using(var db = OpenDbConnection()) { + //insert using InsertParam, and select manually - ok + db.CreateTable(true); + db.Insert(orig); + + _selectAndVerifyManually(orig, db); + } + } + + [Test] + public void CanInsertAndSelectByteArray__InsertParam_insert__GetById_select() + { + var orig = getSampleObject(); + + using(var db = OpenDbConnection()) { + //InsertParam + GetByID - fails + db.CreateTable(true); + db.Insert(orig); + + var target = db.SingleById(orig.Id); + + Assert.AreEqual(orig.Id, target.Id); + Assert.AreEqual(orig.Content, target.Content); + } + } + + [Test] + public void CanInsertAndSelectByteArray__Insert_insert__GetById_select() + { + var orig = getSampleObject(); + + using(var db = OpenDbConnection()) { + //InsertParam + GetByID - fails + db.CreateTable(true); + db.Insert(orig); + + var target = db.SingleById(orig.Id); + + Assert.AreEqual(orig.Id, target.Id); + Assert.AreEqual(orig.Content, target.Content); + } + } + + [Test] + public void CanInsertAndSelectByteArray__Insert_insert__manual_select() + { + var orig = getSampleObject(); + + using(var db = OpenDbConnection()) { + //InsertParam + GetByID - fails + db.CreateTable(true); + db.Insert(orig); + + _selectAndVerifyManually(orig, db); + } + } + + private static void _selectAndVerifyManually(TypeWithByteArrayField orig, System.Data.IDbConnection db) + { + using(var cmd = db.CreateCommand()) { + cmd.CommandText = @"select ""content"" from ""type_with_byte_array_field"" where ""id"" = 1 --manual select"; + using(var reader = cmd.ExecuteReader()) { + reader.Read(); + var ba = reader["content"] as byte[]; + Assert.AreEqual(orig.Content.Length, ba.Length); + Assert.AreEqual(orig.Content, ba); + } + } + } + + private static void _insertManually(TypeWithByteArrayField orig, System.Data.IDbConnection db) + { + using(var cmd = db.CreateCommand()) { + cmd.CommandText = @"INSERT INTO ""type_with_byte_array_field"" (""id"",""content"") VALUES (@Id, @Content) --manual parameterized insert"; + + var p_id = cmd.CreateParameter(); + p_id.ParameterName = "@Id"; + p_id.Value = orig.Id; + + cmd.Parameters.Add(p_id); + + var p_content = cmd.CreateParameter(); + p_content.ParameterName = "@Content"; + p_content.Value = orig.Content; + + cmd.Parameters.Add(p_content); + + cmd.ExecuteNonQuery(); + } + } + } + + class TypeWithByteArrayField + { + public int Id { get; set; } + public byte[] Content { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/XmlTests.cs b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/XmlTests.cs new file mode 100644 index 000000000..0b36c09db --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/XmlTests.cs @@ -0,0 +1,58 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; + +namespace ServiceStack.OrmLite.PostgreSQL.Tests +{ + public class XmlTest + { + public int Id { get; set; } + public XmlValue Xml { get; set; } + } + + public class XmlTests : OrmLiteTestBase + { + [Test] + public void Can_use_xml_in_postgresql() + { + OrmLiteUtils.PrintSql(); + var dbFactory = new OrmLiteConnectionFactory("Server=192.168.1.8;Port=5432;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200", PostgreSqlDialect.Provider); + using (var db = dbFactory.OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new XmlTest { Id = 1, Xml = @" + + John Doe + 1986 + + + php + python + java + +" }); + + db.Insert(new XmlTest { Id = 2, Xml = @" + + Tom Smith + 1978 + + + python + java + ruby + +" }); + + + var results = db.Column(@"SELECT + (xpath('//bio/name/text()', Xml)::text[])[1] + FROM xml_test + WHERE cast(xpath('//bio[birthYear>1980]', Xml) as text[]) != '{}'"); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0], Is.EqualTo("John Doe")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.PostgreSQL.Tests/app.config b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/app.config new file mode 100644 index 000000000..7395f2a93 --- /dev/null +++ b/tests/ServiceStack.OrmLite.PostgreSQL.Tests/app.config @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/ConvertersOrmLiteTestBase.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/ConvertersOrmLiteTestBase.cs new file mode 100644 index 000000000..a10cd2bac --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/ConvertersOrmLiteTestBase.cs @@ -0,0 +1,62 @@ +using System; +using System.Configuration; +using NUnit.Framework; +using ServiceStack.Logging; +using ServiceStack.OrmLite.SqlServer.Converters; + +namespace ServiceStack.OrmLite.SqlServerTests.Converters +{ + public class SqlServer2012ConvertersOrmLiteTestBase : OrmLiteTestBase + { + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + // Appending the Sql Server Type System Version to use SqlServerSpatial110.dll (2012) assembly + // Sql Server defaults to SqlServerSpatial100.dll (2008 R2) even for versions greater + // https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring.aspx + ConnectionString = GetConnectionString() + "Type System Version=SQL Server 2012;"; + + var dialectProvider = SqlServerConverters.Configure(SqlServer2012Dialect.Provider); + + Db = new OrmLiteConnectionFactory(ConnectionString, dialectProvider).OpenDbConnection(); + } + } + + public class SqlServer2014ConvertersOrmLiteTestBase : SqlServer2012ConvertersOrmLiteTestBase + { + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + // Appending the Sql Server Type System Version to use SqlServerSpatial110.dll (2012) assembly + // Sql Server defaults to SqlServerSpatial100.dll (2008 R2) even for versions greater + // https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring.aspx + ConnectionString = GetConnectionString() + "Type System Version=SQL Server 2012;"; + + var dialectProvider = SqlServerConverters.Configure(SqlServer2014Dialect.Provider); + + Db = new OrmLiteConnectionFactory(ConnectionString, dialectProvider).OpenDbConnection(); + } + } + + public class SqlServer2016ConvertersOrmLiteTestBase : SqlServer2014ConvertersOrmLiteTestBase + { + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + // Appending the Sql Server Type System Version to use SqlServerSpatial110.dll (2012) assembly + // Sql Server defaults to SqlServerSpatial100.dll (2008 R2) even for versions greater + // https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring.aspx + ConnectionString = GetConnectionString() + "Type System Version=SQL Server 2012;"; + + var dialectProvider = SqlServerConverters.Configure(SqlServer2016Dialect.Provider); + + Db = new OrmLiteConnectionFactory(ConnectionString, dialectProvider).OpenDbConnection(); + } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/InheritanceTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/InheritanceTest.cs new file mode 100644 index 000000000..00351b598 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/InheritanceTest.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using Microsoft.SqlServer.Types; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.SqlServerTests.Converters +{ + public class InheritanceTest : SqlServer2012ConvertersOrmLiteTestBase + { + public class GeoSuper + { + public long Id { get; set; } + public string Other { get; set; } + } + + public class GeoTest : GeoSuper + { + public SqlGeography Location { get; set; } + public SqlGeography NullLocation { get; set; } + public SqlGeometry Shape { get; set; } + } + + [Test] + public void Can_limit_on_inherited_Type() + { + InsertData(100); + List data = null; + using (var db = OpenDbConnection()) + { + data = db.Select(db.From().Limit(0, int.MaxValue)); + } + + Assert.IsNotNull(data); + Assert.IsTrue(data.Count == 100); + } + + private void InsertData(int count) + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + for (var i = 0; i < count; i++) + { + db.Insert(new GeoTest { Id = i, Location = RandomPosition() }); + } + } + } + + private SqlGeography RandomPosition() + { + var rand = new Random(DateTime.Now.Millisecond * (int)DateTime.Now.Ticks); + double lat = Math.Round(rand.NextDouble() * 160 - 80, 6); + double lon = Math.Round(rand.NextDouble() * 360 - 180, 6); + var result = SqlGeography.Point(lat, lon, 4326).MakeValid(); + return result; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlGeographyTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlGeographyTests.cs new file mode 100644 index 000000000..adab8cc71 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlGeographyTests.cs @@ -0,0 +1,172 @@ +using System; +using System.Linq; +using Microsoft.SqlServer.Types; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests.Converters +{ + [TestFixture] + public class SqlGeographyTests : SqlServer2012ConvertersOrmLiteTestBase + { + public string ColumnDefinition { get; set; } + + [OneTimeSetUp] + public new void TestFixtureSetUp() + { + base.TestFixtureSetUp(); + + var converter = new SqlServer.Converters.SqlServerGeographyTypeConverter(); + ColumnDefinition = converter.ColumnDefinition; + } + + [Test] + public void Can_insert_and_retrieve_SqlGeography() + { + Db.DropAndCreateTable(); + + // Statue of Liberty + var geo = SqlGeography.Point(40.6898329, -74.0452177, 4326); + + Db.Insert(new GeographyTable {Id = 1, Location = geo, NullLocation = SqlGeography.Null}); + + var result = Db.SingleById(1); + + Assert.IsTrue(geo.STEquals(result.Location).Value); + + // Converter always resolves to null even when Null property inserted into database + Assert.AreEqual(null, result.NullLocation); + + result.PrintDump(); + } + + [Test] + public void Can_convert_to_and_from_SqlGeography_and_string_with_anon_typed_insert() + { + Db.DropAndCreateTable(); + + var dialect = Db.GetDialectProvider(); + var tableName = dialect.GetQuotedTableName(ModelDefinition.Definition); + + var stringValue = "POINT(2 6)"; + var location = SqlGeography.Parse(stringValue); + stringValue = location.ToString(); // to fix any whitespace issues + + var sql = $"INSERT {tableName} (Location, StringLocation) VALUES (@Location, @StringLocation);"; + Db.ExecuteSql(sql, new { Location = location, StringLocation = stringValue }); + + var result = Db.Select().FirstOrDefault(); + Assert.AreEqual(stringValue, result.StringLocation); + Assert.IsTrue(location.STEquals(result.Location).Value); + } + + [Test] + public void Can_convert_to_and_from_SqlGeography_and_string_with_strong_typed_insert() + { + Db.DropAndCreateTable(); + + var stringValue = "POINT(38.028495788574205 55.895460650576936)"; + var location = SqlGeography.STGeomFromText(new System.Data.SqlTypes.SqlChars(stringValue), 4326); + stringValue = location.ToString(); // to fix any whitespace issues + + Db.Insert(new GeographyTable() { Location = location, StringLocation = stringValue, NullLocation = SqlGeography.Null }); + + var result = Db.Select().FirstOrDefault(); + Assert.AreEqual(stringValue, result.StringLocation); + Assert.IsTrue(location.STEquals(result.Location).Value); + } + + [Test] + public void Can_convert_SqlGeography_to_quoted_string() + { + var converter = new SqlServer.Converters.SqlServerGeographyTypeConverter(); + + string stringValue = null; + var location = SqlGeography.Parse(stringValue); // NULL + var str = converter.ToQuotedString(typeof(SqlGeography), location); + + Assert.AreEqual($"CAST(null AS {ColumnDefinition})", str); + + stringValue = "POINT(0 0)"; + location = SqlGeography.Parse(stringValue); + stringValue = location.ToString(); // to fix any whitespace issues + + str = converter.ToQuotedString(typeof(SqlGeography), location); + + Assert.AreEqual($"CAST('{stringValue}' AS {ColumnDefinition})", str); + } + + + + [Test] + public void Can_insert_and_update_SqlGeography() + { + Db.DropAndCreateTable(); + + var wkt = "POINT(38.028495788574205 55.895460650576936)"; + var geo = SqlGeography.STGeomFromText(new System.Data.SqlTypes.SqlChars(wkt), 4326); + + var obj = new ModelWithSqlGeography { Name = "Test", Created = DateTime.UtcNow, Geo = geo }; + + var id = (int)Db.Insert(obj, selectIdentity: true); + obj.ID = id; + + try + { + // Update of POCO with SqlGeography proprety should work + obj.Name = "Test - modified"; + obj.Edited = DateTime.UtcNow; + Db.Update(obj); + } + catch (Exception ex) + { + Assert.Fail(ex.ToString()); + } + finally + { + // GetLastSql shouldn't return null after exception + var lastSql = Db.GetLastSql(); + Assert.IsNotNull(lastSql); + } + } + } + + public class GeographyTable + { + [AutoIncrement] + public long Id { get; set; } + + public SqlGeography Location { get; set; } + + public string StringLocation { get; set; } + + public SqlGeography NullLocation { get; set; } + } + + [Alias("GeographyTable")] + public class FlippedGeographyTable + { + [AutoIncrement] + public long Id { get; set; } + + [Alias("StringLocation")] + public SqlGeography Location { get; set; } + + [Alias("Location")] + public string StringLocation { get; set; } + + public SqlGeography NullLocation { get; set; } + } + + public class ModelWithSqlGeography + { + [AutoIncrement] + public int ID { get; set; } + [StringLength(255)] + public string Name { get; set; } + public DateTime Created { get; set; } + public DateTime? Edited { get; set; } + public SqlGeography Geo { get; set; } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlGeometryTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlGeometryTests.cs new file mode 100644 index 000000000..78152477d --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlGeometryTests.cs @@ -0,0 +1,131 @@ +using System; +using System.Linq; +using Microsoft.SqlServer.Types; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests.Converters +{ + [TestFixture] + public class SqlGeometryTests : SqlServer2012ConvertersOrmLiteTestBase + { + public string ColumnDefinition { get; set; } + + [OneTimeSetUp] + public new void TestFixtureSetUp() + { + base.TestFixtureSetUp(); + + var converter = new SqlServer.Converters.SqlServerGeometryTypeConverter(); + ColumnDefinition = converter.ColumnDefinition; + } + + [Test] + public void Can_insert_and_retrieve_SqlGeometry() + { + Db.DropAndCreateTable(); + + // A simple line from (0,0) to (4,4) Length = SQRT(2 * 4^2) + var wkt = new System.Data.SqlTypes.SqlChars("LINESTRING(0 0, 4 4)".ToCharArray()); + var shape = SqlGeometry.STLineFromText(wkt, 0); + + Db.Insert(new GeometryTable { Id = 1, Shape = shape}); + + var result = Db.SingleById(1).Shape; + + var lengths = Db.Column("SELECT Shape.STLength() AS Length FROM GeometryTable"); + + Assert.AreEqual((double) result.STLength(), lengths.First()); + + Assert.AreEqual(shape.STStartPoint().STX, result.STStartPoint().STX); + Assert.AreEqual(shape.STStartPoint().STY, result.STStartPoint().STY); + + Assert.AreEqual(shape.STEndPoint().STX, result.STEndPoint().STX); + Assert.AreEqual(shape.STEndPoint().STY, result.STEndPoint().STY); + + Assert.AreEqual(2, (int) result.STNumPoints()); + + result.PrintDump(); + } + + [Test] + public void Can_convert_to_and_from_SqlGeometry_and_string_with_anon_typed_insert() + { + Db.DropAndCreateTable(); + + var dialect = Db.GetDialectProvider(); + var tableName = dialect.GetQuotedTableName(ModelDefinition.Definition); + + var stringValue = "POINT(2 6)"; + var shape = SqlGeometry.Parse(stringValue); + stringValue = shape.ToString(); // to fix any whitespace issues + + var sql = $"INSERT {tableName} (Shape, StringShape) VALUES (@Shape, @StringShape);"; + Db.ExecuteSql(sql, new { Shape = shape, StringShape = stringValue }); + + var result = Db.Select().FirstOrDefault(); + Assert.AreEqual(stringValue, result.StringShape); + Assert.IsTrue(shape.STEquals(result.Shape).Value); + } + + [Test] + public void Can_convert_to_and_from_SqlGeometry_and_string_with_strong_typed_insert() + { + Db.DropAndCreateTable(); + + var stringValue = "LINESTRING(0 0, 4 4)"; + var shape = SqlGeometry.Parse(stringValue); + stringValue = shape.ToString(); // to fix any whitespace issues + + Db.Insert(new GeometryTable() { Shape = shape, StringShape = stringValue }); + + var result = Db.Select().FirstOrDefault(); + Assert.AreEqual(stringValue, result.StringShape); + Assert.IsTrue(shape.STEquals(result.Shape).Value); + } + + [Test] + public void Can_convert_SqlGeometry_to_quoted_string() + { + var converter = new SqlServer.Converters.SqlServerGeometryTypeConverter(); + + string stringValue = null; + var shape = SqlGeometry.Parse(stringValue); // NULL + var str = converter.ToQuotedString(typeof(SqlGeometry), shape); + + Assert.AreEqual($"CAST(null AS {ColumnDefinition})", str); + + stringValue = "LINESTRING(0 0, 4 4)"; + shape = SqlGeometry.Parse(stringValue); + stringValue = shape.ToString(); // to fix any whitespace issues + + str = converter.ToQuotedString(typeof(SqlGeometry), shape); + + Assert.AreEqual($"CAST('{stringValue}' AS {ColumnDefinition})", str); + } + } + + public class GeometryTable + { + [AutoIncrement] + public long Id { get; set; } + + public SqlGeometry Shape { get; set; } + + public string StringShape { get; set; } + } + + [Alias("GeometryTable")] + public class FlippedGeometryTable + { + [AutoIncrement] + public long Id { get; set; } + + [Alias("StringShape")] + public SqlGeometry Shape { get; set; } + + [Alias("Shape")] + public string StringShape { get; set; } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlHierarchyIdTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlHierarchyIdTests.cs new file mode 100644 index 000000000..5c44eee35 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Converters/SqlHierarchyIdTests.cs @@ -0,0 +1,128 @@ +using System.Linq; +using Microsoft.SqlServer.Types; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests.Converters +{ + [TestFixture] + public class SqlHierarchyIdTests : SqlServer2012ConvertersOrmLiteTestBase + { + public string ColumnDefinition { get; set; } + + [OneTimeSetUp] + public new void TestFixtureSetUp() + { + base.TestFixtureSetUp(); + + var converter = new SqlServer.Converters.SqlServerHierarchyIdTypeConverter(); + ColumnDefinition = converter.ColumnDefinition; + } + + [Test] + public void Can_insert_and_retrieve_HierarchyId() + { + Db.DropAndCreateTable(); + + var stringValue = "/1/1/3/"; // 0x5ADE + var hierarchyId = SqlHierarchyId.Parse(stringValue); + + Db.Insert(new HierarchyIdTable() { + TreeId = hierarchyId, + NullTreeId = SqlHierarchyId.Null, + StringTreeId = stringValue }); + + var result = Db.Select().FirstOrDefault(); + Assert.AreEqual(null, result.NullTreeId); + Assert.AreEqual(hierarchyId, result.TreeId); + Assert.AreEqual(stringValue, result.StringTreeId); + + var parent = Db.Scalar( + Db.From().Select("TreeId.GetAncestor(1)")); + var str = parent.ToString(); + Assert.AreEqual("/1/1/", str); + } + + [Test] + public void Can_convert_to_and_from_HierarchyId_and_string_with_anon_typed_insert() + { + Db.DropAndCreateTable(); + + var dialect = Db.GetDialectProvider(); + var tableName = dialect.GetQuotedTableName(ModelDefinition.Definition); + + var stringValue = "/2/3/6/"; + var treeId = SqlHierarchyId.Parse(stringValue); + + var sql = $"INSERT {tableName} (TreeId, StringTreeId, NullTreeId) VALUES (@TreeId, @StringTreeId, @NullTreeId);"; + Db.ExecuteSql(sql, new { TreeId = treeId, StringTreeId = stringValue, NullTreeId = SqlHierarchyId.Null }); + + var result = Db.Select().FirstOrDefault(); + Assert.AreEqual(stringValue, result.StringTreeId); + Assert.AreEqual(treeId, result.TreeId); + Assert.AreEqual(null, result.NullTreeId); + } + + [Test] + public void Can_convert_to_and_from_HierarchyId_and_string_with_strong_typed_insert() + { + Db.DropAndCreateTable(); + + var stringValue = "/5/4/1/"; + var treeId = SqlHierarchyId.Parse(stringValue); + + Db.Insert(new HierarchyIdTable() { TreeId = treeId, StringTreeId = stringValue, NullTreeId = SqlHierarchyId.Null }); + + var result = Db.Select().FirstOrDefault(); + Assert.AreEqual(stringValue, result.StringTreeId); + Assert.AreEqual(treeId, result.TreeId); + Assert.AreEqual(null, result.NullTreeId); + } + + [Test] + public void Can_convert_hierarchyid_to_quoted_string() + { + var converter = new SqlServer.Converters.SqlServerHierarchyIdTypeConverter(); + + string stringValue = null; + var hierarchyId = SqlHierarchyId.Parse(stringValue); // NULL + var str = converter.ToQuotedString(typeof(SqlHierarchyId), hierarchyId); + + Assert.AreEqual($"CAST(null AS {ColumnDefinition})", str); + + stringValue = "/1/1/3/"; + hierarchyId = SqlHierarchyId.Parse(stringValue); // 0x5ADE + str = converter.ToQuotedString(typeof(SqlHierarchyId), hierarchyId); + + Assert.AreEqual($"CAST('{stringValue}' AS {ColumnDefinition})", str); + } + } + + [Alias("HierarchyIdTable")] + public class HierarchyIdTable + { + [AutoIncrement] + public long Id { get; set; } + + public SqlHierarchyId TreeId { get; set; } + + public string StringTreeId { get; set; } + + public SqlHierarchyId? NullTreeId { get; set; } + } + + [Alias("HierarchyIdTable")] + public class FlippedHierarchyIdTable + { + [AutoIncrement] + public long Id { get; set; } + + [Alias("StringTreeId")] + public SqlHierarchyId TreeId { get; set; } + + [Alias("TreeId")] + public string StringTreeId { get; set; } + + public string NullTreeId { get; set; } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/CustomSqlTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/CustomSqlTests.cs new file mode 100644 index 000000000..e096a1d61 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/CustomSqlTests.cs @@ -0,0 +1,110 @@ +using System.Data; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class LetterFrequency + { + [AutoIncrement] + public int Id { get; set; } + + public string Letter { get; set; } + } + + [TestFixture] + public class CustomSqlTests : OrmLiteTestBase + { + private const string DropProcedureSql = @" + IF OBJECT_ID('spSearchLetters') IS NOT NULL + DROP PROCEDURE spSearchLetters"; + + private const string CreateProcedureSql = @" + CREATE PROCEDURE spSearchLetters + ( + @pLetter varchar(10), + @pTotal int OUT + ) + AS + BEGIN + SELECT @pTotal = COUNT(*) FROM LetterFrequency WHERE Letter = @pLetter + SELECT * FROM LetterFrequency WHERE Letter = @pLetter + END"; + + [Test] + public void Can_execute_stored_procedure_using_SqlList_with_out_params() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); + db.InsertAll(rows); + + db.ExecuteSql(DropProcedureSql); + db.ExecuteSql(CreateProcedureSql); + + IDbDataParameter pTotal = null; + var results = db.SqlList("spSearchLetters", + cmd => + { + cmd.CommandType = CommandType.StoredProcedure; + cmd.AddParam("pLetter", "C"); + pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); + }); + + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(pTotal.Value, Is.EqualTo("3")); + } + } + + [Test] + public void Can_execute_stored_procedure_using_SqlProc_with_out_params() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); + db.InsertAll(rows); + + db.ExecuteSql(DropProcedureSql); + db.ExecuteSql(CreateProcedureSql); + + var cmd = db.SqlProc("spSearchLetters", new { pLetter = "C" }); + + Assert.That(((OrmLiteCommand)cmd).IsDisposed, Is.False); + + var pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); + var results = cmd.ConvertToList(); + + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(pTotal.Value, Is.EqualTo("3")); + } + } + + [Test] + public void Can_execute_stored_procedure_returning_scalars() + { + var dropSP = @"IF OBJECT_ID('TestGetIds') IS NOT NULL + DROP PROCEDURE TestGetIds"; + var createSP = @"CREATE PROCEDURE TestGetIds + AS + SELECT 1 as Id + UNION ALL + SELECT 2;"; + + using (var db = OpenDbConnection()) + { + db.ExecuteSql(dropSP); + db.ExecuteSql(createSP); + using (var cmd = db.SqlProc("TestGetIds")) + { + var userIds = cmd.ConvertToList(); + + Assert.That(userIds.Count, Is.GreaterThan(0)); + } + } + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/DateTimeOffsetTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/DateTimeOffsetTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/DateTimeOffsetTests.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/DateTimeOffsetTests.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Datetime2Tests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Datetime2Tests.cs new file mode 100644 index 000000000..d25297249 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Datetime2Tests.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Data.SqlTypes; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServer; +using ServiceStack.OrmLite.SqlServer.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class Datetime2Tests : OrmLiteTestBase + { + private OrmLiteConnectionFactory dbFactory; + + [OneTimeSetUp] + public new void TestFixtureSetUp() + { + base.TestFixtureSetUp(); + + //change to datetime2 - check for higher range and precision + //default behaviour: normal datetime can't hold DateTime values of year 1. + dbFactory = new OrmLiteConnectionFactory(base.ConnectionString, SqlServerOrmLiteDialectProvider.Instance); + var dp2 = new SqlServerOrmLiteDialectProvider(); + dp2.RegisterConverter(new SqlServerDateTime2Converter()); + dbFactory.RegisterConnection("dt2", base.ConnectionString, dp2); + } + + [Test] + public void datetime_tests__can_use_datetime2() + { + using (var conn = dbFactory.OpenDbConnection("dt2")) { + var test_object_ValidForDatetime2 = Datetime2Test.get_test_object_ValidForDatetime2(); + + conn.CreateTable(true); + + //normal insert + var insertedId = conn.Insert(test_object_ValidForDatetime2, selectIdentity:true); + + //read back, and verify precision + var fromDb = conn.SingleById(insertedId); + Assert.AreEqual(test_object_ValidForDatetime2.ToVerifyPrecision, fromDb.ToVerifyPrecision); + + //update + fromDb.ToVerifyPrecision = test_object_ValidForDatetime2.ToVerifyPrecision.Value.AddYears(1); + conn.Update(fromDb); + var fromDb2 = conn.SingleById(insertedId); + Assert.AreEqual(test_object_ValidForDatetime2.ToVerifyPrecision.Value.AddYears(1), fromDb2.ToVerifyPrecision); + + //check InsertParam + conn.Insert(test_object_ValidForDatetime2); + + //check select on datetime2 value + var result = conn.Select(t => t.ToVerifyPrecision == test_object_ValidForDatetime2.ToVerifyPrecision); + Assert.AreEqual(result.Single().ToVerifyPrecision, test_object_ValidForDatetime2.ToVerifyPrecision); + } + } + + [Test] + public void datetime_tests__check_default_behaviour() + { + using (var conn = dbFactory.OpenDbConnection()) { + var test_object_ValidForDatetime2 = Datetime2Test.get_test_object_ValidForDatetime2(); + var test_object_ValidForNormalDatetime = Datetime2Test.get_test_object_ValidForNormalDatetime(); + + conn.CreateTable(true); + + // normal insert + var insertedId = conn.Insert(test_object_ValidForNormalDatetime, selectIdentity:true); + + // insert works, but can't regular datetime's precision is not great enough. + var fromDb = conn.SingleById(insertedId); + Assert.AreNotEqual(test_object_ValidForNormalDatetime.ToVerifyPrecision, fromDb.ToVerifyPrecision); + + var thrown = Assert.Throws(() => { + conn.Insert(test_object_ValidForDatetime2); + }); + Assert.That(thrown.Message.Contains("SqlDateTime overflow")); + + + // check InsertParam + conn.Insert(test_object_ValidForNormalDatetime); + // InsertParam fails differently: + var insertParamException = Assert.Throws(() => { + conn.Insert(test_object_ValidForDatetime2); + }); + Assert.That(insertParamException.Message.Contains("SqlDateTime overflow")); + } + } + + [Test] + public void Can_Select_DateTime() + { + using (var db = dbFactory.OpenDbConnection("dt2")) + { + db.DropAndCreateTable(); + db.Insert(Datetime2Test.get_test_object_ValidForNormalDatetime()); + + var now = DateTime.UtcNow; + var q = db.From() + .Select(x => new { SomeDateTime = now }); + + var result = db.Select(q)[0]; + + Assert.That(result.SomeDateTime, Is.EqualTo(now).Within(TimeSpan.FromSeconds(1))); + } + } + + [Test] + [NonParallelizable] + public void Can_Select_DateTime2() + { + using (var db = dbFactory.OpenDbConnection("dt2")) + { + db.DropAndCreateTable(); + db.Insert(Datetime2Test.get_test_object_ValidForDatetime2()); + + var now = DateTime.Parse("2019-03-12 09:10:48.3477082"); + var q = db.From() + .Select(x => new { SomeDateTime = now }); + + var result = db.Select(q)[0]; + + Assert.That(result.SomeDateTime, Is.EqualTo(now)); + } + } + + private class Datetime2Test + { + [AutoIncrement] + public int Id { get; set; } + public DateTime SomeDateTime { get; set; } + public DateTime? ToVerifyPrecision { get; set; } + public DateTime? NullableDateTimeLeaveItNull { get; set; } + + /// + /// to check datetime(2)'s precision. A regular 'datetime' is not precise enough + /// + public static readonly DateTime regular_datetime_field_cant_hold_this_exact_moment = new DateTime(2013, 3, 17, 21, 29, 1, 678).AddTicks(1); + + public static Datetime2Test get_test_object_ValidForDatetime2() { return new Datetime2Test { SomeDateTime = new DateTime(1, 1, 1), ToVerifyPrecision = regular_datetime_field_cant_hold_this_exact_moment }; } + + public static Datetime2Test get_test_object_ValidForNormalDatetime() { return new Datetime2Test { SomeDateTime = new DateTime(2001, 1, 1), ToVerifyPrecision = regular_datetime_field_cant_hold_this_exact_moment }; } + + } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/DialectProviderTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/DialectProviderTests.cs new file mode 100644 index 000000000..64db5b519 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/DialectProviderTests.cs @@ -0,0 +1,81 @@ +using System.Configuration; +using System.Data; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class DialectProviderTests + { + public string ConnectionString => OrmLiteTestBase.GetConnectionString(); + + public void DbPocoTest(IDbConnection db) + { + db.DropAndCreateTable(); + db.Insert(new Poco {Id = 1, Name = "foo"}); + var row = db.SingleById(1); + Assert.That(row.Name, Is.EqualTo("foo")); + } + + [Test] + public void Can_use_SqlServerDialectProvider() + { + var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServerDialect.Provider); + + using (var db = dbFactory.Open()) + { + DbPocoTest(db); + } + } + + [Test] + public void Can_use_SqlServer2012DialectProvider() + { + var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServer2012Dialect.Provider); + using (var db = dbFactory.Open()) + { + DbPocoTest(db); + } + } + + [Test] + public void Can_use_SqlServer2014DialectProvider() + { + var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServer2014Dialect.Provider); + using (var db = dbFactory.Open()) + { + DbPocoTest(db); + } + } + + [Test] + public void Can_use_SqlServer2016DialectProvider() + { + var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServer2016Dialect.Provider); + using (var db = dbFactory.Open()) + { + DbPocoTest(db); + } + } + + [Test] + public void Can_use_SqlServer2017DialectProvider() + { + var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServer2017Dialect.Provider); + using (var db = dbFactory.Open()) + { + DbPocoTest(db); + } + } + + [Test] + public void Can_use_SqlServer2019DialectProvider() + { + var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServer2019Dialect.Provider); + using (var db = dbFactory.Open()) + { + DbPocoTest(db); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/EnumTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/EnumTests.cs new file mode 100644 index 000000000..3356efcf5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/EnumTests.cs @@ -0,0 +1,99 @@ +using System.Linq; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class EnumTests : OrmLiteTestBase + { + [Test] + public void CanCreateTable() + { + OpenDbConnection().CreateTable(true); + } + + [Test] + public void CanStoreEnumValue() + { + using(var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum {Id = 1, EnumValue = SomeEnum.Value1}); + } + } + + [Test] + public void CanGetEnumValue() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; + con.Save(obj); + var target = con.SingleById(obj.Id); + Assert.AreEqual(obj.Id, target.Id); + Assert.AreEqual(obj.EnumValue, target.EnumValue); + } + } + + [Test] + public void CanQueryByEnumValue_using_select_with_expression() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Select(q => q.EnumValue == SomeEnum.Value1); + + Assert.AreEqual(2, target.Count()); + } + } + + [Test] + public void CanQueryByEnumValue_using_select_with_string() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Select("EnumValue = @value", new { value = SomeEnum.Value1 }); + + Assert.AreEqual(2, target.Count()); + } + } + + [Test] + public void CanQueryByEnumValue_using_where_with_AnonType() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + con.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var target = con.Where(new { EnumValue = SomeEnum.Value1 }); + + Assert.AreEqual(2, target.Count()); + } + } + } + + public enum SomeEnum + { + Value1, + Value2, + Value3 + } + + public class TypeWithEnum + { + public int Id { get; set; } + public SomeEnum EnumValue { get; set; } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/AdditiveExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/AdditiveExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/AdditiveExpressionsTest.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/AdditiveExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/Author.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/Author.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/Author.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/Author.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/AuthorUseCase.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/AuthorUseCase.cs new file mode 100644 index 000000000..097933fa9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/AuthorUseCase.cs @@ -0,0 +1,378 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.SqlServerTests.Expressions +{ + public class AuthorUseCase : OrmLiteTestBase + { + private List authors; + + public AuthorUseCase() + { + authors = new List(); + authors.Add(new Author() { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }); + authors.Add(new Author() { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }); + authors.Add(new Author() { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }); + authors.Add(new Author() { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }); + authors.Add(new Author() { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); + authors.Add(new Author() { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }); + authors.Add(new Author() { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }); + authors.Add(new Author() { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }); + authors.Add(new Author() { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }); + authors.Add(new Author() { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }); + authors.Add(new Author() { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }); + authors.Add(new Author() { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }); + authors.Add(new Author() { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }); + authors.Add(new Author() { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico", LastActivity = DateTime.Today }); + } + + [SetUp] + public void Setup() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + con.SaveAll(authors); + } + } + + [Test] + public void AuthorUsesCases() + { + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + + using var db = OpenDbConnection(); + int year = DateTime.Today.AddYears(-20).Year; + var lastDay = new DateTime(year, 12, 31); + int expected = 5; + + ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + Author result = null; + List results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(db.From().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + Assert.AreEqual(expected, results.Count); + Author a = new Author() { Birthday = lastDay }; + results = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); + Assert.AreEqual(expected, results.Count); + + // select authors from London, Berlin and Madrid : 6 + expected = 6; + //Sql.In can take params object[] + var city = "Berlin"; + ev.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => Sql.In(rn.City, new[] { "London", "Madrid", "Berlin" })); + Assert.AreEqual(expected, results.Count); + + // select authors from Bogota and Cartagena : 7 + expected = 7; + //... or Sql.In can take List + city = "Bogota"; + List cities = new List(); + cities.Add(city); + cities.Add("Cartagena"); + ev.Where().Where(rn => Sql.In(rn.City, cities)); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); + Assert.AreEqual(expected, results.Count); + + + // select authors which name starts with A + expected = 3; + ev.Where().Where(rn => rn.Name.StartsWith("A")); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => rn.Name.StartsWith("A")); + Assert.AreEqual(expected, results.Count); + + // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) + expected = 3; + var name = "GARZON"; + ev.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); + Assert.AreEqual(expected, results.Count); + + // select authors which name ends with garzon + //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters + //in the string. + //An underscore ("_") in the LIKE pattern matches any single character in the string. + //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). + expected = 3; + ev.Where().Where(rn => rn.Name.EndsWith("garzon")); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => rn.Name.EndsWith("garzon")); + Assert.AreEqual(expected, results.Count); + + + // select authors which name contains Benedict + expected = 2; + name = "Benedict"; + ev.Where().Where(rn => rn.Name.Contains(name)); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => rn.Name.Contains("Benedict")); + Assert.AreEqual(expected, results.Count); + a.Name = name; + results = db.Select(rn => rn.Name.Contains(a.Name)); + Assert.AreEqual(expected, results.Count); + + + // select authors with Earnings <= 50 + expected = 3; + var earnings = 50; + ev.Where().Where(rn => rn.Earnings <= earnings); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => rn.Earnings <= 50); + Assert.AreEqual(expected, results.Count); + + // select authors with Rate = 10 and city=Mexio + expected = 1; + city = "Mexico"; + ev.Where().Where(rn => rn.Rate == 10 && rn.City == city); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); + Assert.AreEqual(expected, results.Count); + + a.City = city; + results = db.Select(rn => rn.Rate == 10 && rn.City == a.City); + Assert.AreEqual(expected, results.Count); + + // enough selecting, lets update; + // set Active=false where rate =0 + expected = 2; + var rate = 0; + ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); + var rows = db.UpdateOnlyFields(new Author() { Active = false }, ev); + Assert.AreEqual(expected, rows); + + // insert values only in Id, Name, Birthday, Rate and Active fields + expected = 4; + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + ev.Where().Where(rn => !rn.Active); + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + + //update comment for City == null + expected = 2; + ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); + rows = db.UpdateOnlyFields(new Author() { Comments = "No comments" }, ev); + Assert.AreEqual(expected, rows); + + // delete where City is null + expected = 2; + rows = db.Delete(ev); + Assert.AreEqual(expected, rows); + + + // lets select all records ordered by Rate Descending and Name Ascending + expected = 14; + ev.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + var author = results.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel", author.Name); + + // select only first 5 rows .... + expected = 5; + ev.Limit(5); // note: order is the same as in the last sentence + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + + + // and finally lets select only Name and City (name will be "UPPERCASED" ) + + ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); + Console.WriteLine(ev.SelectExpression); + results = db.Select(ev); + author = results.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + ev.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); + Console.WriteLine(ev.SelectExpression); + results = db.Select(ev); + author = results.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + //paging : + ev.Limit(0, 4);// first page, page size=4; + results = db.Select(ev); + author = results.FirstOrDefault(); + Assert.AreEqual("Claudia Espinel".ToUpper(), author.Name); + + ev.Limit(4, 4);// second page + results = db.Select(ev); + author = results.FirstOrDefault(); + Assert.AreEqual("Jorge Garzon".ToUpper(), author.Name); + + ev.Limit(8, 4);// third page + results = db.Select(ev); + author = results.FirstOrDefault(); + Assert.AreEqual("Rodger Contreras".ToUpper(), author.Name); + + // select distinct.. + ev.ClearLimits().OrderBy(); // clear limit, clear order by + ev.SelectDistinct(r => r.City); + expected = 6; + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + + // select distinct with limit + ev.Limit(0, 4); + ev.OrderBy(r => r.City); + ev.SelectDistinct(r => r.City); + expected = 4; + results = db.Select(ev); + Assert.AreEqual(expected, results.Count); + + ev.ClearLimits().OrderBy(); + ev.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); + results = db.Select(ev); + var expectedResult = authors.Max(r => r.Birthday); + Assert.AreEqual(expectedResult, results[0].Birthday); + + ev.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); + results = db.Select(ev); + expectedResult = authors.Max(r => r.Birthday); + Assert.AreEqual(expectedResult, results[0].Birthday); + + var r1 = db.Single(ev); + Assert.AreEqual(expectedResult, r1.Birthday); + + var r2 = db.Scalar(e => Sql.Max(e.Birthday)); + Assert.AreEqual(expectedResult, r2); + + ev.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); + result = db.Single(ev); + expectedResult = authors.Min(r => r.Birthday); + Assert.AreEqual(expectedResult, result.Birthday); + + ev.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); + result = db.Single(ev); + expectedResult = authors.Min(r => r.Birthday); + Assert.AreEqual(expectedResult, result.Birthday); + + + ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + results = db.Select(ev); + var expectedStringResult = "Berlin"; + Assert.AreEqual(expectedStringResult, results[0].City); + + ev.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + results = db.Select(ev); + expectedStringResult = "Berlin"; + Assert.AreEqual(expectedStringResult, results[0].City); + + r1 = db.Single(ev); + Assert.AreEqual(expectedStringResult, r1.City); + + var expectedDecimal = authors.Max(e => e.Earnings); + Decimal? r3 = db.Scalar(e => Sql.Max(e.Earnings)); + Assert.AreEqual(expectedDecimal, r3.Value); + + var expectedString = authors.Max(e => e.Name); + string r4 = db.Scalar(e => Sql.Max(e.Name)); + Assert.AreEqual(expectedString, r4); + + var expectedDate = authors.Max(e => e.LastActivity); + DateTime? r5 = db.Scalar(e => Sql.Max(e.LastActivity)); + Assert.AreEqual(expectedDate, r5); + + var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); + DateTime? r51 = db.Scalar( + e => Sql.Max(e.LastActivity), + e => e.City == "Bogota"); + Assert.AreEqual(expectedDate51, r51); + + try + { + var expectedBool = authors.Max(e => e.Active); + bool r6 = db.Scalar(e => Sql.Max(e.Active)); + Assert.AreEqual(expectedBool, r6); + } + catch //(Exception e) + { + //???? + //if (dialect.Name == "PostgreSQL") + // Console.WriteLine("OK PostgreSQL: " + e.Message); + //else + // Console.WriteLine("************** FAILED *************** " + e.Message); + } + + + + // Tests for predicate overloads that make use of the expression visitor + author = db.Single(q => q.Name == "Jorge Garzon"); + + author = db.Single(q => q.Name == "Does not exist"); + Assert.IsNull(author); + + author = db.Single(q => q.City == "Bogota"); + Assert.AreEqual("Angel Colmenares", author.Name); + + a.City = "Bogota"; + author = db.Single(q => q.City == a.City); + Assert.AreEqual("Angel Colmenares", author.Name); + + // count test + + var expectedCount = authors.Count(); + long r7 = db.Scalar(e => Sql.Count(e.Id)); + Assert.AreEqual(expectedCount, r7); + + expectedCount = authors.Count(e => e.City == "Bogota"); + r7 = db.Scalar( + e => Sql.Count(e.Id), + e => e.City == "Bogota"); + Assert.AreEqual(expectedCount, r7); + + ev.Update();// all fields will be updated + // select and update + expected = 1; + var rr = db.Single(rn => rn.Name == "Luis garzon"); + rr.City = "Madrid"; + rr.Comments = "Updated"; + ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated + rows = db.UpdateOnlyFields(rr, ev); // == dbCmd.Update(rr) but it returns void + Assert.AreEqual(expected, rows); + + expected = 0; + ev.Where().Where(r => r.City == "Ciudad Gotica"); + rows = db.UpdateOnlyFields(rr, ev); + Assert.AreEqual(expected, rows); + + expected = db.Select(x => x.City == "Madrid").Count; + author = new Author() { Active = false }; + rows = db.UpdateOnlyFields(author, x => x.Active, x => x.City == "Madrid"); + Assert.AreEqual(expected, rows); + + expected = db.Select(x => x.Active == false).Count; + rows = db.Delete(x => x.Active == false); + Assert.AreEqual(expected, rows); + + // Sql.In(empty array) and Sql.In(null) should evaluate to false rather than failing + + expected = 0; + results = db.Select(rn => Sql.In(rn.City, new string[0])); + Assert.AreEqual(expected, results.Count); + results = db.Select(rn => Sql.In(rn.City, (string[])null)); + Assert.AreEqual(expected, results.Count); + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/ConditionalExpressionTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/ConditionalExpressionTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/ConditionalExpressionTest.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/ConditionalExpressionTest.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/EqualityExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/EqualityExpressionsTest.cs new file mode 100644 index 000000000..691ce7900 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/EqualityExpressionsTest.cs @@ -0,0 +1,305 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.SqlServerTests.Expressions +{ + public class EqualityExpressionsTest : ExpressionsTestBase + { + [Test] + public void Can_select_equals_constant_int_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn == 3); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_equals_variable_int_expression() + { +// ReSharper disable ConvertToConstant.Local + var columnValue = 3; +// ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = columnValue, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn == columnValue); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_equals_int_method_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_not_equals_constant_int_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn != 3); + + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } + + [Test] + public void Can_select_not_equals_variable_int_expression() + { + // ReSharper disable ConvertToConstant.Local + var columnValue = 3; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = columnValue, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn != columnValue); + + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } + + [Test] + public void Can_select_not_equals_int_method_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.IntColumn != GetValue(3)); + + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } + + + [Test] + public void Can_select_equals_constant_bool_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + +// ReSharper disable RedundantBoolCompare + var actual = OpenDbConnection().Select(q => q.BoolColumn == true); +// ReSharper restore RedundantBoolCompare + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_equals_constant_bool_expression2() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + // ReSharper disable RedundantBoolCompare + var actual = OpenDbConnection().Select(q => q.BoolColumn); + // ReSharper restore RedundantBoolCompare + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_equals_variable_bool_expression() + { + // ReSharper disable ConvertToConstant.Local + var columnValue = true; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.BoolColumn == columnValue); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_equals_bool_method_expression() + { + var expected = new TestType() + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.BoolColumn == GetValue(true)); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_equals_null_espression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test", + NullableCol = new TestType { StringColumn = "sometext" } + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.NullableCol == null); + + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 10); + CollectionAssert.DoesNotContain(actual, expected); + } + + [Test] + public void Can_select_not_equals_null_espression() + { + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test", + NullableCol = new TestType { StringColumn = "sometext" } + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => q.NullableCol != null); + + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } + + // Assume not equal works ;-) + + [Test] + public void Can_select_equals_coalesce_on_the_left_expression() + { + // ReSharper disable ConvertToConstant.Local + object stringVal = "sometext"; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test", + NullableCol = "sometext" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => (q.NullableCol ?? "othertext") == stringVal); + + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 1); // this passes, because PARAMS: @0=othertext, @1=sometext + CollectionAssert.Contains(actual, expected); + } + + [Test] + public void Can_select_equals_coalesce_on_the_right_expression() + { + // ReSharper disable ConvertToConstant.Local + object stringVal = "sometext"; + // ReSharper restore ConvertToConstant.Local + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test", + NullableCol = "sometext" + }; + + EstablishContext(10, expected); + + var actual = OpenDbConnection().Select(q => stringVal == (q.NullableCol ?? "othertext")); + + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 1); // this will fail for now, because PARAMS: @0=othertext, @1={Text:"COALESCE(""NullableCol"",@0)"} + CollectionAssert.Contains(actual, expected); // this will fail as well + } + + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/ExpressionsTestBase.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/ExpressionsTestBase.cs new file mode 100644 index 000000000..26b4f165e --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/ExpressionsTestBase.cs @@ -0,0 +1,85 @@ +using System; +using System.Data; +using System.Linq; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.SqlServerTests.Expressions +{ + public class ExpressionsTestBase : OrmLiteTestBase + { + [SetUp] + public void Setup() + { + OpenDbConnection().CreateTable(true); + } + + //Avoid painful refactor to change all tests to use a using pattern + private IDbConnection db; + + public override IDbConnection OpenDbConnection(string connString = null, IOrmLiteDialectProvider dialectProvider = null) + { + dialectProvider ??= OrmLiteConfig.DialectProvider; + + if (db != null && db.State != ConnectionState.Open) + db = null; + + return db ??= base.OpenDbConnection(connString, dialectProvider); + } + + [TearDown] + public void TearDown() + { + if (db == null) + return; + db.Dispose(); + db = null; + } + + public T GetValue(T item) + { + return item; + } + + protected void EstablishContext(int numberOfRandomObjects) + { + EstablishContext(numberOfRandomObjects, null); + } + + protected void EstablishContext(int numberOfRandomObjects, params TestType[] obj) + { + if (obj == null) + obj = new TestType[0]; + + using (var con = OpenDbConnection()) + { + foreach (var t in obj) + { + con.Insert(t); + } + + var random = new Random((int)(DateTime.UtcNow.Ticks ^ (DateTime.UtcNow.Ticks >> 4))); + for (var i = 0; i < numberOfRandomObjects; i++) + { + TestType o = null; + + while (o == null) + { + int intVal = random.Next(); + + o = new TestType + { + BoolColumn = random.Next()%2 == 0, + IntColumn = intVal, + StringColumn = Guid.NewGuid().ToString() + }; + + if (obj.Any(x => x.IntColumn == intVal)) + o = null; + } + + con.Insert(o); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/JsonExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/JsonExpressionsTest.cs new file mode 100644 index 000000000..db3bd6a1b --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/JsonExpressionsTest.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Configuration; + +using ServiceStack.Logging; +using ServiceStack.OrmLite; +using ServiceStack.OrmLite.SqlServer.Converters; + +using NUnit.Framework; + +namespace ServiceStack.OrmLite.SqlServerTests.Expressions +{ + public class JsonExpressionsTest : OrmLiteTestBase + { + public static Address Addr { get; set; } + = new Address + { + Line1 = "1234 Main Street", + Line2 = "Apt. 404", + City = "Las Vegas", + State = "NV" + }; + + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + OrmLiteConfig.DialectProvider = SqlServer2016Dialect.Provider; + OrmLiteConfig.DialectProvider.RegisterConverter(new SqlServerJsonStringConverter()); + OrmLiteConfig.DialectProvider.RegisterConverter
(new SqlServerJsonStringConverter()); + + ConnectionString = GetConnectionString(); + + Db = OpenDbConnection(); + + // Load test data + Db.DropAndCreateTable(); + Db.Insert(new TestType { Id = 1, StringColumn = "not json" }); + Db.Insert(new TestType { Id = 2, StringColumn = Addr.ToJson() }); + } + + [OneTimeTearDown] + public void TextFixtureTearDown() + { + if (Db != null) + { + if (Db.State == System.Data.ConnectionState.Open) + Db.Close(); + + Db.Dispose(); + } + } + + + [Test] + public void Can_test_if_string_field_contains_json() + { + // test if string field is not JSON with Sql.IsJson + var j = Db.From() + .Select(x => Sql.IsJson(x.StringColumn)) + .Where(x => x.Id == 1); + var isJson = Db.Scalar(j); + + Assert.IsFalse(isJson); + + // test if string field is JSON with Sql.IsJson + j = Db.From() + .Select(x => Sql.IsJson(x.StringColumn)) + .Where(x => x.Id == 2); + isJson = Db.Scalar(j); + + Assert.IsTrue(isJson); + } + + [Test] + public void Can_select_using_a_json_scalar_filter() + { + // retrieve records where City in Address is NV (1 record) + var actual = Db.Select(q => + Sql.JsonValue(q.StringColumn, "$.State") == "NV" + && q.Id == 2 + ); + + Assert.IsNotEmpty(actual); + + // retrieve records where City in Address is FL (0 records) + actual = Db.Select(q => + Sql.JsonValue(q.StringColumn, "$.State") == "FL" + && q.Id == 2 + ); + + Assert.IsEmpty(actual); + } + + [Test] + public void Can_select_a_json_scalar_value() + { + // retrieve only the State in a field that contains a JSON Address + var state = Db.Scalar( + Db.From() + .Where(q => q.Id == 2) + .Select(q => + Sql.JsonValue(q.StringColumn, "$.State") + ) + ); + + Assert.AreEqual(state, Addr.State); + } + + [Test] + public void Can_select_a_json_object_value() + { + // demo how to retrieve inserted JSON string directly to an object + var address = Db.Scalar
( + Db.From() + .Where(q => q.Id == 2) + .Select(q => q.StringColumn) + ); + + Assert.That(Addr.Line1, Is.EqualTo(address.Line1)); + Assert.That(Addr.Line2, Is.EqualTo(address.Line2)); + Assert.That(Addr.City, Is.EqualTo(address.City)); + Assert.That(Addr.State, Is.EqualTo(address.State)); + } + + [Ignore("Not functioning properly, issue with converter")] + [Test] + public void Can_insert_an_object_directly_to_json() + { + var tableName = Db.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition); + var sql = $"INSERT {tableName} (StringColumn) VALUES (@Address);"; + + // breaks here with an invalid conversion error from Address to string + Db.ExecuteSql(sql, new { Id = 3, Address = Addr }); + + // demo how to retrieve inserted JSON string directly to an object + var address = Db.Single
( + Db.From() + .Where(q => q.Id == 3) + .Select(q => q.StringColumn) + ); + + Assert.That(Addr.Line1, Is.EqualTo(address.Line1)); + Assert.That(Addr.Line2, Is.EqualTo(address.Line2)); + Assert.That(Addr.City, Is.EqualTo(address.City)); + Assert.That(Addr.State, Is.EqualTo(address.State)); + } + + [SqlJson] + public class Address + { + public string Line1 { get; set; } + public string Line2 { get; set; } + public string City { get; set; } + public string State { get; set; } + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/LogicalExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/LogicalExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/LogicalExpressionsTest.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/LogicalExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/MultiplicativeExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/MultiplicativeExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/MultiplicativeExpressionsTest.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/MultiplicativeExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/OrmLiteCountTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/OrmLiteCountTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/OrmLiteCountTests.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/OrmLiteCountTests.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/PrimaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/PrimaryExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/PrimaryExpressionsTest.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/PrimaryExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/RelationalExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/RelationalExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/RelationalExpressionsTest.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/RelationalExpressionsTest.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/StringFunctionTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/StringFunctionTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/StringFunctionTests.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/StringFunctionTests.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/TestType.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/TestType.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/TestType.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/TestType.cs diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Expressions/UnaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/UnaryExpressionsTest.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Expressions/UnaryExpressionsTest.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Expressions/UnaryExpressionsTest.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/ForeignKeyAttributeTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/ForeignKeyAttributeTests.cs new file mode 100644 index 000000000..026183716 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/ForeignKeyAttributeTests.cs @@ -0,0 +1,180 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + [TestFixture] + public class ForeignKeyAttributeTests : OrmLiteTestBase + { + [OneTimeSetUp] + public void Setup() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateSimpleForeignKey() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteCascade() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CascadesOnDelete() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + + dbConn.Save(new ReferencedType { Id = 1 }); + dbConn.Save(new TypeWithOnDeleteCascade { RefId = 1 }); + + Assert.AreEqual(1, dbConn.Select().Count); + Assert.AreEqual(1, dbConn.Select().Count); + + dbConn.Delete(r => r.Id == 1); + + Assert.AreEqual(0, dbConn.Select().Count); + Assert.AreEqual(0, dbConn.Select().Count); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteNoAction() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [NUnit.Framework.Ignore("Not supported in SQL Server")] + [Test] + public void CanCreateForeignWithOnDeleteRestrict() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteSetDefault() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + + [Test] + public void CanCreateForeignWithOnDeleteSetNull() + { + using (var dbConn = OpenDbConnection()) + { + dbConn.CreateTable(true); + } + } + } + + public class ReferencedType + { + public int Id { get; set; } + } + + + public class TypeWithSimpleForeignKey + { + [AutoIncrement] + public int Id { get; set; } + [References(typeof(ReferencedType))] + public int RefId { get; set; } + } + + public class TypeWithOnDeleteCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteAndUpdateCascade + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "CASCADE", OnUpdate = "CASCADE")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteNoAction + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "NO ACTION")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteRestrict + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "RESTRICT")] + public int? RefId { get; set; } + } + + public class TypeWithOnDeleteSetDefault + { + [AutoIncrement] + public int Id { get; set; } + + [Default(typeof(int), "17")] + [ForeignKey(typeof(ReferencedType), OnDelete = "SET DEFAULT")] + public int RefId { get; set; } + } + + public class TypeWithOnDeleteSetNull + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(ReferencedType), OnDelete = "SET NULL")] + public int? RefId { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/InsertParam_GetLastInsertId.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/InsertParam_GetLastInsertId.cs new file mode 100644 index 000000000..61c48b955 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/InsertParam_GetLastInsertId.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Dapper; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class InsertParam_GetLastInsertId : OrmLiteTestBase + { + [Test] + public void Can_GetLastInsertedId_using_InsertParam() + { + var testObject = new SimpleType { Name = "test" }; + + //verify that "normal" Insert works as expected + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + + con.Save(testObject); + Assert.That(testObject.Id, Is.GreaterThan(0), "normal Insert"); + } + + //test with InsertParam + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + + var lastInsertId = con.Insert(testObject, selectIdentity: true); + Assert.That(lastInsertId, Is.GreaterThan(0), "with InsertParam"); + } + } + + public class ServerGuid + { + [Default(typeof(Guid), "newid()")] + public Guid Id { get; set; } + + public string Name { get; set; } + } + + [Test] + public void Can_retrieve_ServerGuid() + { + using (var db = OpenDbConnection()) + using (var cmd = db.CreateCommand()) + { + db.DropAndCreateTable(); + + var obj = new ServerGuid { Name = "foo" }; + + cmd.GetDialectProvider().PrepareParameterizedInsertStatement(cmd, + insertFields: db.GetDialectProvider().GetNonDefaultValueInsertFields(obj)); + + cmd.CommandText = cmd.CommandText.Replace("VALUES", "OUTPUT inserted.Id VALUES"); + + cmd.GetDialectProvider().SetParameterValues(cmd, obj); + + var id = (Guid)cmd.ExecuteScalar(); + + Assert.That(id, Is.Not.EqualTo(default(Guid))); + + var insertedRow = db.SingleById(id); + + Assert.That(insertedRow.Name, Is.EqualTo("foo")); + } + } + + [PostCreateTable("DBCC CHECKIDENT (SeedTest, RESEED, 1000)")] + public class SeedTest + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + } + + [Test] + public void Can_create_table_starting_from_specific_seed() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + //var modelDef = typeof(SeedTest).GetModelMetadata(); + //var tableName = db.GetDialectProvider().GetQuotedTableName(modelDef); + //db.ExecuteSql($"DBCC CHECKIDENT ({tableName}, RESEED, 1000)"); + + db.Insert(new SeedTest { Name = "foo" }); + + Assert.That(db.Select()[0].Id, Is.EqualTo(1000)); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/CountDistinctTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/CountDistinctTests.cs new file mode 100644 index 000000000..4356d4222 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/CountDistinctTests.cs @@ -0,0 +1,42 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.SqlServerTests.Issues +{ + [TestFixture] + public class CountDistinctTests : OrmLiteTestBase + { + public class CountDistinctIssueTable + { + public long AutoId { get; set; } + } + + [Test] + public void CountDistinctTest() + { + Execute(SqlServerDialect.Provider); + } + + [Test] + public void CountDistinctTest2008() + { + Execute(SqlServer2008Dialect.Provider); + } + + [Test] + public void CountDistinctTest2012() + { + Execute(SqlServer2012Dialect.Provider); + } + + private void Execute(IOrmLiteDialectProvider dialectProvider) + { + using var db = OpenDbConnection(null, dialectProvider); + db.DropAndCreateTable(); + + var query = db.From(); + query.Skip(0); + + db.Scalar(query.Select(x => Sql.CountDistinct(x.AutoId))); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/CustomSelectWithPagingIssue.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/CustomSelectWithPagingIssue.cs new file mode 100644 index 000000000..ac50cc079 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/CustomSelectWithPagingIssue.cs @@ -0,0 +1,41 @@ +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests.Issues +{ + public class SimpleModel + { + public int Id { get; set; } + public int Foo { get; set; } + public int Bar { get; set; } + } + + [TestFixture] + public class CustomSelectWithPagingIssue + : OrmLiteTestBase + { + [Test] + public void Can_CustomSelect_With_Paging() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertAll(new[] { + new SimpleModel { Id = 1, Foo = 1, Bar = 42 }, + new SimpleModel { Id = 2, Foo = 2, Bar = 55 }, + }); + + var q = db.From() + .UnsafeSelect("SimpleModel.Id, CASE WHEN Foo IN (1,3) THEN 1 ELSE 0 END AS Foo, Bar") + .Take(1) + .Skip(1); + + var result = db.Select(q); + db.GetLastSql().Print(); + + Assert.That(result.Count, Is.EqualTo(1)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/DeleteWithGeoTypesIssue.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/DeleteWithGeoTypesIssue.cs new file mode 100644 index 000000000..341a4a1af --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/DeleteWithGeoTypesIssue.cs @@ -0,0 +1,62 @@ +using System; +using Microsoft.SqlServer.Types; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServerTests.Converters; + +namespace ServiceStack.OrmLite.SqlServerTests.Issues +{ + public class ModelWithGeo + { + [AutoIncrement] + public long Id { get; set; } + public string Name { get; set; } + public SqlGeography Location { get; set; } + } + + [TestFixture] + public class DeleteWithGeoTypesIssue : SqlServer2012ConvertersOrmLiteTestBase + { + [Test] + public void Can_delete_entity_with_Geo_Type() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithGeo { Name = "Foo", Location = RandomPosition() }); + db.Insert(new ModelWithGeo { Name = "Bar", Location = RandomPosition() }); + db.Insert(new ModelWithGeo { Name = "Qux", Location = RandomPosition() }); + + var rows = db.Select(); + Assert.That(rows.Count, Is.EqualTo(3)); + + var bar = db.Single(x => x.Name == "Bar"); + db.SqlScalar( + "DELETE FROM ModelWithGeo WHERE Id=@Id AND Location.STEquals(@Location) = 1", + new { Id = bar.Id, Location = bar.Location }); + + Assert.That(db.Select().Count, Is.EqualTo(2)); + + var qux = db.Single(x => x.Name == "Qux"); + db.Delete(qux); + + Assert.That(db.Select().Count, Is.EqualTo(1)); + + var foo = db.Single(x => x.Name == "Foo"); + db.DeleteById(foo.GetId()); + + Assert.That(db.Select().Count, Is.EqualTo(0)); + } + } + + private SqlGeography RandomPosition() + { + var rand = new Random(DateTime.Now.Millisecond * (int)DateTime.Now.Ticks); + double lat = Math.Round(rand.NextDouble() * 160 - 80, 6); + double lon = Math.Round(rand.NextDouble() * 360 - 180, 6); + var result = SqlGeography.Point(lat, lon, 4326).MakeValid(); + return result; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/JamesGeoIssue.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/JamesGeoIssue.cs new file mode 100644 index 000000000..94c662861 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/JamesGeoIssue.cs @@ -0,0 +1,45 @@ +using Microsoft.SqlServer.Types; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServerTests.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests.Issues +{ + public class James + { + [AutoIncrement] + public int id { get; set; } + + public SqlGeography loc { get; set; } + } + + [TestFixture] + public class JamesGeoIssue : SqlServer2012ConvertersOrmLiteTestBase + { + [Test] + public void Can_insert_and_select_GeoPoint() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var james = new James + { + loc = SqlGeography.Point(40.6898329, -74.0452177, 4326) + }; + db.Insert(james); + + + var result = db.SingleById(1); + + result.PrintDump(); + + Assert.That(result.id, Is.EqualTo(1)); + Assert.That(result.loc.Lat, Is.EqualTo(james.loc.Lat)); + Assert.That(result.loc.Long, Is.EqualTo(james.loc.Long)); + Assert.That(result.loc.STSrid, Is.EqualTo(james.loc.STSrid)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/LocalizationTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/LocalizationTests.cs new file mode 100644 index 000000000..a231ebb33 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/LocalizationTests.cs @@ -0,0 +1,45 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Logging; + +namespace ServiceStack.OrmLite.SqlServerTests.Issues +{ + public class LocalizationTest + { + [AutoIncrement] + public int Id { get; set; } + + public string Field { get; set; } + } + + public class LocalizationTests : OrmLiteTestBase + { + public LocalizationTests() + { + LogManager.LogFactory = new ConsoleLogFactory(debugEnabled:true); + } + + [Test] + public void Can_save_arabic_numbers() + { + OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode = true; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var model = new LocalizationTest { + Field = "۳۹۹۳" + }; + + db.Save(model); + + var row = db.SingleById(model.Id); + + Assert.That(row.Field, Is.EqualTo(model.Field)); + } + + OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode = false; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/PrecisionAndScaleTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/PrecisionAndScaleTests.cs new file mode 100644 index 000000000..2370faedc --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/PrecisionAndScaleTests.cs @@ -0,0 +1,46 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ServiceStack.OrmLite.SqlServerTests.Issues +{ + [TestFixture] + public class PrecisionAndScaleTests : OrmLiteTestBase + { + private const string DropProcedureSql = @" + IF OBJECT_ID('spGetNumber') IS NOT NULL + DROP PROCEDURE spGetNumber"; + + private const string CreateProcedureSql = @" + CREATE PROCEDURE spGetNumber + ( + @pNumber decimal(8,3) OUT + ) + AS + BEGIN + SELECT @pNumber = 12345.678 + END"; + + [Test] + public void Can_execute_stored_procedure_with_scale_precision_params_() + { + using (var db = OpenDbConnection()) + { + db.ExecuteSql(DropProcedureSql); + db.ExecuteSql(CreateProcedureSql); + + var cmd = db.SqlProc("spGetNumber"); + + var pNumber = cmd.AddParam("pNumber", 1.0, direction: ParameterDirection.Output, precision: 8, scale: 3); + + cmd.ExecuteNonQuery(); + + Assert.That(pNumber.Value, Is.EqualTo(12345.678)); + } + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/Issues/SerializationTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/SerializationTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/Issues/SerializationTests.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/SerializationTests.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/StringLengthParamTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/StringLengthParamTests.cs new file mode 100644 index 000000000..687ac5409 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/Issues/StringLengthParamTests.cs @@ -0,0 +1,69 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests.Issues +{ + class StringLengthParamTest + { + [AutoIncrement] + public int Id { get; set; } + + //[CustomField("VARCHAR(MAX)")] + [StringLength(StringLengthAttribute.MaxText)] + public string Name { get; set; } + } + + public class StringLengthParamTests + : OrmLiteTestBase + { + [Test] + public void Can_select_param_greater_than_default_length() + { + var hold = OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode; + OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode = false; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var name = "a" + new string('b', 8000) + "c"; + + db.Insert(new StringLengthParamTest + { + Name = name + }); + + var people = db.Select(p => p.Name == name); + + Assert.That(people.Count, Is.EqualTo(1)); + } + + OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode = hold; + } + + [Test] + public void Can_insert_only_param_greater_than_default_length() + { + var hold = OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode; + OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode = true; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var name = "a" + new string('b', 8000) + "c"; + + db.InsertOnly(new StringLengthParamTest + { + Name = name + }, s => s.Name); + + var people = db.Select(p => p.Name == name); + + Assert.That(people.Count, Is.EqualTo(1)); + } + + OrmLiteConfig.DialectProvider.GetStringConverter().UseUnicode = hold; + } + } +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerTests/NestedTransactions.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/NestedTransactions.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/NestedTransactions.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/NestedTransactions.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/OrmLiteTestBase.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/OrmLiteTestBase.cs new file mode 100644 index 000000000..ff8179927 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/OrmLiteTestBase.cs @@ -0,0 +1,37 @@ +using System; +using System.Configuration; +using System.Data; +using NUnit.Framework; +using ServiceStack.Logging; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class OrmLiteTestBase + { + protected virtual string ConnectionString { get; set; } + + public IDbConnection Db { get; set; } + + [OneTimeSetUp] + public virtual void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + ConnectionString = GetConnectionString(); + OrmLiteConfig.DialectProvider = SqlServerDialect.Provider; + } + + public void Log(string text) + { + Console.WriteLine(text); + } + + // public static string GetConnectionString() => "Data Source=tcp:localhost,48501\\SQLExpress;Initial Catalog=master;User Id=sa;Password=Test!tesT;Connect Timeout=120;MultipleActiveResultSets=True;"; + public static string GetConnectionString() => "Server=localhost;Database=test;User Id=test;Password=test;MultipleActiveResultSets=True;"; + public virtual IDbConnection OpenDbConnection(string connString = null, IOrmLiteDialectProvider dialectProvider = null) + { + dialectProvider ??= OrmLiteConfig.DialectProvider; + connString ??= ConnectionString; + return new OrmLiteConnectionFactory(connString, dialectProvider).OpenDbConnection(); + } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/ReturnAttributeTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/ReturnAttributeTests.cs new file mode 100644 index 000000000..7591b1249 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/ReturnAttributeTests.cs @@ -0,0 +1,154 @@ +using System.Data; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite; +using NUnit.Framework; +using ServiceStack.Logging; +using ServiceStack.OrmLite.SqlServerTests; + +namespace ReturnAttributeTests +{ + public class UserSequence + { + [Sequence("Gen_UserSequence_Id"), ReturnOnInsert] + public int Id { get; set; } + + public string Name { get; set; } + public string UserName { get; set; } + public string Email { get; set; } + } + + public class UserSequence3 + { + [Sequence("Gen_UserSequence_Id"), ReturnOnInsert] + public int Id { get; set; } + + public string Name { get; set; } + public string UserName { get; set; } + public string Email { get; set; } + + [Sequence("Gen_Counter")] + public int Counter { get; set; } + + [Sequence("Gen_Counter_Return"), ReturnOnInsert] + public int CounterReturn { get; set; } + } + + public class TestsBase + { + private OrmLiteConnectionFactory dbFactory; + + protected string ConnectionString { get; set; } + protected IOrmLiteDialectProvider DialectProvider { get; set; } + protected OrmLiteConnectionFactory DbFactory => dbFactory ??= new OrmLiteConnectionFactory(ConnectionString, DialectProvider); + + public TestsBase() + { + } + + protected void Init() + { + LogManager.LogFactory = new ConsoleLogFactory(debugEnabled:true); + } + + public IDbConnection OpenDbConnection() + { + Init(); + return DbFactory.OpenDbConnection(); + } + } + + public class ReturnAttributeTests : TestsBase + { + public ReturnAttributeTests() + { + ConnectionString = OrmLiteTestBase.GetConnectionString(); + DialectProvider = SqlServer2012Dialect.Provider; + } + + [Test] + public void Does_use_and_return_Sequence_on_Insert() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var user = new UserSequence { Name = "me", Email = "me@mydomain.com" }; + user.UserName = user.Email; + + db.Insert(user); + Assert.That(user.Id, Is.GreaterThan(0), "normal Insert"); + } + } + + [Test] + public void Does_use_and_return_Sequence_on_Save() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var user = new UserSequence { Name = "me", Email = "me@mydomain.com" }; + user.UserName = user.Email; + + db.Save(user); + Assert.That(user.Id, Is.GreaterThan(0), "normal Insert"); + } + } + + [Test] + public void Can_use_3_Sequences_on_Insert() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var user = new UserSequence3 { Name = "me", Email = "me@mydomain.com" }; + user.UserName = user.Email; + + db.Insert(user); + Assert.That(user.Id, Is.GreaterThan(0), "normal Insert"); + Assert.That(user.CounterReturn, Is.GreaterThan(0), "counter sequence ok"); + Assert.That(user.Counter, Is.EqualTo(0)); + + var dbUser = db.SingleById(user.Id); + Assert.That(dbUser.Counter, Is.GreaterThan(0)); + } + } + + [Test] + public void Does_generate_Sql_with_Sequence() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var user = new UserSequence { Name = "me", Email = "me@mydomain.com" }; + user.UserName = user.Email; + + var id = db.Insert(user); + var sql = db.GetLastSql(); + Assert.That(sql, Is.EqualTo("INSERT INTO \"UserSequence\" (\"Id\",\"Name\",\"UserName\",\"Email\") OUTPUT INSERTED.\"Id\" VALUES (NEXT VALUE FOR \"Gen_UserSequence_Id\",@Name,@UserName,@Email)"), "normal Insert"); + } + } + + [Test] + public void Does_drop_and_create_tables_with_sequences() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + Assert.That(!db.TableExists()); + + db.CreateTable(); + Assert.That(db.TableExists()); + + db.DropTable(); + Assert.That(!db.TableExists()); + + db.CreateTable(); + Assert.That(db.TableExists()); + } + } + + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/RowVersionTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/RowVersionTests.cs new file mode 100644 index 000000000..16abaf823 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/RowVersionTests.cs @@ -0,0 +1,303 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.Data; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Dapper; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + [TestFixture] + public class RowVersionTests : OrmLiteTestBase + { + public class ByteChildTbl + { + [PrimaryKey] + public Guid Id { get; set; } + + [References(typeof(ByteTbl))] + public Guid ParentId { get; set; } + + [RowVersion] + public byte[] RowVersion { get; set; } + + + } + + public class ByteTbl + { + [PrimaryKey] + public Guid Id { get; set; } + + public string Text { get; set; } + + [RowVersion] + public byte[] RowVersion { get; set; } + + [Reference] + public List Children { get; set; } = new List(); + } + + public class UlongChildTbl + { + [PrimaryKey] + public Guid Id { get; set; } + + [References(typeof(UlongTbl))] + public Guid ParentId { get; set; } + + [RowVersion] + public ulong RowVersion { get; set; } + } + + public class UlongTbl + { + [PrimaryKey] + public Guid Id { get; set; } + + public string Text { get; set; } + + // Use of ulong makes embedded Dapper functionality unavailable + [RowVersion] + public ulong RowVersion { get; set; } + + [Reference] + public List Children { get; set; } = new List(); + } + + [Test] + public void Read_and_write_to_tables_with_rowversions() + { + using (var db = OpenDbConnection()) + { + // Show that we can drop and create tables with rowversions of both .NET types and both get created as ROWVERSION in MSSQL + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + + + + + { + // Confirm off new Ormlite CRUD functionality with byte[] rowversion + + var byteId = Guid.NewGuid(); + db.Insert(new ByteTbl() { Id = byteId }); + + var getByteRecord = db.SingleById(byteId); + getByteRecord.Text += " Updated"; + db.Update(getByteRecord); //success! + + getByteRecord.Text += "Attempting to update stale record"; + + //Can't update stale record + Assert.Throws(() => db.Update(getByteRecord)); + + //Can update latest version + var updatedRow = db.SingleById(byteId); // fresh version + updatedRow.Text += "Update Success!"; + db.Update(updatedRow); + + updatedRow = db.SingleById(byteId); + db.Delete(updatedRow); // can delete fresh version + } + + + { + // confirm original Ormlite CRUD functionality based on ulong rowversion + + var ulongId = Guid.NewGuid(); + db.Insert(new UlongTbl { Id = ulongId }); + + var getUlongRecord = db.SingleById(ulongId); + getUlongRecord.Text += " Updated"; + db.Update(getUlongRecord); //success! + + getUlongRecord.Text += "Attempting to update stale record"; + + //Can't update stale record + Assert.Throws(() => db.Update(getUlongRecord)); + + // Can update latest version + var updatedUlongRow = db.SingleById(ulongId); // fresh version + updatedUlongRow.Text += "Update Success!"; + db.Update(updatedUlongRow); + + updatedUlongRow = db.SingleById(ulongId); + db.Delete(updatedUlongRow); // can delete fresh version + } + + + { + // Confirm that original ulong rowversion unfortunately fails with Dapper custom sql queries + + var ulongId = Guid.NewGuid(); + db.Insert(new UlongTbl { Id = ulongId }); + + // As a further example, using Dapper but without rowversion column WILL work (but rowversion will NOT be set of course) + var thisDapperQryWorks = db.Query("select Id, Text from [UlongTbl]").ToList(); + Assert.True(thisDapperQryWorks.Count == 1); + + // But any time RowVersion as ulong is include... no joy.. the map from db rowversion to ulong in dapper fails + Assert.Throws(() => db.Query("select Id, Text, Rowversion from [UlongTbl]")); + } + + + { + // Now test out use of new byte[] rowversion with Dapper custom sql queries + + var byteId = Guid.NewGuid(); + db.Insert(new ByteTbl { Id = byteId }); + + // As a further example, using Dapper but without rowversion column WILL work, BUT the rowversion WONT BE SET (of course) + var thisDapperQryWorks = db.Query("select Id, Text from [ByteTbl]").ToList(); + Assert.True(thisDapperQryWorks.Count == 1); + Assert.True(thisDapperQryWorks.First().RowVersion == default(byte[])); + + // But any time RowVersion as ulong is include... no joy.. the map from db rowversion to ulong in dapper fails + var thisDapperQryWithRowVersionAlsoWorks = db.Query("select Id, Text, Rowversion from [ByteTbl]").ToList(); + Assert.True(thisDapperQryWithRowVersionAlsoWorks.Count == 1); + Assert.True(thisDapperQryWithRowVersionAlsoWorks.First().RowVersion != default(byte[])); + } + + + { + // test original ulong version with child operations + var ulongId1 = Guid.NewGuid(); + db.Save(new UlongTbl + { + Id = ulongId1, + Children = new List() + { + new UlongChildTbl { Id = Guid.NewGuid() }, + new UlongChildTbl { Id = Guid.NewGuid() } + } + }, references: true); + var ulongObj1 = db.LoadSelect(x => x.Id == ulongId1, x => x.Children).First(); + Assert.AreNotEqual(default(byte[]), ulongObj1.RowVersion); + Assert.AreNotEqual(default(byte[]), ulongObj1.Children[0].RowVersion); + Assert.AreNotEqual(default(byte[]), ulongObj1.Children[1].RowVersion); + + var ulongId2 = Guid.NewGuid(); + db.Save(new UlongTbl + { + Id = ulongId2, + Children = new List() + { + new UlongChildTbl {Id = Guid.NewGuid()}, + new UlongChildTbl {Id = Guid.NewGuid()} + } + }, references: true); + var ulongObj2 = db.LoadSelect(x => x.Id == ulongId2, x => x.Children).First(); + Assert.AreNotEqual(default(byte[]), ulongObj2.RowVersion); + Assert.AreNotEqual(default(byte[]), ulongObj2.Children[0].RowVersion); + Assert.AreNotEqual(default(byte[]), ulongObj2.Children[1].RowVersion); + + // COnfirm multip select logic works + var q = db.From() + .Join() + ; + var results = db.SelectMulti(q); + foreach (var tuple in results) + { + UlongTbl parent = tuple.Item1; + UlongChildTbl child = tuple.Item2; + Assert.AreNotEqual(default(byte[]), parent.RowVersion); + Assert.AreNotEqual(default(byte[]), child.RowVersion); + } + } + + { + // test byte[] version with child operations + var byteid1 = Guid.NewGuid(); + db.Save(new ByteTbl + { + Id = byteid1, + Children = new List() + { + new ByteChildTbl() { Id = Guid.NewGuid(), ParentId = byteid1}, + new ByteChildTbl { Id = Guid.NewGuid(), ParentId = byteid1 } + } + }, references: true); + var byteObj1 = db.LoadSelect(x => x.Id == byteid1, x => x.Children).First(); + Assert.AreNotEqual(default(byte[]), byteObj1.RowVersion); + Assert.AreNotEqual(default(byte[]), byteObj1.Children[0].RowVersion); + Assert.AreNotEqual(default(byte[]), byteObj1.Children[1].RowVersion); + + var byteid2 = Guid.NewGuid(); + db.Save(new ByteTbl + { + Id = byteid2, + Children = new List() + { + new ByteChildTbl {Id = Guid.NewGuid(), ParentId = byteid2}, + new ByteChildTbl {Id = Guid.NewGuid(), ParentId = byteid2} + } + }, references: true); + var byteObj2 = db.LoadSelect(x => x.Id == byteid2, x => x.Children).First(); + Assert.AreNotEqual(default(byte[]), byteObj2.RowVersion); + Assert.AreNotEqual(default(byte[]), byteObj2.Children[0].RowVersion); + Assert.AreNotEqual(default(byte[]), byteObj2.Children[1].RowVersion); + + // COnfirm multip select logic works + var q = db.From() + .Join() + ; + var results = db.SelectMulti(q); + foreach (var tuple in results) + { + ByteTbl parent = tuple.Item1; + ByteChildTbl child = tuple.Item2; + Assert.AreNotEqual(default(byte[]), parent.RowVersion); + Assert.AreNotEqual(default(byte[]), child.RowVersion); + } + } + + + { + // test the multi select using dapper + + var byteid2 = Guid.NewGuid(); + db.Save(new ByteTbl + { + Id = byteid2, + Children = new List() + { + new ByteChildTbl {Id = Guid.NewGuid(), ParentId = byteid2}, + new ByteChildTbl {Id = Guid.NewGuid(), ParentId = byteid2} + } + }, references: true); + + var q = db.From() + .Join() + .Select("*"); + + using (var multi = db.QueryMultiple(q.ToSelectStatement())) + { + var results = multi.Read>(Tuple.Create).ToList(); + + foreach (var tuple in results) + { + ByteTbl parent = tuple.Item1; + ByteChildTbl child = tuple.Item2; + Assert.AreNotEqual(default(byte[]), parent.RowVersion); + Assert.AreNotEqual(default(byte[]), child.RowVersion); + } + Assert.True(results.Count > 0); + } + } + //Console.WriteLine("hit a key to end test"); + //Console.ReadLine(); + + + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/SchemaTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/SchemaTests.cs new file mode 100644 index 000000000..7883381e1 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/SchemaTests.cs @@ -0,0 +1,146 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServer.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + [TestFixture] + public class SchemaTests : OrmLiteTestBase + { + public class TableTest + { + public int Id { get; set; } + public string Name { get; set; } + } + + [Test] + public void Can_drop_and_add_column() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + Assert.That(db.ColumnExists(x => x.Id)); + Assert.That(db.ColumnExists(x => x.Name)); + + db.DropColumn(x => x.Name); + Assert.That(!db.ColumnExists(x => x.Name)); + + try + { + db.DropColumn(x => x.Name); + Assert.Fail("Should throw"); + } + catch (Exception) { } + + db.AddColumn(x => x.Name); + Assert.That(db.ColumnExists(x => x.Name)); + + try + { + db.AddColumn(x => x.Name); + Assert.Fail("Should throw"); + } + catch (Exception) {} + } + } + + [Schema("Schema")] + public class SchemaTest + { + public int Id { get; set; } + public string Name { get; set; } + } + + [Test] + public void Can_drop_and_add_column_with_Schema() + { + using (var db = OpenDbConnection()) + { + db.ExecuteSql( +@"IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'Schema') +BEGIN + EXEC( 'CREATE SCHEMA [Schema]' ); +END"); + db.DropAndCreateTable(); + + Assert.That(db.ColumnExists(x => x.Id)); + Assert.That(db.ColumnExists(x => x.Name)); + + db.DropColumn(x => x.Name); + Assert.That(!db.ColumnExists(x => x.Name)); + + try + { + db.DropColumn(x => x.Name); + Assert.Fail("Should throw"); + } + catch (Exception) { } + + db.AddColumn(x => x.Name); + Assert.That(db.ColumnExists(x => x.Name)); + + try + { + db.AddColumn(x => x.Name); + Assert.Fail("Should throw"); + } + catch (Exception) { } + } + } + + public class TestDecimalConverter + { + public int Id { get; set; } + public decimal Decimal { get; set; } + } + + [Test] + public void Can_replace_decimal_column() + { + SqlServerDialect.Provider.RegisterConverter(new SqlServerFloatConverter()); + + //Requires OrmLiteConnection Wrapper to capture last SQL executed + var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServerDialect.Provider); + + using (var db = dbFactory.OpenDbConnection()) + { + db.DropAndCreateTable(); + + Assert.That(db.GetLastSql(), Does.Contain("FLOAT")); + } + } + + [Test] + public void Get_actual_column_definition() + { + var sql = @"select COLUMN_NAME, data_type + + case + when data_type like '%text' or data_type like 'image' or data_type like 'sql_variant' or data_type like 'xml' + then '' + when data_type = 'float' + then '(' + convert(varchar(10), isnull(numeric_precision, 18)) + ')' + when data_type = 'numeric' or data_type = 'decimal' + then '(' + convert(varchar(10), isnull(numeric_precision, 18)) + ',' + convert(varchar(10), isnull(numeric_scale, 0)) + ')' + when (data_type like '%char' or data_type like '%binary') and character_maximum_length = -1 + then '(max)' + when character_maximum_length is not null + then '(' + convert(varchar(10), character_maximum_length) + ')' + else '' + end as COLUMN_DEFINITION +FROM INFORMATION_SCHEMA.COLUMNS"; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var results = db.Dictionary(sql + " WHERE table_name = 'TableTest'"); + results.PrintDump(); + Assert.That(results["Name"], Is.EqualTo("varchar(8000)")); + } + } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/ServiceStack.OrmLite.SqlServer.Tests.csproj b/tests/ServiceStack.OrmLite.SqlServer.Tests/ServiceStack.OrmLite.SqlServer.Tests.csproj new file mode 100644 index 000000000..098a0dbb7 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/ServiceStack.OrmLite.SqlServer.Tests.csproj @@ -0,0 +1,29 @@ + + + net472 + + ServiceStack.OrmLite.SqlServerTests + ServiceStack.OrmLite.SqlServerTests + default + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerExpressionVisitorQueryTest.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerExpressionVisitorQueryTest.cs new file mode 100644 index 000000000..976674ca1 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerExpressionVisitorQueryTest.cs @@ -0,0 +1,273 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ServiceStack.OrmLite.SqlServerTests.UseCase; +using System.Data; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + [TestFixture] + public class SqlServerExpressionVisitorQueryTest : OrmLiteTestBase + { + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + base.TestFixtureSetUp(); + + OrmLiteConfig.SanitizeFieldNameForParamNameFn = s => + (s ?? "").Replace(" ", "").Replace("°", ""); + } + + [Test] + public void Skip_Take_works_with_injected_Visitor() + { + using (var db = OpenDbConnection()) + { + FillTestEntityTableWithTestData(db); + + var result = db.Select(db.From().Limit(10, 100)); + + Assert.NotNull(result); + Assert.AreEqual(100, result.Count); + Assert.Less(10, result[0].Id); + Assert.Greater(111, result[99].Id); + } + } + + [Test] + public void test_if_limit_works_with_rows_and_skip() + { + using (var db = OpenDbConnection()) + { + FillTestEntityTableWithTestData(db); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.Limit(10, 100); + + var result = db.Select(ev); + Assert.NotNull(result); + Assert.AreEqual(100, result.Count); + Assert.Less(10, result[0].Id); + Assert.Greater(111, result[99].Id); + } + } + + [Test] + public void test_if_limit_works_with_rows() + { + using (var db = OpenDbConnection()) + { + FillTestEntityTableWithTestData(db); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.Limit(100); + + var result = db.Select(ev); + Assert.NotNull(result); + Assert.AreEqual(100, result.Count); + Assert.Less(0, result[0].Id); + Assert.Greater(101, result[99].Id); + } + } + + [Test] + public void test_if_limit_works_with_rows_and_skip_and_orderby() + { + using (var db = OpenDbConnection()) + { + FillTestEntityTableWithTestData(db); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.Limit(10, 100); + ev.OrderBy(e => e.Baz); + + var result = db.Select(ev); + Assert.NotNull(result); + Assert.AreEqual(100, result.Count); + Assert.LessOrEqual(result[10].Baz, result[11].Baz); + } + } + + [Test] + public void test_if_ev_still_works_without_limit_and_orderby() + { + using (var db = OpenDbConnection()) + { + FillTestEntityTableWithTestData(db); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.OrderBy(e => e.Baz); + ev.Where(e => e.Baz < 0.1m); + + var result = db.Select(ev); + Assert.NotNull(result); + Assert.IsTrue(result.Count > 0); + } + } + + [Test] + public void test_if_and_works_with_nullable_parameter() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + var id = db.Insert(new TestEntity + { + Foo = this.RandomString(16), + Bar = this.RandomString(16), + Baz = this.RandomDecimal() + }, selectIdentity: true); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.Where(e => e.Id == id); + int? i = null; + ev.And(e => e.NullInt == i); + + var result = db.Select(ev); + Assert.NotNull(result); + Assert.IsTrue(result.Count > 0); + } + } + + [Test] + public void test_if_limit_works_with_rows_and_skip_if_pk_columnname_has_space() + { + using (var db = OpenDbConnection()) + { + FillAliasedTestEntityTableWithTestData(db); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.Limit(10, 100); + + var result = db.Select(ev); + Assert.NotNull(result); + Assert.AreEqual(100, result.Count); + } + } + + [Test] + public void test_if_limit_works_with_rows_and_skip_and_orderby_if_pk_columnname_has_space() + { + using (var db = OpenDbConnection()) + { + FillAliasedTestEntityTableWithTestData(db); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.Limit(10, 100); + ev.OrderBy(e => e.Baz); + + var result = db.Select(ev); + Assert.NotNull(result); + Assert.AreEqual(100, result.Count); + Assert.LessOrEqual(result[10].Baz, result[11].Baz); + } + } + + [Test] + public void Can_query_table_with_special_alias() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new TestEntityWithAliases { Id = 1, Foo = "Foo", Bar = "Bar", Baz = 2 }); + + var row = db.SingleById(1); + Assert.That(row.Foo, Is.EqualTo("Foo")); + + row = db.Single(q => q.Bar == "Bar"); + Assert.That(row.Foo, Is.EqualTo("Foo")); + } + } + + [Test] + public void Can_OrderbyDesc_using_ComplexFunc() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new TestEntityWithAliases {Id = 1, Foo = "Foo", Bar = "Bar", Baz = 2}); + + System.Linq.Expressions.Expression> orderBy = x => + String.Concat(String.Concat("Text1: ", x.Foo), + String.Concat("Text2: ", x.Bar)); + var q = db.From().OrderByDescending(orderBy); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("desc,")); + + var target = db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + } + + [Test] + public void Can_OrderBy_using_isnull() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new TestEntityWithAliases {Id = 1, Foo = "Foo", Bar = "Bar", Baz = 2}); + System.Linq.Expressions.Expression> orderBy = x => x.Foo == null ? x.Foo : x.Bar; + var q = Db.From().OrderBy(orderBy); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("isnull")); + + var target = db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + } + + protected void FillTestEntityTableWithTestData(IDbConnection db) + { + db.CreateTable(true); + + for (int i = 1; i < 1000; i++) + { + db.Insert(new TestEntity() + { + Foo = RandomString(16), + Bar = RandomString(16), + Baz = RandomDecimal(i) + }); + } + } + + protected void FillAliasedTestEntityTableWithTestData(IDbConnection db) + { + db.CreateTable(true); + + for (int i = 1; i < 1000; i++) + { + db.Insert(new TestEntityWithAliases() + { + Foo = RandomString(16), + Bar = RandomString(16), + Baz = RandomDecimal(i) + }); + } + } + + protected string RandomString(int length) + { + var rnd = new System.Random(); + var buffer = new StringBuilder(); + + for (var i = 0; i < length; i++) + { + buffer.Append(Convert.ToChar(((byte)rnd.Next(254))) + .ToString(CultureInfo.InvariantCulture)); + } + + return buffer.ToString(); + } + + protected decimal RandomDecimal(int seed = 0) + { + var rnd = new Random(seed); + return new decimal(rnd.NextDouble()); + } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerTypes/Loader.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerTypes/Loader.cs new file mode 100644 index 000000000..0dc61f615 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerTypes/Loader.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace SqlServerTypes +{ + /// + /// Utility methods related to CLR Types for SQL Server + /// + internal class Utilities + { + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr LoadLibrary(string libname); + + /// + /// Loads the required native assemblies for the current architecture (x86 or x64) + /// + /// + /// Root path of the current application. Use Server.MapPath(".") for ASP.NET applications + /// and AppDomain.CurrentDomain.BaseDirectory for desktop applications. + /// + public static void LoadNativeAssemblies(string rootApplicationPath) + { + var nativeBinaryPath = IntPtr.Size > 4 + ? Path.Combine(rootApplicationPath, @"SqlServerTypes\x64\") + : Path.Combine(rootApplicationPath, @"SqlServerTypes\x86\"); + + LoadNativeAssembly(nativeBinaryPath, "msvcr100.dll"); + LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial110.dll"); + } + + private static void LoadNativeAssembly(string nativeBinaryPath, string assemblyName) + { + var path = Path.Combine(nativeBinaryPath, assemblyName); + var ptr = LoadLibrary(path); + if (ptr == IntPtr.Zero) + { + throw new Exception(string.Format( + "Error loading {0} (ErrorCode: {1})", + assemblyName, + Marshal.GetLastWin32Error())); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerTypes/readme.htm b/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerTypes/readme.htm new file mode 100644 index 000000000..0f9eade1a --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/SqlServerTypes/readme.htm @@ -0,0 +1,39 @@ + + + + Microsoft.SqlServer.Types + + + +
+

Action required to load native assemblies

+

+ To deploy an application that uses spatial data types to a machine that does not have 'System CLR Types for SQL Server' installed you also need to deploy the native assembly SqlServerSpatial110.dll. Both x86 (32 bit) and x64 (64 bit) versions of this assembly have been added to your project under the SqlServerTypes\x86 and SqlServerTypes\x64 subdirectories. The native assembly msvcr100.dll is also included in case the C++ runtime is not installed. +

+

+ You need to add code to load the correct one of these assemblies at runtime (depending on the current architecture). +

+

ASP.NET applications

+

+ For ASP.NET applications, add the following line of code to the Application_Start method in Global.asax.cs: +

    SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));
+

+

Desktop applications

+

+ For desktop applications, add the following line of code to run before any spatial operations are performed: +

    SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);
+

+
+ + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/FileStreamTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/FileStreamTests.cs new file mode 100644 index 000000000..7bd02d208 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/FileStreamTests.cs @@ -0,0 +1,105 @@ +using System; +using Microsoft.SqlServer.Types; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests.TableOptions +{ + [TestFixture] + public class FileTableAttributeTests : SqlServer2012TableOptionsOrmLiteTestBase + { + [Explicit("Requires FileGroups enabled in DB")] + [Test] + public void Can_select_from_FileTable() + { + Db.DropAndCreateTable(); + + var ft = new FileTable + { + Name = "content.txt", + Path = SqlHierarchyId.Parse("/1/"), + FileContent = "contents".ToUtf8Bytes(), + FileType = MimeTypes.PlainText + }; + Db.Insert(ft); + + var fileTable = Db.Single(x => x.Name == "content.txt"); + + Assert.IsNotNull(fileTable); + Assert.IsTrue(ft.FileContent.EquivalentTo(fileTable.FileContent)); + } + } + + + public class FileWithCustomSelect : FileTable + { + [CustomSelect("Contents.GetFileNamespacePath() + (CASE WHEN is_directory = 1 THEN '\' ELSE '' END)")] + public string FullPath { get; set; } + } + + [SqlServerFileTable(directory: "FILESTREAM_DIR")] + public class FileTable + { + [PrimaryKey] + [CustomField("uniqueidentifier ROWGUIDCOL NOT NULL")] + [Default("newuid()")] + [Alias("stream_id")] + public Guid Id { get; set; } + + [CustomField("varbinary(max) FILESTREAM")] + [Alias("file_stream")] + //[DataAnnotations.Ignore] + public byte[] FileContent { get; set; } + + [Alias("name")] + [StringLength(255)] + public string Name { get; set; } + + [Alias("path_locator")] + public SqlHierarchyId Path { get; set; } + + //[ForeignKey(typeof(FileStream))] + [Alias("parent_path_locator")] + [Compute] + public SqlHierarchyId? ParentPath { get; set; } + + [Alias("file_type")] + [Compute] + [StringLength(255)] + public string FileType { get; set; } + + [Alias("cached_file_size")] + [Compute] + public long? FileSize { get; set; } + + [Alias("creation_time")] + public DateTimeOffset CreationDateTime { get; set; } + + [Alias("last_write_time")] + public DateTimeOffset LastWriteDateTime { get; set; } + + [Alias("last_access_time")] + public DateTimeOffset? LastAccessDateTime { get; set; } + + [Alias("is_directory")] + public bool IsDirectory { get; set; } + + [Alias("is_offline")] + public bool IsOffline { get; set; } + + [Alias("is_hidden")] + public bool IsHidden { get; set; } + + [Alias("is_readonly")] + public bool IsReadOnly { get; set; } + + [Alias("is_archive")] + public bool IsArchive { get; set; } + + [Alias("is_system")] + public bool IsSystem { get; set; } + + [Alias("is_temporary")] + public bool IsTemporary { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/MemoryOptimizedAttributeTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/MemoryOptimizedAttributeTests.cs new file mode 100644 index 000000000..d511fffb2 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/MemoryOptimizedAttributeTests.cs @@ -0,0 +1,162 @@ +using System; +using System.Data.SqlClient; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests.TableOptions +{ + [TestFixture] + public class SqlServer2014MemoryOptimizedAttributeTests : SqlServer2014TableOptionsOrmLiteTestBase + { + [OneTimeSetUp] + public void Setup() + { + base.TestFixtureSetUp(); + + // memory optimised tables can't be created in system databases, create new db + var dbName = "MemOptTest"; + Db.ExecuteSql($"IF DB_ID (N'{dbName}') IS NOT NULL DROP DATABASE {dbName};"); + Db.ExecuteSql($"CREATE DATABASE {dbName};"); + Db.ExecuteSql($"ALTER DATABASE {dbName} SET AUTO_CLOSE OFF;"); + Db.ExecuteSql($"ALTER DATABASE {dbName} ADD FILEGROUP imoltp_mod CONTAINS MEMORY_OPTIMIZED_DATA"); + Db.ExecuteSql($"ALTER DATABASE {dbName} ADD FILE (name='imoltp_mod1', filename='.\\imoltp_mod1') TO FILEGROUP imoltp_mod"); + Db.ExecuteSql($"ALTER DATABASE {dbName} SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT=ON"); + Db.ExecuteSql($"USE {dbName};"); + + ConnectionString = ConnectionString.Replace("master", dbName); + + if (Db.TableExists()) + Db.DropTable(); + + if (Db.TableExists()) + Db.DropTable(); + + if (Db.TableExists()) + Db.DropTable(); + + if (Db.TableExists()) + Db.DropTable(); + } + + [Test] + public void Can_Create_Memory_Optimized_Table() + { + Db.CreateTable(true); + + var sql = Db.GetLastSql(); + + Assert.IsTrue(sql.Contains("MEMORY_OPTIMIZED = ON")); + Assert.IsFalse(sql.Contains("DURABILITY = SCHEMA_ONLY")); + Assert.IsFalse(sql.Contains("DURABILITY = SCHEMA_AND_DATA")); + + var name = "Test 1"; + var id = Db.Insert(new TypeWithMemTableNoDurability { Name = name }, selectIdentity: true); + var fromDb = Db.SingleById(id); + + Assert.AreEqual(name, fromDb.Name); + } + + [Test] + public void Can_Create_Memory_Optimized_Table_With_Schema_Only_Durability() + { + Db.CreateTable(true); + + var sql = Db.GetLastSql(); + + Assert.IsTrue(sql.Contains("MEMORY_OPTIMIZED = ON")); + Assert.IsTrue(sql.Contains("DURABILITY = SCHEMA_ONLY")); + Assert.IsFalse(sql.Contains("DURABILITY = SCHEMA_AND_DATA")); + + var name = "Test 2"; + var id = Db.Insert(new TypeWithMemTableSchemaOnlyDurability { Name = name }, selectIdentity: true); + var fromDb = Db.SingleById(id); + + Assert.AreEqual(name, fromDb.Name); + } + + [Test] + public void Can_Create_Memory_Optimized_Table_With_Schema_And_Data_Durability() + { + Db.CreateTable(true); + + var sql = Db.GetLastSql(); + + Assert.IsTrue(sql.Contains("MEMORY_OPTIMIZED = ON")); + Assert.IsFalse(sql.Contains("DURABILITY = SCHEMA_ONLY")); + Assert.IsTrue(sql.Contains("DURABILITY = SCHEMA_AND_DATA")); + + var name = "Test 3"; + var id = Db.Insert(new TypeWithMemTableSchemaAndDataDurability { Name = name }, selectIdentity: true); + var fromDb = Db.SingleById(id); + + Assert.AreEqual(name, fromDb.Name); + } + + [Test] + public void Can_not_Create_Memory_Optimized_Table_Without_BIN2_Collate_Hash_Index() + { + try + { + Db.CreateTable(true); + } + catch (Exception ex) + { + Assert.IsInstanceOf(ex); + } + } + + [Test] + public void Can_Create_Memory_Optimized_Table_With_Collated_Hash_Index() + { + var name = "Test 5"; + var index = "Test Index"; + + Db.CreateTable(true); + + var sql = Db.GetLastSql(); + + Assert.IsTrue(sql.Contains("MEMORY_OPTIMIZED = ON")); + Assert.IsTrue(sql.Contains("COLLATE")); + + var id = Db.Insert(new TypeWithMemTableWithCollatedHashIndex {Name = name, Index = index }, selectIdentity: true); + var fromDb = Db.SingleById(id); + + Assert.AreEqual(name, fromDb.Name); + Assert.AreEqual(index, fromDb.Index); + } + } + + public class TypeWithNoMemOptimization + { + [PrimaryKey] + public int Id { get; set; } + + public string Name { get; set; } + } + + [SqlServerMemoryOptimized] + public class TypeWithMemTableNoDurability : TypeWithNoMemOptimization { } + + [SqlServerMemoryOptimized(SqlServerDurability.SchemaOnly)] + public class TypeWithMemTableSchemaOnlyDurability : TypeWithNoMemOptimization { } + + [SqlServerMemoryOptimized(SqlServerDurability.SchemaAndData)] + public class TypeWithMemTableSchemaAndDataDurability : TypeWithNoMemOptimization { } + + [SqlServerMemoryOptimized] + public class TypeWithMemTableWithoutBIN2HashIndex : TypeWithNoMemOptimization + { + [StringLength(25)] + [SqlServerBucketCount(1000)] + public string Index { get; set; } + } + + [SqlServerMemoryOptimized] + public class TypeWithMemTableWithCollatedHashIndex : TypeWithNoMemOptimization + { + [StringLength(25)] + [SqlServerCollate("Latin1_General_100_BIN2")] + [SqlServerBucketCount(1000)] + public string Index { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/TableOptionsOrmLiteTestBase.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/TableOptionsOrmLiteTestBase.cs new file mode 100644 index 000000000..9f345ba66 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/TableOptionAttributes/TableOptionsOrmLiteTestBase.cs @@ -0,0 +1,56 @@ +using System; +using System.Configuration; +using NUnit.Framework; +using ServiceStack.Logging; +using ServiceStack.OrmLite.SqlServer.Converters; + +namespace ServiceStack.OrmLite.SqlServerTests.TableOptions +{ + public class SqlServer2012TableOptionsOrmLiteTestBase : OrmLiteTestBase + { + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + // Sql Server In-Memory OLTP does not support MARS + ConnectionString = GetConnectionString().Replace("MultipleActiveResultSets=True;", ""); + + var dialectProvider = SqlServerConverters.Configure(SqlServer2012Dialect.Provider); + + Db = new OrmLiteConnectionFactory(ConnectionString, dialectProvider).OpenDbConnection(); + } + } + + public class SqlServer2014TableOptionsOrmLiteTestBase : OrmLiteTestBase + { + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + // Sql Server In-Memory OLTP does not support MARS + ConnectionString = GetConnectionString().Replace("MultipleActiveResultSets=True;", ""); + + var dialectProvider = SqlServerConverters.Configure(SqlServer2014Dialect.Provider); + + Db = new OrmLiteConnectionFactory(ConnectionString, dialectProvider).OpenDbConnection(); + } + } + + public class SqlServer2016TableOptionsOrmLiteTestBase : OrmLiteTestBase + { + [OneTimeSetUp] + public override void TestFixtureSetUp() + { + LogManager.LogFactory = new ConsoleLogFactory(); + + // Sql Server In-Memory OLTP does not support MARS + ConnectionString = GetConnectionString().Replace("MultipleActiveResultSets=True;", ""); + + var dialectProvider = SqlServerConverters.Configure(SqlServer2016Dialect.Provider); + + Db = new OrmLiteConnectionFactory(ConnectionString, dialectProvider).OpenDbConnection(); + } + } +} diff --git a/src/ServiceStack.OrmLite.SqlServerTests/TypeWithByteArrayFieldTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/TypeWithByteArrayFieldTests.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/TypeWithByteArrayFieldTests.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/TypeWithByteArrayFieldTests.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/TypedExtensionTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/TypedExtensionTests.cs new file mode 100644 index 000000000..9b5d9363a --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/TypedExtensionTests.cs @@ -0,0 +1,59 @@ +using System.Configuration; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServer; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class TypedExtensionTests + { + public class TestDao + { + [PrimaryKey] + public int Id { get; set; } + + public string Thing { get; set; } + } + + private IOrmLiteDialectProvider provider; + private OrmLiteConnectionFactory factory; + + [OneTimeSetUp] + public void Setup() + { + provider = new SqlServer2014OrmLiteDialectProvider(); + var connectionString = OrmLiteTestBase.GetConnectionString(); + factory = new OrmLiteConnectionFactory(connectionString, provider, false); + } + + [OneTimeTearDown] + public void Teardown() + { + OrmLiteConfig.DialectProvider = provider; + + using var connection = factory.OpenDbConnection(); + if (connection.TableExists()) + { + connection.DropTable(); + } + } + + [Test] + public void GivenAnOrmLiteTypedConnectionFactory_WhenUsingOrmLiteExtensionsAndGlobalProviderNotSet_ThenArgumentNullExceptionIsNotThrown() + { + using var db = factory.OpenDbConnection(); + db.CreateTableIfNotExists(); + + var dao = new TestDao {Id = 1, Thing = "Thing"}; + + db.Insert(dao); + db.SingleById(1); + + dao.Thing = "New Thing"; + + db.Update(dao, d => d.Id == dao.Id); + db.Delete(dao); + db.DropTable(); + } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/UnicodeTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UnicodeTests.cs new file mode 100644 index 000000000..897ce6e04 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/UnicodeTests.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + /// + /// test for issue #69 + /// + class UnicodeTests : OrmLiteTestBase + { + [Test] + public void can_insert_and_retrieve_unicode_values() + { + //save and restore state, so it doesn't mess with other tests + var stringConverter = OrmLiteConfig.DialectProvider.GetStringConverter(); + bool prevUnicodestate = stringConverter.UseUnicode; + try { + stringConverter.UseUnicode = true; + + var testData = new[]{ + "árvíztűrő tükörfúrógép", + "ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP", //these are the Hungarian "special" characters, they work fine out of the box. At least on Hungarian_Technical_CI_AS + "♪♪♫", //this one comes back as 'ddd' + //greek alphabet + @" +Letter Name Sound value +Ancient[5] Modern[6] +Α α alpha [a] [aː] [a] +Β β beta [b] [v] +Γ γ gamma [ɡ] [ɣ] ~ [ʝ] +Δ δ delta [d] [ð] +Ε ε epsilon [e] [e] +Ζ ζ zeta [zd] (or [dz][7]) [z] +Η η eta [ɛː] [i] +Θ θ theta [tʰ] [θ] +Ι ι iota [i] [iː] [i] +Κ κ kappa [k] [k] ~ [c] +Λ λ lambda [l] [l] +Μ μ mu [m] [m] +Letter Name Sound value +Ancient Modern +Ν ν nu [n] [n] +Ξ ξ xi [ks] [ks] +Ο ο omicron [o] [o] +Π π pi [p] [p] +Ρ ρ rho [r] [r] +Σ σς sigma [s] [s] +Τ τ tau [t] [t] +Υ υ upsilon [y] [yː] [i] +Φ φ phi [pʰ] [f] +Χ χ chi [kʰ] [x] ~ [ç] +Ψ ψ psi [ps] [ps] +Ω ω omega [ɔː] [o] +" + }; + + using(var con = OpenDbConnection()) { + con.ExecuteSql(table_re_creation_script); + + foreach(var item in testData) { con.Insert(new Unicode_poco { Text = item }); } + + var fromDb = con.Select().Select(x => x.Text).ToArray(); + + CollectionAssert.AreEquivalent(testData, fromDb); + } + } + finally { stringConverter.UseUnicode = prevUnicodestate; } + } + + + /* * +--if you run this in SSMS, it produces 'ddd' +INSERT INTO [Unicode_poco] ([Text]) VALUES ('hai ♪♪♫') + +--if you run this in SSMS, it works fine +INSERT INTO [Unicode_poco] ([Text]) VALUES (N'hai ♪♪♫') + +select * from Unicode_poco + * */ + + + private class Unicode_poco + { + [PrimaryKey, AutoIncrement] + public int Id { get; set; } + + public string Text { get; set; } + } + + /// + /// because OrmLite does not create nvarchar columns + /// + private string table_re_creation_script = @" +IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Unicode_poco]') AND type in (N'U')) +DROP TABLE [dbo].[Unicode_poco]; + + +CREATE TABLE [dbo].[Unicode_poco]( + [Id] [int] IDENTITY(1,1) NOT NULL, + [Text] [nvarchar](4000) NULL, + CONSTRAINT [PK_Unicode_poco] PRIMARY KEY CLUSTERED +( + [Id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY]"; + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/UpdateTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UpdateTests.cs new file mode 100644 index 000000000..55b5e0247 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/UpdateTests.cs @@ -0,0 +1,161 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests +{ + public class UpdateTests : OrmLiteTestBase + { + [Test] + public void Can_execute_update_using_expression() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new SimpleType { Name = "Somename" }; + con.Save(obj); + var storedObj = con.SingleById(obj.Id); + + Assert.AreEqual(obj.Name, storedObj.Name); + + obj.Id = storedObj.Id; + obj.Name = "Someothername"; + con.Update(obj, q => q.Id == storedObj.Id); + + var target = con.SingleById(storedObj.Id); + + Assert.AreEqual(obj.Name, target.Name); + } + } + + [Test] + public void Can_execute_update_only() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new SimpleType { Name = "Somename" }; + con.Save(obj); + var storedObj = con.SingleById(obj.Id); + + Assert.AreEqual(obj.Name, storedObj.Name); + + var ev = OrmLiteConfig.DialectProvider.SqlExpression(); + ev.Update(); + ev.Where(q => q.Id == storedObj.Id); + storedObj.Name = "Someothername"; + + con.UpdateOnlyFields(storedObj, ev); + + var target = con.SingleById(storedObj.Id); + + Assert.AreEqual("Someothername", target.Name); + } + } + + + [Test] + public void Can_execute_update() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new SimpleType { Name = "Somename" }; + con.Save(obj); + var storedObj = con.SingleById(obj.Id); + + Assert.AreEqual(obj.Name, storedObj.Name); + + obj.Id = storedObj.Id; + obj.Name = "Someothername"; + con.Update(obj); + + var target = con.SingleById(storedObj.Id); + + Assert.AreEqual(obj.Name, target.Name); + } + } + + [Test] + public void Can_execute_update_using_aliased_columns() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new SimpleAliasedType { Name = "Somename" }; + con.Save(obj); + var storedObj = con.SingleById(obj.Id); + + Assert.AreEqual(obj.Name, storedObj.Name); + + obj.Id = storedObj.Id; + obj.Name = "Someothername"; + con.Update(obj); + + var target = con.SingleById(storedObj.Id); + + Assert.AreEqual(obj.Name, target.Name); + } + } + + [Test] + public void Can_execute_updateParam() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new SimpleType { Name = "Somename" }; + con.Save(obj); + var storedObj = con.SingleById(obj.Id); + + Assert.AreEqual(obj.Name, storedObj.Name); + + obj.Id = storedObj.Id; + obj.Name = "Someothername"; + con.Update(obj); + + var target = con.SingleById(storedObj.Id); + + Assert.AreEqual(obj.Name, target.Name); + } + } + + [Test] + public void Can_execute_updateParam_using_aliased_columns() + { + using (var con = OpenDbConnection()) + { + con.CreateTable(true); + var obj = new SimpleAliasedType { Name = "Somename" }; + con.Save(obj); + var storedObj = con.SingleById(obj.Id); + + Assert.AreEqual(obj.Name, storedObj.Name); + + obj.Id = storedObj.Id; + obj.Name = "Someothername"; + con.Update(obj); + + var target = con.SingleById(storedObj.Id); + + Assert.AreEqual(obj.Name, target.Name); + } + } + } + + + public class SimpleType + { + [AutoIncrement] + public int Id { get; set; } + public string Name { get; set; } + } + + public class SimpleAliasedType + { + [AutoIncrement] + public int Id { get; set; } + [Alias("NewName")] + public string Name { get; set; } + + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/ComplexJoinWithLimitAndNoOrderByTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/ComplexJoinWithLimitAndNoOrderByTests.cs new file mode 100644 index 000000000..2e104409c --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/ComplexJoinWithLimitAndNoOrderByTests.cs @@ -0,0 +1,106 @@ +using System; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests.UseCase +{ + public class Bar : IHasGuidId + { + [PrimaryKey] + [Alias("BarId")] + public Guid Id { get; set; } + + [Required] + public string Name { get; set; } + } + + public class Foo : IHasIntId + { + [AutoIncrement] + [PrimaryKey] + public int Id { get; set; } + + [Alias("FKBarId")] + [ForeignKey(typeof(Bar), ForeignKeyName = "fk_Foo_Bar")] + public Guid BarId { get; set; } + } + + internal class FooBarJoin + { + [BelongTo(typeof(Foo))] + public int Id { get; set; } + + [BelongTo(typeof(Bar))] + public Guid BarId { get; set; } + + [BelongTo(typeof(Bar))] + public string Name { get; set; } + } + + [TestFixture] + public class ComplexJoinWithLimitAndNoOrderByTests : OrmLiteTestBase + { + private static int _foo1Id; + private static int _foo2Id; + private static int _foo3Id; + private static Guid _bar1Id; + private static Guid _bar2Id; + private static Guid _bar3Id; + + private static void InitTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + _bar1Id = new Guid("5bd67b84-bfdb-4057-9799-5e7a72a6eaa9"); + _bar2Id = new Guid("a8061d08-6816-4e1e-b3d7-1178abcefa0d"); + _bar3Id = new Guid("84BF769D-5BA9-4506-A7D2-5030E5595EDC"); + + db.Insert(new Bar { Id = _bar1Id, Name = "Banana", }); + db.Insert(new Bar { Id = _bar2Id, Name = "Orange", }); + db.Insert(new Bar { Id = _bar3Id, Name = "Apple", }); + + _foo1Id = (int)db.Insert(new Foo { BarId = _bar1Id, }, true); + _foo2Id = (int)db.Insert(new Foo { BarId = _bar2Id, }, true); + _foo3Id = (int)db.Insert(new Foo { BarId = _bar3Id, }, true); + } + + [Test] + public void ComplexJoin_with_JoinSqlBuilder_and_limit_and_no_orderby() + { + using (var db = OpenDbConnection()) + { + InitTables(db); + + //JoinSqlBuilder is obsolete + //var jn = new JoinSqlBuilder() + // .Join(dp => dp.BarId, p => p.Id) + // //.OrderBy(f => f.Id) // Test fails without an explicity OrderBy because auto-generated OrderBy uses join table (FooBarJoin) name + // .Limit(1, 2); + + var jn = db.From() + .Join((f,b) => f.BarId == b.Id) + .Limit(1, 2); + + var results = db.Select(jn); + db.GetLastSql().Print(); + + results.PrintDump(); + + var fooBarJoin = results.FirstOrDefault(x => x.BarId == _bar1Id); + Assert.IsNull(fooBarJoin); + fooBarJoin = results.First(x => x.BarId == _bar2Id); + Assert.That(fooBarJoin.Id, Is.EqualTo(_foo2Id)); + fooBarJoin = results.First(x => x.BarId == _bar3Id); + Assert.That(fooBarJoin.Id, Is.EqualTo(_foo3Id)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/ComplexJoinWithLimitAndSpacesInAliasesTests.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/ComplexJoinWithLimitAndSpacesInAliasesTests.cs new file mode 100644 index 000000000..2916c8a43 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/ComplexJoinWithLimitAndSpacesInAliasesTests.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests.UseCase +{ + [Alias("Bar Table")] + public class BarSpace : IHasGuidId + { + [PrimaryKey] + [Alias("BarSpace Id")] + public Guid Id { get; set; } + + [Alias("BarSpace Name")] + [Required] + public string Name { get; set; } + } + + [Alias("Foo Table")] + public class FooSpace : IHasIntId + { + [AutoIncrement] + [PrimaryKey] + [Alias("FooSpace Id")] + public int Id { get; set; } + + [Alias("FK BarId")] + [ForeignKey(typeof(BarSpace), ForeignKeyName = "fk_FooSpace_BarSpace")] + public Guid BarId { get; set; } + } + + internal class FooSpaceBarSpaceJoin + { + [BelongTo(typeof(FooSpace))] + [Alias("FooSpace Id")] + public int Id { get; set; } + + [BelongTo(typeof(BarSpace))] + [Alias("BarSpace Id")] + public Guid BarId { get; set; } + + [BelongTo(typeof(BarSpace))] + [Alias("BarSpace Name")] + public string BarName { get; set; } + } + + [TestFixture] + public class ComplexJoinWithLimitAndSpacesInAliasesTests : OrmLiteTestBase + { + private static int _foo1Id; + private static int _foo2Id; + private static int _foo3Id; + private static Guid _bar1Id; + private static Guid _bar2Id; + private static Guid _bar3Id; + + private static void InitTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + _bar1Id = new Guid("5bd67b84-bfdb-4057-9799-5e7a72a6eaa9"); + _bar2Id = new Guid("a8061d08-6816-4e1e-b3d7-1178abcefa0d"); + _bar3Id = new Guid("84BF769D-5BA9-4506-A7D2-5030E5595EDC"); + + db.Insert(new BarSpace { Id = _bar1Id, Name = "Banana", }); + db.Insert(new BarSpace { Id = _bar2Id, Name = "Orange", }); + db.Insert(new BarSpace { Id = _bar3Id, Name = "Apple", }); + + _foo1Id = (int)db.Insert(new FooSpace { BarId = _bar1Id, }, true); + _foo2Id = (int)db.Insert(new FooSpace { BarId = _bar2Id, }, true); + _foo3Id = (int)db.Insert(new FooSpace { BarId = _bar3Id, }, true); + } + + [Test] + public void ComplexJoin_with_JoinSqlBuilder_and_limit_with_spaces_in_aliases() + { + using (var db = OpenDbConnection()) + { + InitTables(db); + + //JoinSqlBuilder is obsolete + //var jn = new JoinSqlBuilder() + // .Join(dp => dp.BarId, p => p.Id) + // .OrderBy(f => f.Id) + // .Limit(1, 2); + + var jn = db.From() + .Join((f,b) => f.BarId == b.Id) + .OrderBy(f => f.Id) + .Limit(1, 2); + + var results = db.Select(jn); + db.GetLastSql().Print(); + + results.PrintDump(); + + var fooBarJoin = results.FirstOrDefault(x => x.BarId == _bar1Id); + Assert.IsNull(fooBarJoin); + fooBarJoin = results.First(x => x.BarId == _bar2Id); + Assert.That(fooBarJoin.Id, Is.EqualTo(_foo2Id)); + fooBarJoin = results.First(x => x.BarId == _bar3Id); + Assert.That(fooBarJoin.Id, Is.EqualTo(_foo3Id)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/JoinWithHintUseCase.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/JoinWithHintUseCase.cs new file mode 100644 index 000000000..e088e05fe --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/JoinWithHintUseCase.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServer; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqlServerTests.UseCase +{ + [TestFixture] + public class JoinWithHintUseCase : OrmLiteTestBase + { + [Alias("car")] + class Car + { + + [PrimaryKey] + [Alias("car_id")] + [AutoIncrement] + public int CarId { get; set; } + + [Alias("car_name")] + public string Name { get; set; } + } + + [Alias("car_type")] + class CarType + { + [Alias("car_id")] + public int CarId { get; set; } + + [Alias("car_type_name")] + public string CarTypeName { get; set; } + } + + class CarTypeJoin + { + public int CarId { get; set; } + public string CarTypeName { get; set; } + } + + private static void InitTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + + var id1 = db.Insert(new Car { Name = "Subaru" }, true); + var id2 = db.Insert(new Car { Name = "BMW" }, true); + var id3 = db.Insert(new Car { Name = "Nissan" }, true); + + db.Insert(new CarType { CarId = (int)id1, CarTypeName = "Sedan" }); + db.Insert(new CarType { CarId = (int)id2, CarTypeName = "Coupe" }); + db.Insert(new CarType { CarId = (int)id3, CarTypeName = "SUV" }); + } + + [Test] + public void can_join_with_readuncommitted() + { + using (var db = OpenDbConnection()) + { + InitTables(db); + + var join = db.From() + .Join((l, r) => l.CarId == r.CarId, SqlServerTableHint.ReadUncommitted); + + var selectStatement = join.ToSelectStatement(); + selectStatement.Print(); + + var data = db.Select(join); + + Assert.That(selectStatement.Contains("READUNCOMMITTED")); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/SimpleUseCase.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/SimpleUseCase.cs new file mode 100644 index 000000000..c5a388c41 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/SimpleUseCase.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using NUnit.Framework; +using ServiceStack.OrmLite.SqlServer; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests.UseCase +{ + [TestFixture, NUnit.Framework.Ignore("")] + public class SimpleUseCase + { + [OneTimeSetUp] + public void TestFixtureSetUp() + { + //Inject your database provider here + OrmLiteConfig.DialectProvider = new SqlServerOrmLiteDialectProvider(); + } + + public class User + { + public long Id { get; set; } + + [Index] + public string Name { get; set; } + + public DateTime CreatedDate { get; set; } + + public bool IsAdmin { get; set; } + } + + public class Dual + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + } + + [Test] + public void Simple_CRUD_example() + { + //using (IDbConnection db = ":memory:".OpenDbConnection()) + + var connStr = ConfigurationManager.ConnectionStrings["TestDb"].ConnectionString; + var sqlServerFactory = new OrmLiteConnectionFactory(connStr, SqlServerOrmLiteDialectProvider.Instance); + + using (IDbConnection db = sqlServerFactory.OpenDbConnection()) + { + db.CreateTable(true); + db.CreateTable(true); + + db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now }); + db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); + db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now, IsAdmin = true}); + + db.Insert(new Dual { Name = "Dual" }); + var lastInsertId = db.LastInsertId(); + Assert.That(lastInsertId, Is.GreaterThan(0)); + + var rowsB = db.Select("Name = @name", new { name = "B" }); + + Assert.That(rowsB, Has.Count.EqualTo(2)); + + var admin = db.Select("IsAdmin = @isAdmin", new { isAdmin = true }); + Assert.That(admin[0].Id, Is.EqualTo(3)); + + var rowIds = rowsB.ConvertAll(x => x.Id); + Assert.That(rowIds, Is.EquivalentTo(new List { 2, 3 })); + + rowsB.ForEach(x => db.Delete(x)); + + rowsB = db.Select("Name = @name", new { name = "B" }); + Assert.That(rowsB, Has.Count.EqualTo(0)); + + var rowsLeft = db.Select(); + Assert.That(rowsLeft, Has.Count.EqualTo(1)); + + Assert.That(rowsLeft[0].Name, Is.EqualTo("A")); + } + } + + } + +} \ No newline at end of file diff --git a/src/ServiceStack.OrmLite.SqlServerTests/UseCase/TestEntity.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/TestEntity.cs similarity index 100% rename from src/ServiceStack.OrmLite.SqlServerTests/UseCase/TestEntity.cs rename to tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/TestEntity.cs diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/TestEntityWithAliases.cs b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/TestEntityWithAliases.cs new file mode 100644 index 000000000..fef850c19 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/UseCase/TestEntityWithAliases.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqlServerTests.UseCase +{ + public class TestEntityWithAliases + { + #region Properties + + [AutoIncrement] + [Alias("Id Column")] + public int Id { get; set; } + + [Alias("Foo Column")] + public String Foo { get; set; } + + [Alias("Bar Column °")] + public String Bar { get; set; } + + //[Index] + [Alias("Baz Column")] + public Decimal Baz { get; set; } + + #endregion + } +} diff --git a/tests/ServiceStack.OrmLite.SqlServer.Tests/app.config b/tests/ServiceStack.OrmLite.SqlServer.Tests/app.config new file mode 100644 index 000000000..d355ff5b9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqlServer.Tests/app.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/Properties/AssemblyInfo.cs b/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 0a3f820ff..000000000 --- a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.SqliteNet.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.SqliteNet.Tests")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("04b1dd87-d237-4998-bacd-75f9dd5d863d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/ServiceStack.OrmLite.Sqlite.Windows.Tests.csproj b/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/ServiceStack.OrmLite.Sqlite.Windows.Tests.csproj index 5fef32628..ff16c8a4b 100644 --- a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/ServiceStack.OrmLite.Sqlite.Windows.Tests.csproj +++ b/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/ServiceStack.OrmLite.Sqlite.Windows.Tests.csproj @@ -1,104 +1,17 @@ - - - + - Debug - AnyCPU - {701ABAE8-9B65-4D88-8CD6-C0FDD9D6BE08} - Library - Properties - ServiceStack.OrmLite.Sqlite.Windows.Tests - ServiceStack.OrmLite.Sqlite.Windows.Tests - v4.5 - 512 - ..\..\src\ - true - + net472 + ServiceStack.OrmLite.Sqlite.Windows.Testss + ServiceStack.OrmLite.Sqlite.Windows.Tests + default - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - ..\..\src\packages\NUnit.2.6.3\lib\nunit.framework.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - ..\..\src\packages\System.Data.SQLite.Core.1.0.94.0\lib\net45\System.Data.SQLite.dll - - - - - - - - - - OrmLiteTestBase.cs - - - UseCase\PasswordUseCase.cs - - - UseCase\SimpleUseCase.cs - - - - - - - {a5541444-70ee-4b5e-8a5f-c7d8a0048ebe} - ServiceStack.OrmLite.Sqlite.Windows - - - {96179ac6-f6f1-40c3-9fdd-4f6582f54c5c} - ServiceStack.OrmLite - - - + + + + + + - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/UseCase/NullableDateTimeOffset.cs b/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/UseCase/NullableDateTimeOffset.cs index b24fb2459..cda0aea69 100644 --- a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/UseCase/NullableDateTimeOffset.cs +++ b/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/UseCase/NullableDateTimeOffset.cs @@ -11,11 +11,11 @@ namespace ServiceStack.OrmLite.Tests.UseCase [TestFixture] public class NullableDateTimeOffset { - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { //Inject your database provider here - OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider(); + OrmLiteConfig.DialectProvider = new SqliteWindowsOrmLiteDialectProvider(); } public class Record @@ -31,7 +31,7 @@ public class Record [Test] public void Can_Insert_RecordWithNullable_DateTimeOffset() { - var path = Config.SqliteFileDb; + var path = SqliteDb.FileConnection; if (File.Exists(path)) File.Delete(path); @@ -48,7 +48,7 @@ public void Can_Insert_RecordWithNullable_DateTimeOffset() [Test] public void Can_Update_RecordWithNullable_DateTimeOffset() { - var path = Config.SqliteFileDb; + var path = SqliteDb.FileConnection; if (File.Exists(path)) File.Delete(path); @@ -70,7 +70,7 @@ public void Can_Update_RecordWithNullable_DateTimeOffset() [Test] public void Can_UpdateWithNull_RecordWithNullable_DateTimeOffset() { - var path = Config.SqliteFileDb; + var path = SqliteDb.FileConnection; if (File.Exists(path)) File.Delete(path); diff --git a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/packages.config b/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/packages.config deleted file mode 100644 index 48131b8af..000000000 --- a/tests/ServiceStack.OrmLite.Sqlite.Windows.Tests/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Sqlite64Tests/Properties/AssemblyInfo.cs b/tests/ServiceStack.OrmLite.Sqlite64Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 06b33efdb..000000000 --- a/tests/ServiceStack.OrmLite.Sqlite64Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.Sqlite64Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite64Tests")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a03645ee-363c-428c-b556-c009a536f817")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/ServiceStack.OrmLite.Sqlite64Tests/ServiceStack.OrmLite.Sqlite64Tests.csproj b/tests/ServiceStack.OrmLite.Sqlite64Tests/ServiceStack.OrmLite.Sqlite64Tests.csproj deleted file mode 100644 index 3c8a44b1d..000000000 --- a/tests/ServiceStack.OrmLite.Sqlite64Tests/ServiceStack.OrmLite.Sqlite64Tests.csproj +++ /dev/null @@ -1,89 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {1B97B329-8B70-4034-A2C9-35BF5DF428DC} - Library - Properties - ServiceStack.OrmLite.Tests - ServiceStack.OrmLite.Sqlite64Tests - v4.0 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x64 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x64 - - - bin\Signed\ - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset - - - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\tests\ServiceStack.Text.dll - - - - - - - - - - - - OrmLiteTestBase.cs - - - UseCase\SimpleUseCase.cs - - - - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqliteTests/App_Data/northwind.sqlite b/tests/ServiceStack.OrmLite.SqliteTests/App_Data/northwind.sqlite new file mode 100644 index 000000000..d94d87fe1 Binary files /dev/null and b/tests/ServiceStack.OrmLite.SqliteTests/App_Data/northwind.sqlite differ diff --git a/tests/ServiceStack.OrmLite.SqliteTests/Expressions/AuthorUseCase.cs b/tests/ServiceStack.OrmLite.SqliteTests/Expressions/AuthorUseCase.cs index 5f3ed6fa2..6a52bba87 100644 --- a/tests/ServiceStack.OrmLite.SqliteTests/Expressions/AuthorUseCase.cs +++ b/tests/ServiceStack.OrmLite.SqliteTests/Expressions/AuthorUseCase.cs @@ -52,7 +52,7 @@ public void AuthorUsesCases() ev.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); List result = db.Select(ev); Assert.AreEqual(expected, result.Count); - result = db.Select(qry => qry.Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); + result = db.Select(db.From().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); Assert.AreEqual(expected, result.Count); result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); Assert.AreEqual(expected, result.Count); @@ -154,14 +154,14 @@ public void AuthorUsesCases() expected = 2; var rate = 0; ev.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); - var rows = db.UpdateOnly(new Author() { Active = false }, ev); + var rows = db.UpdateOnlyFields(new Author() { Active = false }, ev); Assert.AreEqual(expected, rows); // insert values only in Id, Name, Birthday, Rate and Active fields expected = 4; ev.Insert(rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, ev); - db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, ev); + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); ev.Where().Where(rn => !rn.Active); result = db.Select(ev); Assert.AreEqual(expected, result.Count); @@ -169,7 +169,7 @@ public void AuthorUsesCases() //update comment for City == null expected = 2; ev.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); - rows = db.UpdateOnly(new Author() { Comments = "No comments" }, ev); + rows = db.UpdateOnlyFields(new Author() { Comments = "No comments" }, ev); Assert.AreEqual(expected, rows); // delete where City is null @@ -298,7 +298,7 @@ public void AuthorUsesCases() bool r6 = db.Scalar(e => Sql.Max(e.Active)); Assert.AreEqual(expectedBool, r6); } - catch (Exception e) + catch (Exception) { //???? //if (dialect.Name == "PostgreSQL") @@ -312,16 +312,6 @@ public void AuthorUsesCases() // Tests for predicate overloads that make use of the expression visitor author = db.Single(q => q.Name == "Jorge Garzon"); - try - { - author = db.Single(q => q.Name == "Does not exist"); - Assert.Fail(); - } - catch - { - //"Expected exception thrown, OK? True" - } - author = db.Single(q => q.Name == "Does not exist"); Assert.IsNull(author); @@ -351,17 +341,17 @@ public void AuthorUsesCases() rr.City = "Madrid"; rr.Comments = "Updated"; ev.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated - rows = db.UpdateOnly(rr, ev); // == dbCmd.Update(rr) but it returns void + rows = db.UpdateOnlyFields(rr, ev); // == dbCmd.Update(rr) but it returns void Assert.AreEqual(expected, rows); expected = 0; ev.Where().Where(r => r.City == "Ciudad Gotica"); - rows = db.UpdateOnly(rr, ev); + rows = db.UpdateOnlyFields(rr, ev); Assert.AreEqual(expected, rows); expected = db.Select(x => x.City == "Madrid").Count; author = new Author() { Active = false }; - rows = db.UpdateOnly(author, x => x.Active, x => x.City == "Madrid"); + rows = db.UpdateOnlyFields(author, x => x.Active, x => x.City == "Madrid"); Assert.AreEqual(expected, rows); expected = db.Select(x => x.Active == false).Count; diff --git a/tests/ServiceStack.OrmLite.SqliteTests/Issues/BooleanTests.cs b/tests/ServiceStack.OrmLite.SqliteTests/Issues/BooleanTests.cs new file mode 100644 index 000000000..d99ab1e1d --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqliteTests/Issues/BooleanTests.cs @@ -0,0 +1,70 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [Alias("users")] + public class User + { + [Alias("id"), PrimaryKey, Required, AutoIncrement] + public int Id { get; set; } + + [Alias("username")] + public string Username { get; set; } + + [Alias("password")] + public string Password { get; set; } + + [Alias("system_admin"), Required] + public bool IsSystemAdmin { get; set; } + + [Alias("system_user"), Required] + public bool IsSystemUser { get; set; } + + [Alias("is_admin"), Required] + public bool IsAdmin { get; set; } + + [Alias("notes")] + public string Notes { get; set; } + } + + public class BooleanTests + { + [Test] + public async Task Can_create_user_with_BOOLEAN_columns() + { + var factory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider); + using var db = await factory.OpenAsync(); + + db.ExecuteSql(@" +CREATE TABLE IF NOT EXISTS `users` ( +`id` INTEGER NOT NULL, +`username` VARCHAR, +`system_user` BOOLEAN, +`system_admin` BOOLEAN, +`is_admin` BOOLEAN, +`password` VARCHAR, +`notes` VARCHAR, +PRIMARY KEY(`id`) +);"); + + var row = new User { + Notes = "notes", + IsAdmin = true, + Username = "user", + Password = "pass" + }; + + await db.SaveAsync(row); + + var dbRow = await db.SingleByIdAsync(row.Id); + Assert.That(dbRow.Id, Is.EqualTo(row.Id)); + Assert.That(dbRow.Notes, Is.EqualTo(row.Notes)); + Assert.That(dbRow.IsAdmin, Is.EqualTo(row.IsAdmin)); + Assert.That(dbRow.Username, Is.EqualTo(row.Username)); + Assert.That(dbRow.Password, Is.EqualTo(row.Password)); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqliteTests/Issues/InsertTests.cs b/tests/ServiceStack.OrmLite.SqliteTests/Issues/InsertTests.cs new file mode 100644 index 000000000..1c641ff61 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqliteTests/Issues/InsertTests.cs @@ -0,0 +1,50 @@ +using System; +using System.Data; +using NUnit.Framework; +using ServiceStack.OrmLite.Converters; +using ServiceStack.OrmLite.Sqlite; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixture] + public class InsertTests + { + [OneTimeSetUp] + public void TestFixtureSetUp() + { + //OrmLiteConfig.UseParameterizeSqlExpressions = false; //Removed in OrmLite in future + OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider(); + DateTimeConverter dates = OrmLiteConfig.DialectProvider.GetDateTimeConverter(); + dates.DateStyle = DateTimeKind.Utc; + } + + public class User + { + public int Id { get; set; } + public DateTime Date { get; set; } + public string Value { get; set; } + public bool Bool { get; set; } + + } + + [Test] + public void InsertValues_values_via_insertonly() + { + using (IDbConnection db = ":memory:".OpenDbConnection()) + { + db.CreateTable(true); + + var utcDate = DateTime.UtcNow; + + db.InsertOnly(new User { Id = 1, Date = utcDate, Bool = true}, new string[0]); + db.InsertOnly(new User { Id = 2, Date = utcDate.AddDays(-1) }, new string[0]); + db.InsertOnly(new User { Id = 3, Date = utcDate.AddDays(-2) }, new string[0]); + db.Insert(new User { Id = 4, Date = utcDate.AddDays(1), Bool = true}); + + var actualCount = db.Count(u => u.Bool); + + Assert.That(actualCount, Is.EqualTo(2)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqliteTests/Issues/StringConverterGuidIssue.cs b/tests/ServiceStack.OrmLite.SqliteTests/Issues/StringConverterGuidIssue.cs new file mode 100644 index 000000000..ef6e76299 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqliteTests/Issues/StringConverterGuidIssue.cs @@ -0,0 +1,74 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class StringConverterGuidIssue : OrmLiteTestBase + { + [Alias("location")] + public class DbPoco + { + [Alias("poco_id"), PrimaryKey, AutoIncrement] + public int Id { get; set; } + + [Alias("poco_uuid")] + public Guid UniqueId { get; set; } = Guid.NewGuid(); + } + + /// + /// Example Dto with Guid as a string. + /// + public class Dto + { + public string Id { get; set; } + + // Fails when using ServiceStack.OrmLite.Sqlite / System.Data.SQLite.Core due to reader.GetValue() on Guid: + // https://forums.servicestack.net/t/ormlite-sqllite-stringconverter-behavior-change-5-4-5-6/ + // Passes when using ServiceStack.OrmLite.Sqlite.Data / Microsoft.Data.SQLite + public string UniqueId { get; set; } + } + + public class MySqliteStringConverter : StringConverter + { + public override object FromDbValue(Type fieldType, object value) + { + object result; + + if (value is byte[] byteValue) + { + var res = new Guid(byteValue).ToString(); + result = res; + } + else + { + result = base.FromDbValue(fieldType, value); + } + + return result; + } + } + + [Test] + public void Does_convert_Guid_with_Custom_String_Converter() + { + var dialectProvider = SqliteDialect.Provider; + dialectProvider.RegisterConverter(new MySqliteStringConverter()); + var dbFactory = new OrmLiteConnectionFactory(":memory:", dialectProvider); + + var uuid = Guid.NewGuid(); + using (var db = dbFactory.Open()) + { + db.CreateTable(false, typeof(DbPoco)); + db.Insert(new DbPoco { Id = 1, UniqueId = uuid }); + + var result = db.Single(db.From().Where(poco => poco.UniqueId == uuid)); + + Assert.That(result.UniqueId, Is.EqualTo(uuid.ToString())); +// Assert.That(result.UniqueId, Is.EqualTo(uuid)); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqliteTests/Issues/UtcDateTests.cs b/tests/ServiceStack.OrmLite.SqliteTests/Issues/UtcDateTests.cs new file mode 100644 index 000000000..ee9fa9af0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqliteTests/Issues/UtcDateTests.cs @@ -0,0 +1,194 @@ +using System; +using System.Data; +using NUnit.Framework; +using ServiceStack.OrmLite.Converters; +using ServiceStack.OrmLite.Sqlite; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + // also see ServiceStack.OrmLite.Tests.DateTimeTests, running that test against Sqlite should + // expose the same problem? + + // *************************************************************************** + // Failing Tests - 4.0.50 and 4.0.52 + + [TestFixture] + public class When_DateTimeConverter_DateStyle_is_Utc + { + [OneTimeSetUp] + public void TestFixtureSetUp() + { + OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider(); + DateTimeConverter dates = OrmLiteConfig.DialectProvider.GetDateTimeConverter(); + dates.DateStyle = DateTimeKind.Utc; + } + + public class User + { + public int Id { get; set; } + + public DateTime Date { get; set; } + } + + [Test] + public void Insert_and_select_utc_DateTime() + { + using (IDbConnection db = ":memory:".OpenDbConnection()) + { + db.CreateTable(true); + + var utcDate = DateTime.UtcNow; + + db.Insert(new User { Id = 1, Date = utcDate }); + + var actual = db.SingleById(1); + + Assert.AreEqual(actual.Date.Kind, DateTimeKind.Utc); // passes + Assert.AreEqual(actual.Date, utcDate); // fails + } + } + + [Test] + public void Insert_and_select_local_DateTime() + { + using (IDbConnection db = ":memory:".OpenDbConnection()) + { + db.CreateTable(true); + + var localDate = DateTime.Now; + + db.Insert(new User { Id = 2, Date = localDate }); + + var actual = db.SingleById(2); + var utcDate = localDate.ToUniversalTime(); + + Assert.AreEqual(actual.Date.Kind, DateTimeKind.Utc); // passes + Assert.AreEqual(actual.Date, utcDate); // fails + } + } + } + + // *************************************************************************** + // Failing Tests, but only if UseParameterizeSqlExpressions is false - 4.0.52 + + [TestFixture] + public class _DateTimeQueryTests + { + [OneTimeSetUp] + public void TestFixtureSetUp() + { + //OrmLiteConfig.UseParameterizeSqlExpressions = false; //Removed in OrmLite in future + OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider(); + DateTimeConverter dates = OrmLiteConfig.DialectProvider.GetDateTimeConverter(); + dates.DateStyle = DateTimeKind.Utc; + } + + public class User + { + public int Id { get; set; } + public DateTime Date { get; set; } + public string Value { get; set; } + } + + [Test] + public void Count_using_utc_DateTime_in_where_clause() + { + using (IDbConnection db = ":memory:".OpenDbConnection()) + { + db.CreateTable(true); + + var utcDate = DateTime.UtcNow; + + db.Insert(new User { Id = 1, Date = utcDate }); + db.Insert(new User { Id = 2, Date = utcDate.AddDays(-1) }); + db.Insert(new User { Id = 3, Date = utcDate.AddDays(-2) }); + db.Insert(new User { Id = 4, Date = utcDate.AddDays(1) }); + + var actualCount = db.Count(u => u.Date <= utcDate); + + Assert.That(actualCount, Is.EqualTo(3)); + } + } + + [Test] + public void Count_using_local_DateTime_in_where_clause() + { + using (IDbConnection db = ":memory:".OpenDbConnection()) + { + db.CreateTable(true); + + var localDate = DateTime.Now; + + db.Insert(new User { Id = 1, Date = localDate }); + db.Insert(new User { Id = 2, Date = localDate.AddDays(-1) }); + db.Insert(new User { Id = 3, Date = localDate.AddDays(-2) }); + db.Insert(new User { Id = 4, Date = localDate.AddDays(1) }); + + var utcDate = localDate.ToUniversalTime(); + var actualCount = db.Count(u => u.Date <= localDate); + + Assert.That(actualCount, Is.EqualTo(3)); + } + } + } + + // *************************************************************************** + // Passing Tests: 4.0.50 and 4.0.52 + + [TestFixture] + public class When_DateTimeConverter_DateStyle_is_default + { + [OneTimeSetUp] + public void TestFixtureSetUp() + { + OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider(); + DateTimeConverter dates = OrmLiteConfig.DialectProvider.GetDateTimeConverter(); + dates.DateStyle = DateTimeKind.Unspecified; // OR: + //dates.DateStyle = DateTimeKind.Local; + } + + public class User + { + public int Id { get; set; } + + public DateTime Date { get; set; } + } + + [Test] + public void Insert_and_select_utc_DateTime() + { + using (IDbConnection db = ":memory:".OpenDbConnection()) + { + db.CreateTable(true); + + var utcDate = DateTime.UtcNow; + var localDate = utcDate.ToLocalTime(); + + db.Insert(new User { Id = 1, Date = utcDate }); + + var actual = db.SingleById(1); + + Assert.That(actual.Date.Kind, Is.EqualTo(DateTimeKind.Local).Or.EqualTo(DateTimeKind.Unspecified)); + Assert.That(actual.Date, Is.EqualTo(localDate)); + } + } + + [Test] + public void Insert_and_select_local_DateTime() + { + using (IDbConnection db = ":memory:".OpenDbConnection()) + { + db.CreateTable(true); + + var localDate = DateTime.Now; + + db.Insert(new User { Id = 2, Date = localDate }); + + var actual = db.SingleById(2); + + Assert.That(actual.Date.Kind, Is.EqualTo(DateTimeKind.Local).Or.EqualTo(DateTimeKind.Unspecified)); + Assert.That(actual.Date, Is.EqualTo(localDate)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqliteTests/NorthwindTypes.cs b/tests/ServiceStack.OrmLite.SqliteTests/NorthwindTypes.cs new file mode 100644 index 000000000..7994712f5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqliteTests/NorthwindTypes.cs @@ -0,0 +1,137 @@ +using System; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.SqliteTests +{ + public class Category + { + public int Id { get; set; } + public string CategoryName { get; set; } + public string Description { get; set; } + } + + public class Customer + { + public string Id { get; set; } + public string CompanyName { get; set; } + public string ContactName { get; set; } + public string ContactTitle { get; set; } + public string Address { get; set; } + public string City { get; set; } + public string Region { get; set; } + public string PostalCode { get; set; } + public string Country { get; set; } + public string Phone { get; set; } + public string Fax { get; set; } + } + + public class Employee + { + public int Id { get; set; } + public string LastName { get; set; } + public string FirstName { get; set; } + public string Title { get; set; } + public string TitleOfCourtesy { get; set; } + public DateTime? BirthDate { get; set; } + public DateTime? HireDate { get; set; } + public string Address { get; set; } + public string City { get; set; } + public string Region { get; set; } + public string PostalCode { get; set; } + public string Country { get; set; } + public string HomePhone { get; set; } + public string Extension { get; set; } + public byte[] Photo { get; set; } + + [StringLength(StringLengthAttribute.MaxText)] + public string Notes { get; set; } + + public int? ReportsTo { get; set; } + public string PhotoPath { get; set; } + } + + public class EmployeeTerritory + { + public string Id => $"{EmployeeId}/{TerritoryId}"; + public int EmployeeId { get; set; } + public string TerritoryId { get; set; } + } + + public class Order + { + public int Id { get; set; } + public string CustomerId { get; set; } + public int EmployeeId { get; set; } + public DateTime? OrderDate { get; set; } + public DateTime? RequiredDate { get; set; } + public DateTime? ShippedDate { get; set; } + public int? ShipVia { get; set; } + public decimal Freight { get; set; } + public string ShipName { get; set; } + public string ShipAddress { get; set; } + public string ShipCity { get; set; } + public string ShipRegion { get; set; } + public string ShipPostalCode { get; set; } + public string ShipCountry { get; set; } + } + + public class OrderDetail + { + public string Id => $"{OrderId}/{ProductId}"; + public int OrderId { get; set; } + public int ProductId { get; set; } + public decimal UnitPrice { get; set; } + public short Quantity { get; set; } + public double Discount { get; set; } + } + + public class Product + { + public int Id { get; set; } + public string ProductName { get; set; } + public int SupplierId { get; set; } + public int CategoryId { get; set; } + public string QuantityPerUnit { get; set; } + public decimal UnitPrice { get; set; } + public short UnitsInStock { get; set; } + public short UnitsOnOrder { get; set; } + public short ReorderLevel { get; set; } + public bool Discontinued { get; set; } + } + + public class Region + { + public int Id { get; set; } + public string RegionDescription { get; set; } + } + + public class Shipper + { + public int Id { get; set; } + public string CompanyName { get; set; } + public string Phone { get; set; } + } + + public class Supplier + { + public int Id { get; set; } + public string CompanyName { get; set; } + public string ContactName { get; set; } + public string ContactTitle { get; set; } + public string Address { get; set; } + public string City { get; set; } + public string Region { get; set; } + public string PostalCode { get; set; } + public string Country { get; set; } + public string Phone { get; set; } + public string Fax { get; set; } + public string HomePage { get; set; } + } + + public class Territory + { + public string Id { get; set; } + public string TerritoryDescription { get; set; } + public int RegionId { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.SqliteTests/OrmLiteTestBase.cs b/tests/ServiceStack.OrmLite.SqliteTests/OrmLiteTestBase.cs index 750e4638e..bac31abcd 100644 --- a/tests/ServiceStack.OrmLite.SqliteTests/OrmLiteTestBase.cs +++ b/tests/ServiceStack.OrmLite.SqliteTests/OrmLiteTestBase.cs @@ -35,7 +35,7 @@ protected void CreateNewDatabase() ConnectionString = GetFileConnectionString(); } - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { LogManager.LogFactory = new ConsoleLogFactory(); diff --git a/tests/ServiceStack.OrmLite.SqliteTests/Properties/AssemblyInfo.cs b/tests/ServiceStack.OrmLite.SqliteTests/Properties/AssemblyInfo.cs deleted file mode 100644 index 1a30d1ac2..000000000 --- a/tests/ServiceStack.OrmLite.SqliteTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.Sqlite32Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.Sqlite32Tests")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b6a852ed-ff16-46f2-b05d-804d5f67e1e7")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/ServiceStack.OrmLite.SqliteTests/ServiceStack.OrmLite.SqliteTests.csproj b/tests/ServiceStack.OrmLite.SqliteTests/ServiceStack.OrmLite.SqliteTests.csproj index 7560f81da..71f3c183c 100644 --- a/tests/ServiceStack.OrmLite.SqliteTests/ServiceStack.OrmLite.SqliteTests.csproj +++ b/tests/ServiceStack.OrmLite.SqliteTests/ServiceStack.OrmLite.SqliteTests.csproj @@ -1,110 +1,27 @@ - - + + - Debug - AnyCPU - 8.0.30703 - 2.0 - {956FD518-A6CC-46B1-A93A-1C92779BF942} - Library - Properties - ServiceStack.OrmLite.Tests + net472;net6.0 + portable ServiceStack.OrmLite.SqliteTests - v4.0 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - - - bin\Signed\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset + ServiceStack.OrmLite.Sqlite32Tests + Library + ServiceStack.OrmLite.SqliteTests + win;win-x86;ubuntu.16.04-x64 + default + - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\tests\ServiceStack.Text.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {cf68a37d-d071-469d-ae04-68594cb95382} - ServiceStack.OrmLite.Sqlite - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - + + + + + + + - - sqlite3.dll - PreserveNewest - + - - - \ No newline at end of file + + diff --git a/tests/ServiceStack.OrmLite.SqliteTests/SqliteReadOnlyTests.cs b/tests/ServiceStack.OrmLite.SqliteTests/SqliteReadOnlyTests.cs new file mode 100644 index 000000000..8af184350 --- /dev/null +++ b/tests/ServiceStack.OrmLite.SqliteTests/SqliteReadOnlyTests.cs @@ -0,0 +1,42 @@ +using System; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.SqliteTests +{ + public class DisableWrites + { + public int Id { get; set; } + } + + class SqliteReadOnlyTests : OrmLiteTestBase + { + [Test] + public void Can_open_readonly_connection_to_file_database() + { + var dbPath = "~/App_Data/northwind.sqlite".MapProjectPlatformPath(); + var connectionString = $"Data Source={dbPath};Read Only=true"; + + connectionString.Print(); + var dbFactory = new OrmLiteConnectionFactory(connectionString, SqliteDialect.Provider); + + using (var db = dbFactory.OpenDbConnection()) + { + var count = db.Count(); + Assert.That(count, Is.GreaterThan(1)); + + try + { + db.DropAndCreateTable(); + Assert.Fail("should thow"); + } + catch (Exception ex) + { + Assert.That(ex.Message, Does.Contain("attempt to write a readonly database")); + } + } + } + + } +} diff --git a/tests/ServiceStack.OrmLite.SqliteTests/UseCase/PasswordUseCase.cs b/tests/ServiceStack.OrmLite.SqliteTests/UseCase/PasswordUseCase.cs index a25c0def9..903fb0d88 100644 --- a/tests/ServiceStack.OrmLite.SqliteTests/UseCase/PasswordUseCase.cs +++ b/tests/ServiceStack.OrmLite.SqliteTests/UseCase/PasswordUseCase.cs @@ -11,7 +11,7 @@ namespace ServiceStack.OrmLite.Tests.UseCase [TestFixture] public class PasswordUseCase { - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { //Inject your database provider here @@ -38,6 +38,9 @@ public class User2 } [Test] +#if NETCORE + [NUnit.Framework.Ignore("Microsoft.Data.Sqlite provider does not support `password` keyword")] +#endif public void Simple_CRUD_example() { var path = Config.SqliteFileDb; @@ -53,7 +56,7 @@ public void Simple_CRUD_example() db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - var rowsB = db.SelectFmt("Name = {0}", "B"); + var rowsB = db.Select("Name = @name", new { name = "B" }); var rowsB1 = db.Select(user => user.Name == "B"); Assert.That(rowsB, Has.Count.EqualTo(2)); @@ -64,7 +67,7 @@ public void Simple_CRUD_example() rowsB.ForEach(x => db.Delete(x)); - rowsB = db.SelectFmt("Name = {0}", "B"); + rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(0)); var rowsLeft = db.Select(); diff --git a/tests/ServiceStack.OrmLite.SqliteTests/UseCase/SimpleUseCase.cs b/tests/ServiceStack.OrmLite.SqliteTests/UseCase/SimpleUseCase.cs index 11a2f890f..552960024 100644 --- a/tests/ServiceStack.OrmLite.SqliteTests/UseCase/SimpleUseCase.cs +++ b/tests/ServiceStack.OrmLite.SqliteTests/UseCase/SimpleUseCase.cs @@ -11,7 +11,7 @@ namespace ServiceStack.OrmLite.Tests.UseCase [TestFixture] public class SimpleUseCase { - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { //Inject your database provider here @@ -53,7 +53,7 @@ public void Simple_CRUD_example() db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - var rowsB = db.SelectFmt("Name = {0}", "B"); + var rowsB = db.Select("Name = @name", new { name = "B" }); var rowsB1 = db.Select(user => user.Name == "B"); Assert.That(rowsB, Has.Count.EqualTo(2)); @@ -64,7 +64,7 @@ public void Simple_CRUD_example() rowsB.ForEach(x => db.Delete(x)); - rowsB = db.SelectFmt("Name = {0}", "B"); + rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(0)); var rowsLeft = db.Select(); diff --git a/tests/ServiceStack.OrmLite.Tests.Setup/Init.cs b/tests/ServiceStack.OrmLite.Tests.Setup/Init.cs new file mode 100644 index 000000000..bf8c517e0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Setup/Init.cs @@ -0,0 +1,14 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Setup +{ + public class Init + { + [Test] + public void Run_RDBMS_Setup_on_all_databases() + { + var dbFactory = TestConfig.InitDbFactory(); + TestConfig.InitDbScripts(dbFactory); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests.Setup/ServiceStack.OrmLite.Tests.Setup.csproj b/tests/ServiceStack.OrmLite.Tests.Setup/ServiceStack.OrmLite.Tests.Setup.csproj new file mode 100644 index 000000000..c95cb079a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Setup/ServiceStack.OrmLite.Tests.Setup.csproj @@ -0,0 +1,32 @@ + + + + net472;net6.0 + portable + ServiceStack.OrmLite.Tests.Setup + Library + ServiceStack.OrmLite.Tests.Setup + + false + + default + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ServiceStack.OrmLite.Tests.Setup/TestConfig.cs b/tests/ServiceStack.OrmLite.Tests.Setup/TestConfig.cs new file mode 100644 index 000000000..0fd4a7b10 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Setup/TestConfig.cs @@ -0,0 +1,463 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.Common; +using System.Data.SqlClient; +using System.IO; +using System.Linq; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public partial class TestConfig + { + /// + /// This value controls which providers are tested for all tests where dialects are not explicitly set + /// + public static Dialect Dialects = EnvironmentVariable("ORMLITE_DIALECT", Dialect.Sqlite); + } + + [Flags] + public enum Dialect + { + Sqlite = 1, + + SqlServer = 1 << 1, + SqlServer2012 = 1 << 2, + SqlServer2014 = 1 << 3, + SqlServer2016 = 1 << 4, + SqlServer2017 = 1 << 5, + SqlServer2019 = 1 << 6, + + PostgreSql9 = 1 << 8, + PostgreSql10 = 1 << 9, + PostgreSql11 = 1 << 10, + + MySql = 1 << 11, + MySqlConnector = 1 << 12, + + Oracle = 1 << 13, + + Firebird = 1 << 14, + Firebird4 = 1 << 15, + + // any versions + AnyPostgreSql = PostgreSql9 | PostgreSql10 | PostgreSql11, + AnyMySql = MySql | MySqlConnector, + AnySqlServer = SqlServer | SqlServer2012 | SqlServer2014 | SqlServer2016 | SqlServer2017 | SqlServer2019, + AnyOracle = Oracle, + + // db groups + BaseSupported = Sqlite | SqlServer | AnyPostgreSql | MySql | MySqlConnector, + Supported = Sqlite | AnySqlServer | AnyMySql | AnyPostgreSql, + Community = Firebird | Oracle, + + // all + All = Supported | Community + } + + public struct DialectContext + { + public Dialect Dialect; + public int Version; + public DialectContext(Dialect dialect, int version) + { + Dialect = dialect; + Version = version; + } + + public Tuple Tuple => System.Tuple.Create(Dialect, Version); + public static string Key(Tuple tuple) => Key(tuple.Item1, tuple.Item2); + public static string Key(Dialect dialect, int version) => dialect + "-" + version; + + public override string ToString() + { + var defaultLabel = Dialect + " " + Version; + switch (Dialect) + { + case Dialect.Sqlite: + return SqliteDb.VersionString(Version); + case Dialect.SqlServer: + case Dialect.SqlServer2012: + case Dialect.SqlServer2014: + case Dialect.SqlServer2016: + case Dialect.SqlServer2017: + case Dialect.SqlServer2019: + return SqlServerDb.VersionString(Dialect, Version); + case Dialect.MySql: + return MySqlDb.VersionString(Version); + case Dialect.PostgreSql9: + case Dialect.PostgreSql10: + case Dialect.PostgreSql11: + return PostgreSqlDb.VersionString(Version); + case Dialect.Oracle: + return OracleDb.VersionString(Version); + case Dialect.Firebird: + case Dialect.Firebird4: + return FirebirdDb.VersionString(Version); + } + + return defaultLabel; + } + + public OrmLiteConnectionFactory NamedConnection => OrmLiteConnectionFactory.NamedConnections[Key(Dialect, Version)]; + } + + public static class SqliteDb + { + public const int Memory = 1; + public const int File = 100; + public static int[] Versions => TestConfig.EnvironmentVariableInto("SQLITE_VERSION", new[]{ Memory }); + public static string DefaultConnection => MemoryConnection; + public static string MemoryConnection => TestConfig.DialectConnections[Tuple.Create(Dialect.Sqlite, Memory)]; + public static string FileConnection => TestConfig.DialectConnections[Tuple.Create(Dialect.Sqlite, File)]; + public static string VersionString(int version) => "SQLite " + (version == Memory + ? "Memory" + : version == File + ? "File" + : version.ToString()); + } + public static class SqlServerDb + { + public const int V2012 = 2012; + public const int V2014 = 2014; + public const int V2016 = 2016; + public const int V2017 = 2017; + public static int V2019 = 2019; + public static int[] Versions = TestConfig.EnvironmentVariableInto("MSSQL_VERSION", new[]{ V2012, V2014, V2016, V2017, V2019 }); + public static int[] V2012Versions = Versions.Where(x => x == V2012).ToArray(); + public static int[] V2014Versions = Versions.Where(x => x == V2014).ToArray(); + public static int[] V2016Versions = Versions.Where(x => x == V2016).ToArray(); + public static int[] V2017Versions = Versions.Where(x => x == V2017).ToArray(); + public static int[] V2019Versions = Versions.Where(x => x == V2019).ToArray(); + + public static string DefaultConnection => TestConfig.DialectConnections[Tuple.Create(Dialect.SqlServer2019, V2019)]; + + public static string VersionString(Dialect dialect, int version) => "SQL Server " + version; + + public static Dictionary CompatibilityLevels = new Dictionary + { + [Dialect.SqlServer2012] = 110, + [Dialect.SqlServer2014] = 120, + [Dialect.SqlServer2016] = 130, + [Dialect.SqlServer2017] = 140, + [Dialect.SqlServer2019] = 150, + }; + } + public static class MySqlDb + { + public const int V5_5 = 55; + public const int V10_1 = 101; + public const int V10_2 = 102; + public const int V10_3 = 103; + public const int V10_4 = 104; + public static readonly int[] Versions; + public static int[] MySqlConnectorVersions; + public static readonly string DefaultConnection; + + static MySqlDb() + { + try + { + Versions = TestConfig.EnvironmentVariableInto("MYSQL_VERSION", new[] { V5_5, V10_1, V10_2, V10_3, V10_4 }); + MySqlConnectorVersions = Versions.Where(x => x == V10_4).ToArray(); + DefaultConnection = TestConfig.DialectConnections[Tuple.Create(Dialect.MySql, V10_4)]; + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } + + public static string VersionString(int version) => "MySQL " + (version == V5_5 + ? "v5_5" + : version == V10_1 + ? "v10_1" + : version == V10_2 + ? "v10_2" + : version == V10_3 + ? "v10_3" + : version == V10_4 + ? "v10_4" + : version.ToString()); + + } + public static class PostgreSqlDb + { + public const int V9 = 9; + public const int V10 = 10; + public const int V11 = 11; + public static readonly int[] Versions = TestConfig.EnvironmentVariableInto("PGSQL_VERSION", new[]{ V9, V10, V11 }); + public static readonly string DefaultConnection = TestConfig.GetConnection(Dialect.PostgreSql11, V11); + public static int[] V9Versions = Versions.Where(x => x == V9).ToArray(); + public static int[] V10Versions = Versions.Where(x => x == V10).ToArray(); + public static int[] V11Versions = Versions.Where(x => x == V11).ToArray(); + + public static string VersionString(int version) => "PostgreSQL " + (version == V9 + ? "v9" + : version == V10 + ? "v10" + : version == V11 + ? "v11" + : version.ToString()); + } + public static class OracleDb + { + public const int V11 = 11; + public static readonly int[] Versions = TestConfig.EnvironmentVariableInto("ORACLE_VERSION", new[]{ V11 }); + public static readonly string DefaultConnection = TestConfig.GetConnection(Dialect.Oracle, V11); + public static string VersionString(int version) => "Oracle " + (version == V11 + ? "v11" + : version.ToString()); + } + public static class FirebirdDb + { + public const int V3 = 3; + public const int V4 = 4; + public static readonly int[] Versions = TestConfig.EnvironmentVariableInto("FIREBIRD_VERSION", new[]{ V3, V4 }); + public static readonly string DefaultConnection = TestConfig.GetConnection(Dialect.Firebird, V3); + public static readonly string V4Connection = TestConfig.GetConnection(Dialect.Firebird, V4); + public static string VersionString(int version) => "Firebird " + (version == V3 + ? "v3" + : version == V4 + ? "v4" + : version.ToString()); + } + + /// + /// Primary config for all tests + /// + public partial class TestConfig + { + public const bool EnableDebugLogging = false; + + public static Dictionary DialectProviders = new() + { + [Dialect.Sqlite] = SqliteDialect.Provider, + [Dialect.SqlServer] = SqlServerDialect.Provider, + [Dialect.SqlServer2012] = SqlServer2012Dialect.Provider, + [Dialect.SqlServer2014] = SqlServer2014Dialect.Provider, + [Dialect.SqlServer2016] = SqlServer2016Dialect.Provider, + [Dialect.SqlServer2017] = SqlServer2017Dialect.Provider, + [Dialect.SqlServer2019] = SqlServer2019Dialect.Provider, + [Dialect.PostgreSql9] = PostgreSqlDialect.Provider, + [Dialect.PostgreSql10] = PostgreSqlDialect.Provider, + [Dialect.PostgreSql11] = PostgreSqlDialect.Provider, + [Dialect.MySql] = MySqlDialect.Provider, + [Dialect.MySqlConnector] = MySqlConnectorDialect.Provider, + [Dialect.Oracle] = OracleDialect.Provider, + [Dialect.Firebird] = FirebirdDialect.Provider, + [Dialect.Firebird4] = Firebird4Dialect.Provider, + }; + + public static string GetConnection(Dialect dialect, int version) + { + if (DialectConnections.TryGetValue(Tuple.Create(dialect, version), out var connString)) + return connString; + + return null; + } + + private static Dictionary, string> dialectConnections; + public static Dictionary, string> DialectConnections => dialectConnections ??= LoadDialectConnections(); + + private static Dictionary, string> LoadDialectConnections() + { + try + { + return new Dictionary, string> + { + [Tuple.Create(Dialect.Sqlite, SqliteDb.Memory)] = EnvironmentVariable(new[]{ "SQLITE_MEMORY_CONNECTION", "SQLITE_CONNECTION" }, ":memory:"), + [Tuple.Create(Dialect.Sqlite, SqliteDb.File)] = EnvironmentVariable(new[]{ "SQLITE_FILE_CONNECTION", "SQLITE_CONNECTION" }, "~/App_Data/db.sqlite".MapAbsolutePath()), + + [Tuple.Create(Dialect.SqlServer, SqlServerDb.V2012)] = EnvironmentVariable(new[]{ "MSSQL2012_CONNECTION", "MSSQL_CONNECTION" }, "Data Source=tcp:localhost,48501\\SQLExpress;Initial Catalog=master;User Id=sa;Password=Test!tesT;Connect Timeout=120;MultipleActiveResultSets=True;"), + [Tuple.Create(Dialect.SqlServer2017, SqlServerDb.V2017)] = EnvironmentVariable(new[]{ "MSSQL2017_CONNECTION", "MSSQL_CONNECTION" }, "Data Source=tcp:localhost,48501\\SQLExpress;Initial Catalog=master;User Id=sa;Password=Test!tesT;Connect Timeout=120;MultipleActiveResultSets=True;"), + [Tuple.Create(Dialect.SqlServer2019, SqlServerDb.V2019)] = EnvironmentVariable(new[]{ "MSSQL2019_CONNECTION", "MSSQL_CONNECTION" }, "Data Source=tcp:localhost,48501\\SQLExpress;Initial Catalog=master;User Id=sa;Password=Test!tesT;Connect Timeout=120;MultipleActiveResultSets=True;"), + + [Tuple.Create(Dialect.PostgreSql9, PostgreSqlDb.V9)] = EnvironmentVariable(new[]{ "PGSQL9_CONNECTION", "PGSQL_CONNECTION" }, "Server=localhost;Port=48301;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"), + [Tuple.Create(Dialect.PostgreSql10, PostgreSqlDb.V10)] = EnvironmentVariable(new[]{ "PGSQL10_CONNECTION", "PGSQL_CONNECTION" }, "Server=localhost;Port=48302;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"), + [Tuple.Create(Dialect.PostgreSql11, PostgreSqlDb.V11)] = EnvironmentVariable(new[]{ "PGSQL11_CONNECTION", "PGSQL_CONNECTION" }, "Server=localhost;Port=48303;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"), + + [Tuple.Create(Dialect.MySql, MySqlDb.V5_5)] = EnvironmentVariable(new[]{ "MYSQL55_CONNECTION", "MYSQL_CONNECTION" }, "Server=localhost;Port=48201;Database=test;UID=root;Password=test;SslMode=none;Convert Zero Datetime=True;"), + [Tuple.Create(Dialect.MySql, MySqlDb.V10_1)] = EnvironmentVariable(new[]{ "MYSQL101_CONNECTION", "MYSQL_CONNECTION" }, "Server=localhost;Port=48202;Database=test;UID=root;Password=test;SslMode=none"), + [Tuple.Create(Dialect.MySql, MySqlDb.V10_2)] = EnvironmentVariable(new[]{ "MYSQL102_CONNECTION", "MYSQL_CONNECTION" }, "Server=localhost;Port=48203;Database=test;UID=root;Password=test;SslMode=none"), + [Tuple.Create(Dialect.MySql, MySqlDb.V10_3)] = EnvironmentVariable(new[]{ "MYSQL103_CONNECTION", "MYSQL_CONNECTION" }, "Server=localhost;Port=48204;Database=test;UID=root;Password=test;SslMode=none"), + [Tuple.Create(Dialect.MySql, MySqlDb.V10_4)] = EnvironmentVariable(new[]{ "MYSQL104_CONNECTION", "MYSQL_CONNECTION" }, "Server=localhost;Port=48205;Database=test;UID=root;Password=test;SslMode=none"), + + [Tuple.Create(Dialect.MySqlConnector, MySqlDb.V10_4)] = EnvironmentVariable(new[]{ "MYSQL104_CONNECTION", "MYSQL_CONNECTION" }, "Server=localhost;Port=48205;Database=test;UID=root;Password=test;SslMode=none"), + + [Tuple.Create(Dialect.Oracle, OracleDb.V11)] = EnvironmentVariable(new[]{ "ORACLE11_CONNECTION", "ORACLE_CONNECTION" }, "Data Source=tcp:localhost,48501\\SQLExpress;Initial Catalog=master;User Id=sa;Password=Test!tesT;Connect Timeout=120;MultipleActiveResultSets=True;"), + + [Tuple.Create(Dialect.Firebird, FirebirdDb.V3)] = EnvironmentVariable(new[]{ "FIREBIRD3_CONNECTION", "FIREBIRD_CONNECTION" }, @"User=SYSDBA;Password=masterkey;Database=/firebird/data/test.gdb;DataSource=localhost;Port=48101;Dialect=3;charset=ISO8859_1;MinPoolSize=0;MaxPoolSize=100;"), + + [Tuple.Create(Dialect.Firebird, FirebirdDb.V4)] = EnvironmentVariable(new[]{ "FIREBIRD4_CONNECTION", "FIREBIRD_CONNECTION" }, @"User=SYSDBA;Password=masterkey;Database=c:\ormlite-tests\firebird\test.fdb;DataSource=localhost;Dialect=3;charset=utf8;MinPoolSize=0;MaxPoolSize=100;"), + }; + } + catch (Exception e) + { + //Best place to Catch Exceptions is in NUnit.Framework.Internal.Builders.DefaultSideBuilder Line 115 + Console.WriteLine(e); + throw; + } + } + + public static Dictionary DialectVersions = new Dictionary + { + [Dialect.Sqlite] = SqliteDb.Versions, + [Dialect.SqlServer2012] = SqlServerDb.V2012Versions, + [Dialect.SqlServer2014] = SqlServerDb.V2014Versions, + [Dialect.SqlServer2016] = SqlServerDb.V2016Versions, + [Dialect.SqlServer2017] = SqlServerDb.V2017Versions, + [Dialect.SqlServer2019] = SqlServerDb.V2019Versions, + [Dialect.PostgreSql9] = PostgreSqlDb.V9Versions, + [Dialect.PostgreSql10] = PostgreSqlDb.V10Versions, + [Dialect.PostgreSql11] = PostgreSqlDb.V11Versions, + [Dialect.MySql] = MySqlDb.Versions, + [Dialect.MySqlConnector] = MySqlDb.MySqlConnectorVersions, + + [Dialect.Oracle] = OracleDb.Versions, + [Dialect.Firebird] = FirebirdDb.Versions, + }; + + public static IOrmLiteDialectProvider DefaultProvider = SqliteDialect.Provider; + public static string DefaultConnection = SqliteDb.DefaultConnection; + + public static string EnvironmentVariable(string[] variables, string defaultValue) => + variables.Map(Environment.GetEnvironmentVariable).FirstOrDefault(x => x != null) ?? defaultValue; + + public static T EnvironmentVariable(string variable, T defaultValue) + { + var value = Environment.GetEnvironmentVariable(variable); + return string.IsNullOrEmpty(value) ? defaultValue : Convert(value); + } + + public static T[] EnvironmentVariableInto(string variable, T[] defaultValues) + { + var value = Environment.GetEnvironmentVariable(variable); + return string.IsNullOrEmpty(value) ? defaultValues : value.FromJsv(); + } + + private static T Convert(string value) + { + var converter = TypeDescriptor.GetConverter(typeof(T)); + return (T)converter.ConvertFromInvariantString(value); + } + + public static OrmLiteConnectionFactory InitDbFactory() + { + // init DbFactory, should be mainly ignored in tests as they should always ask for a provider specific named connection + var dbFactory = new OrmLiteConnectionFactory(DefaultConnection, DefaultProvider); + + foreach (var dialectConnection in DialectConnections) + { + var dialect = dialectConnection.Key.Item1; + if (!DialectProviders.TryGetValue(dialect, out var dialectProvider)) + continue; + + dbFactory.RegisterConnection(DialectContext.Key(dialectConnection.Key), dialectConnection.Value, dialectProvider); + } + + foreach (var provider in DialectProviders) + { + dbFactory.RegisterDialectProvider(provider.Key.ToString(), provider.Value); + } + + return dbFactory; + } + + public static void InitDbScripts(OrmLiteConnectionFactory dbFactory) + { + if ((Dialects & Dialect.AnyPostgreSql) != 0) + { + void SetupPostgreSql(Dialect dialect, int version) + { + if ((Dialects & dialect) != 0) + { + if (DialectConnections.TryGetValue(Tuple.Create(dialect, version), out var connString)) + { + using (var db = dbFactory.OpenDbConnectionString(connString + ";Timeout=10", dialect.ToString())) + { + InitPostgres(dialect, db); + } + } + } + } + SetupPostgreSql(Dialect.PostgreSql9, PostgreSqlDb.V9); + SetupPostgreSql(Dialect.PostgreSql10, PostgreSqlDb.V10); + SetupPostgreSql(Dialect.PostgreSql11, PostgreSqlDb.V11); + } + + if ((Dialects & Dialect.MySqlConnector) != 0) + { + try + { + foreach (var version in DialectVersions[Dialect.MySqlConnector]) + { + using (var db = dbFactory.OpenDbConnectionString( + DialectConnections[Tuple.Create(Dialect.MySqlConnector, version)] + ";Timeout=10", + Dialect.MySqlConnector.ToString())) + { + InitMySqlConnector(Dialect.MySqlConnector, db); + } + } + } + catch {} + } + + if ((Dialects & Dialect.AnySqlServer) != 0) + { + void SetupSqlServer(Dialect dialect, int version) + { + if ((Dialects & dialect) != 0) + { + if (DialectConnections.TryGetValue(Tuple.Create(dialect, version), out var connString)) + { + using (var db = dbFactory.OpenDbConnectionString(connString + ";Timeout=10", dialect.ToString())) + { + InitSqlServer(dialect, db); + } + } + } + } + SetupSqlServer(Dialect.SqlServer2012, SqlServerDb.V2012); + SetupSqlServer(Dialect.SqlServer2014, SqlServerDb.V2014); + SetupSqlServer(Dialect.SqlServer2016, SqlServerDb.V2016); + SetupSqlServer(Dialect.SqlServer2017, SqlServerDb.V2017); + SetupSqlServer(Dialect.SqlServer2019, SqlServerDb.V2019); + } + } + + public static void InitPostgres(Dialect dialect, IDbConnection db) + { + db.ExecuteSql("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";"); + db.ExecuteSql("CREATE EXTENSION IF NOT EXISTS hstore"); + + var dialectProvider = db.GetDialectProvider(); + var schemaName = dialectProvider.NamingStrategy.GetSchemaName("Schema"); + db.ExecuteSql($"CREATE SCHEMA IF NOT EXISTS {dialectProvider.GetQuotedName(schemaName)}"); + } + + public static void InitMySqlConnector(Dialect dialect, IDbConnection db) + { + db.ExecuteSql("CREATE DATABASE IF NOT EXISTS `testMySql`"); + } + + public static void InitSqlServer(Dialect dialect, IDbConnection db) + { + // Create unique db per fixture to avoid conflicts when testing dialects + // uses COMPATIBILITY_LEVEL set to each version + + var dbName = dialect.ToString(); + var compatibilityLevel = SqlServerDb.CompatibilityLevels[dialect]; + var createSqlDb = $@"If(db_id(N'{dbName}') IS NULL) + BEGIN + CREATE DATABASE {dbName}; + ALTER DATABASE {dbName} SET COMPATIBILITY_LEVEL = {compatibilityLevel}; + END"; + db.ExecuteSql(createSqlDb); + } + + } +} diff --git a/tests/ServiceStack.OrmLite.Tests.Vb/Class1.vb b/tests/ServiceStack.OrmLite.Tests.Vb/Class1.vb new file mode 100644 index 000000000..b2b3244b2 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Vb/Class1.vb @@ -0,0 +1,31 @@ +Imports NUnit.Framework + +Public Class Table + Public Property Id As Integer + public Property IsActive As Boolean + public Property IsDeleted As Boolean +End Class + + _ +Public Class VbTests + + _ + Public Sub Test_and_Expression() + + OrmLiteUtils.PrintSql() + + Dim dbFactory as New OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider) + Using db As IDbConnection = dbFactory.Open() + + db.CreateTable(Of Table) + + Dim q = db.From(Of Table) _ + .Where(Function(t) t.IsDeleted = False And t.IsActive = False) + + Dim results = db.Select(q) + + End Using + + End Sub + +End Class \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests.Vb/My Project/Application.Designer.vb b/tests/ServiceStack.OrmLite.Tests.Vb/My Project/Application.Designer.vb new file mode 100644 index 000000000..88dd01c78 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Vb/My Project/Application.Designer.vb @@ -0,0 +1,13 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + diff --git a/tests/ServiceStack.OrmLite.Tests.Vb/My Project/Application.myapp b/tests/ServiceStack.OrmLite.Tests.Vb/My Project/Application.myapp new file mode 100644 index 000000000..758895def --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Vb/My Project/Application.myapp @@ -0,0 +1,10 @@ + + + false + false + 0 + true + 0 + 1 + true + diff --git a/tests/ServiceStack.OrmLite.Tests.Vb/My Project/AssemblyInfo.vb b/tests/ServiceStack.OrmLite.Tests.Vb/My Project/AssemblyInfo.vb new file mode 100644 index 000000000..7627d439a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Vb/My Project/AssemblyInfo.vb @@ -0,0 +1,35 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: +' + + + diff --git a/tests/ServiceStack.OrmLite.Tests.Vb/ServiceStack.OrmLite.Tests.Vb.vbproj b/tests/ServiceStack.OrmLite.Tests.Vb/ServiceStack.OrmLite.Tests.Vb.vbproj new file mode 100644 index 000000000..ebee3933a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Vb/ServiceStack.OrmLite.Tests.Vb.vbproj @@ -0,0 +1,156 @@ + + + + + + Debug + AnyCPU + {12BC7DB2-8802-42C2-92CF-912389241584} + Library + ServiceStack.OrmLite.Tests.Vb + ServiceStack.OrmLite.Tests.Vb + 512 + Windows + v4.7.2 + + + true + full + true + true + bin\Debug\ + ServiceStack.OrmLite.Tests.Vb.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + pdbonly + false + true + true + bin\Release\ + ServiceStack.OrmLite.Tests.Vb.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + On + + + Binary + + + Off + + + On + + + + + + ..\..\src\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll + True + + + ..\..\src\packages\ServiceStack.5.6.1\lib\net45\ServiceStack.dll + True + + + ..\..\src\packages\ServiceStack.Client.5.6.1\lib\net45\ServiceStack.Client.dll + True + + + ..\..\src\packages\ServiceStack.Common.5.6.1\lib\net45\ServiceStack.Common.dll + True + + + ..\..\src\packages\ServiceStack.Interfaces.5.6.1\lib\net45\ServiceStack.Interfaces.dll + True + + + ..\..\src\packages\ServiceStack.Text.5.6.1\lib\net45\ServiceStack.Text.dll + True + + + + ..\..\src\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + True + + + + + ..\..\src\packages\System.Data.SQLite.Core.1.0.111.0\lib\net46\System.Data.SQLite.dll + True + + + ..\..\src\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + True + + + + + ..\..\src\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + True + + + ..\..\src\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + True + + + + ..\..\src\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll + True + + + + + + + + + + + + + + + + + + + + + + + + + True + Application.myapp + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + + + + {cf68a37d-d071-469d-ae04-68594cb95382} + ServiceStack.OrmLite.Sqlite + + + {96179ac6-f6f1-40c3-9fdd-4f6582f54c5c} + ServiceStack.OrmLite + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests.Vb/packages.config b/tests/ServiceStack.OrmLite.Tests.Vb/packages.config new file mode 100644 index 000000000..d1eb4ac1e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests.Vb/packages.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/AdminTasks.cs b/tests/ServiceStack.OrmLite.Tests/AdminTasks.cs index 44ffaa733..4c31f6a75 100644 --- a/tests/ServiceStack.OrmLite.Tests/AdminTasks.cs +++ b/tests/ServiceStack.OrmLite.Tests/AdminTasks.cs @@ -1,12 +1,14 @@ -using NUnit.Framework; -using ServiceStack.OrmLite.Tests.UseCase; +using System; +using NUnit.Framework; namespace ServiceStack.OrmLite.Tests { - [Ignore, Explicit("OneOff Tasks")] - public class AdminTasks - : OrmLiteTestBase + [TestFixtureOrmLite, Explicit, Ignore("OneOff Tasks")] + [Obsolete("Would think this is redundant if spinning up clean dbs for each test run")] + public class AdminTasks : OrmLiteProvidersTestBase { + public AdminTasks(DialectContext context) : base(context) {} + [Test] public void Clean_Database() { diff --git a/tests/ServiceStack.OrmLite.Tests/AdoNetDataAccessTests.cs b/tests/ServiceStack.OrmLite.Tests/AdoNetDataAccessTests.cs index 98ed17a89..5319a2b7a 100644 --- a/tests/ServiceStack.OrmLite.Tests/AdoNetDataAccessTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/AdoNetDataAccessTests.cs @@ -5,18 +5,18 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture, Explicit] - public class AdoNetDataAccessTests - : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer), Ignore("Required DB with MigrateSqlServerTypes table")] + public class AdoNetDataAccessTests : OrmLiteProvidersTestBase { + public AdoNetDataAccessTests(DialectContext context) : base(context) {} /* CREATE TABLE [dbo].[MigrateSqlServerTypes]( - [Id] [int] IDENTITY(1,1) NOT NULL, - [SqlServerTime] [time](7) NULL, - [OrmLiteTimeSpan] [bigint] NULL, + [Id] [int] IDENTITY(1,1) NOT NULL, + [SqlServerTime] [time](7) NULL, + [OrmLiteTimeSpan] [bigint] NULL, ) - */ + */ public class MigrateSqlServerTypes { @@ -27,34 +27,30 @@ public class MigrateSqlServerTypes [Test] public void Can_read_from_existing_database() { - OrmLiteConfig.DialectProvider = SqlServerDialect.Provider; + using var db = OpenDbConnection(); + var map = new Dictionary(); - using (var db = Config.SqlServerBuildDb.OpenDbConnection()) + using (var dbCmd = db.CreateCommand()) { - var map = new Dictionary(); + dbCmd.CommandText = "SELECT * FROM MigrateSqlServerTypes"; - using (var dbCmd = db.CreateCommand()) + using (var reader = dbCmd.ExecuteReader()) { - dbCmd.CommandText = "SELECT * FROM MigrateSqlServerTypes"; - - using (var reader = dbCmd.ExecuteReader()) + while (reader.Read()) { - while (reader.Read()) - { - var id = reader.GetInt32(0); - var sqlTime = (TimeSpan)reader.GetValue(1); - map[id] = sqlTime; - } + var id = reader.GetInt32(0); + var sqlTime = (TimeSpan)reader.GetValue(1); + map[id] = sqlTime; } } + } - foreach (var entry in map) - { - db.Update(new MigrateSqlServerTypes { Id = entry.Key, OrmLiteTimeSpan = entry.Value }); - } - - db.Select().PrintDump(); + foreach (var entry in map) + { + db.Update(new MigrateSqlServerTypes { Id = entry.Key, OrmLiteTimeSpan = entry.Value }); } + + db.Select().PrintDump(); } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ApiSqlServerTests.cs b/tests/ServiceStack.OrmLite.Tests/ApiSqlServerTests.cs index 9878a6288..5d611be6b 100644 --- a/tests/ServiceStack.OrmLite.Tests/ApiSqlServerTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ApiSqlServerTests.cs @@ -1,69 +1,67 @@ using System.Collections.Generic; -using System.Data; using System.Linq; using NUnit.Framework; using ServiceStack.OrmLite.Tests.Shared; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - public class ApiSqlServerTests - : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class ApiSqlServerTests : OrmLiteProvidersTestBase { - private IDbConnection db; - - [SetUp] - public void SetUp() + public ApiSqlServerTests(DialectContext context) : base(context) {} + + [Test] + public void API_SqlServer_Examples() { - SuppressIfOracle("SQL Server tests"); - db = CreateSqlServerDbFactory().OpenDbConnection(); + using var db = OpenDbConnection(); db.DropAndCreateTable(); db.DropAndCreateTable(); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - [Test] - public void API_SqlServer_Examples() - { db.Insert(Person.Rockstars); db.Select(x => x.Age > 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); - db.Select(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)\nORDER BY \"Id\"")); - - db.Select(q => q.Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); + db.Select(db.From().Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); db.Select(db.From().Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); db.Single(x => x.Age == 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)")); - - db.Single(q => q.Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)")); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + } db.Single(db.From().Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)")); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + } db.Scalar(x => Sql.Max(x.Age)); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"")); db.Scalar(x => Sql.Max(x.Age), x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + db.Scalar(x => Sql.Count(x.Age), x => x.Id > 0); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(\"Age\") \nFROM \"Person\"\nWHERE (\"Id\" > @0)")); db.Count(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Count(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Select("Age > 40"); @@ -72,6 +70,9 @@ public void API_SqlServer_Examples() db.Select("SELECT * FROM Person WHERE Age > 40"); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + db.Select("SELECT * FROM Person WHERE Age > @age", new[] { db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + db.Select("Age > @age", new { age = 40 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); @@ -84,17 +85,11 @@ public void API_SqlServer_Examples() db.Select("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - db.SelectFmt("Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - db.SelectFmt("SELECT * FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - db.Select(typeof(Person)); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\"")); - db.SelectFmt(typeof(Person), "Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); + db.Select(typeof(Person), "Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > @age")); db.Where("Age", 27); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); @@ -103,7 +98,7 @@ public void API_SqlServer_Examples() Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); db.SelectByIds(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); db.SelectNonDefaults(new Person { Id = 1 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); @@ -114,12 +109,12 @@ public void API_SqlServer_Examples() db.SelectLazy().ToList(); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\"")); + db.SelectLazy(db.From().Where(x => x.Age > 40)).ToList(); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + db.SelectLazy("Age > @age", new { age = 40 }).ToList(); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - db.SelectLazyFmt("Age > {0}", 40).ToList(); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - db.WhereLazy(new { Age = 27 }).ToList(); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); @@ -132,8 +127,8 @@ public void API_SqlServer_Examples() db.Single("Age = @age", new { age = 42 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); - db.SingleFmt("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + db.Single("Age = @age", new[]{ db.CreateParam("age", 42)}); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); db.SingleById(1); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); @@ -141,58 +136,66 @@ public void API_SqlServer_Examples() db.SingleWhere("Age", 42); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - db.Scalar(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - db.Scalar(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); + db.Scalar(db.From().Where(q => q.Age > 40).Select(Sql.Count("*"))); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + db.Scalar(db.From().Where(q => q.Age > 40).Select(x => Sql.Count("*"))); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); - db.ScalarFmt("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); + db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new[] { db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); db.Column(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = 27)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); db.Column("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); - db.ColumnFmt("SELECT LastName FROM Person WHERE Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); + db.Column("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age", 27) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); db.ColumnDistinct(db.From().Select(x => x.Age).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.ColumnDistinct("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); - db.ColumnDistinctFmt("SELECT Age FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); + db.ColumnDistinct("SELECT Age FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); db.Lookup(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Lookup("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); - db.LookupFmt("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); - db.Dictionary(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Dictionary("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); - db.DictionaryFmt("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); - db.Exists(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + } db.Exists(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + } db.Exists(new { Age = 42 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); @@ -202,62 +205,60 @@ public void API_SqlServer_Examples() db.Exists("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); - db.ExistsFmt("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); - db.ExistsFmt("SELECT * FROM Person WHERE Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); - db.SqlList(db.From().Select("*").Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.SqlList("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + db.SqlList("SELECT * FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + db.SqlList("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); db.SqlColumn(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); db.SqlScalar(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); + db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); + var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); - db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); db.Insert(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, x => new { x.FirstName, x.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); - db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => db.From().Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); + db.InsertOnly(() => new PersonWithAutoId { FirstName = "Amy", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); @@ -273,36 +274,54 @@ public void API_SqlServer_Examples() db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=1, \"FirstName\"='JJ', \"LastName\"=NULL, \"Age\"=27 WHERE (\"LastName\" = 'Hendrix')")); + db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, where: x => x.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=@Id, \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE (\"LastName\" = @0)")); + + db.Update(new { FirstName = "JJ" }, where: x => x.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + db.UpdateNonDefaults(new Person { FirstName = "JJ" }, x => x.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + db.UpdateOnly(() => new Person { FirstName = "JJ" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, x => x.FirstName); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + db.UpdateOnlyFields(new Person { FirstName = "JJ", Age = 27 }, p => new { p.FirstName, p.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"Age\"=@Age")); - db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); + db.UpdateOnlyFields(new Person { FirstName = "JJ", Age = 27 }, new[] { "FirstName", "Age" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"Age\"=@Age")); - db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, x => x.FirstName, x => x.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); - db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); + db.UpdateOnly(() => new Person { FirstName = "JJ" }, x => x.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); - db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); + db.UpdateOnly(() => new Person { FirstName = "JJ" }, db.From().Where(p => p.LastName == "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); - db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, db.From().Update(x => x.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); - db.UpdateOnly(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"FirstName\" = 'Jimi')")); + db.UpdateAdd(() => new Person { Age = 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age")); - db.UpdateFmt(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + db.UpdateAdd(() => new Person { Age = 5 }, x => x.LastName == "Presley"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age WHERE (\"LastName\" = @0)")); - db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + db.UpdateAdd(() => new Person { Age = 5 }, db.From().Where(x => x.LastName == "Presley")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age WHERE (\"LastName\" = @0)")); db.Delete(new { FirstName = "Jimi", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + db.Delete(new Dictionary { ["FirstName"] = "Jimi", ["Age"] = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\"=@Id AND \"FirstName\"=@FirstName AND \"LastName\"=@LastName AND \"Age\"=@Age")); @@ -317,28 +336,19 @@ public void API_SqlServer_Examples() Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" = @0")); db.DeleteByIds(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); - - db.DeleteFmt("Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); - db.DeleteFmt(typeof(Person), "Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + db.Delete("Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); - db.Delete(p => p.Age == 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); + db.Delete(typeof(Person), "Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); - db.Delete(q => q.Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); + db.Delete(x => x.Age == 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); - db.Delete(db.From().Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - db.DeleteFmt(where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + db.Delete(db.From().Where(x => x.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); db.Save(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); @@ -351,6 +361,5 @@ public void API_SqlServer_Examples() db.SaveAll(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); } - } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ApiSqliteTests.cs b/tests/ServiceStack.OrmLite.Tests/ApiSqliteTests.cs index 0d10b0e8b..8586621c7 100644 --- a/tests/ServiceStack.OrmLite.Tests/ApiSqliteTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ApiSqliteTests.cs @@ -1,68 +1,53 @@ using System.Collections.Generic; -using System.Data; using System.Linq; using NUnit.Framework; using ServiceStack.OrmLite.Tests.Shared; namespace ServiceStack.OrmLite.Tests { - [Explicit] - public class ApiSqliteTests - : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.Sqlite)] + public class ApiSqliteTests : OrmLiteProvidersTestBase { - private IDbConnection db; - - [SetUp] - public void SetUp() + public ApiSqliteTests(DialectContext context) : base(context) {} + + [Test] + public void API_Sqlite_Examples() { - db = CreateSqliteMemoryDbFactory().OpenDbConnection(); + using var db = OpenDbConnection(); db.DropAndCreateTable(); db.DropAndCreateTable(); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - [Test] - public void API_Sqlite_Examples() - { db.Insert(Person.Rockstars); db.Select(x => x.Age > 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - db.Select(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)\nORDER BY \"Id\"")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); - db.Select(q => q.Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); + db.Select(db.From().Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); db.Select(db.From().Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); db.Single(x => x.Age == 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)\nLIMIT 1")); - - db.Single(q => q.Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)\nLIMIT 1")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)\nLIMIT 1")); db.Single(db.From().Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)\nLIMIT 1")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)\nLIMIT 1")); db.Scalar(x => Sql.Max(x.Age)); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"")); + db.Scalar(x => Sql.Count(x.Age), x => x.Id > 0); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(\"Age\") \nFROM \"Person\"\nWHERE (\"Id\" > @0)")); + db.Scalar(x => Sql.Max(x.Age), x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Count(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Count(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Select("Age > 40"); @@ -71,6 +56,9 @@ public void API_Sqlite_Examples() db.Select("SELECT * FROM Person WHERE Age > 40"); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + db.Select("SELECT * FROM Person WHERE Age > @age", new[]{ db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + db.Select("Age > @age", new { age = 40 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); @@ -83,17 +71,11 @@ public void API_Sqlite_Examples() db.Select("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - db.SelectFmt("Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - db.SelectFmt("SELECT * FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - db.Select(typeof(Person)); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\"")); - db.SelectFmt(typeof(Person), "Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); + db.Select(typeof(Person), "Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > @age")); db.Where("Age", 27); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); @@ -102,7 +84,7 @@ public void API_Sqlite_Examples() Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); db.SelectByIds(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); db.SelectNonDefaults(new Person { Id = 1 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); @@ -113,12 +95,12 @@ public void API_Sqlite_Examples() db.SelectLazy().ToList(); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\"")); + db.SelectLazy(db.From().Where(x => x.Age > 40)).ToList(); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + db.SelectLazy("Age > @age", new { age = 40 }).ToList(); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - db.SelectLazyFmt("Age > {0}", 40).ToList(); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - db.WhereLazy(new { Age = 27 }).ToList(); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); @@ -131,8 +113,8 @@ public void API_Sqlite_Examples() db.Single("Age = @age", new { age = 42 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); - db.SingleFmt("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + db.Single("Age = @age", new[] { db.CreateParam("age", 42) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); db.SingleById(1); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); @@ -140,64 +122,58 @@ public void API_Sqlite_Examples() db.SingleWhere("Age", 42); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - db.Scalar(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - db.Scalar(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); + db.Scalar(db.From().Where(q => q.Age > 40).Select(Sql.Count("*"))); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + db.Scalar(db.From().Where(q => q.Age > 40).Select(x => Sql.Count("*"))); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); - db.ScalarFmt("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); + db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new[] { db.CreateParam("age",40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); db.Column(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = 27)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); db.Column("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); - db.ColumnFmt("SELECT LastName FROM Person WHERE Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); + db.Column("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age",27) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); db.ColumnDistinct(db.From().Select(x => x.Age).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.ColumnDistinct("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); - db.ColumnDistinctFmt("SELECT Age FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); + db.ColumnDistinct("SELECT Age FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); db.Lookup(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Lookup("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); - db.LookupFmt("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); - db.Dictionary(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Dictionary(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Dictionary(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.Dictionary("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); - db.DictionaryFmt("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); - db.Exists(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)\nLIMIT 1")); db.Exists(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)\nLIMIT 1")); db.Exists(new { Age = 42 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); @@ -207,45 +183,45 @@ public void API_Sqlite_Examples() db.Exists("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); - db.ExistsFmt("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); - db.ExistsFmt("SELECT * FROM Person WHERE Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); - db.SqlList(db.From().Select("*").Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.SqlList("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + db.SqlList("SELECT * FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + db.SqlList("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); db.SqlColumn(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); db.SqlScalar(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); + db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); + var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); - db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); @@ -254,15 +230,14 @@ public void API_Sqlite_Examples() Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => ev.Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); - db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => db.From().Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); + db.InsertOnly(() => new PersonWithAutoId { FirstName = "Amy", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); @@ -278,36 +253,54 @@ public void API_Sqlite_Examples() db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=1, \"FirstName\"='JJ', \"LastName\"=NULL, \"Age\"=27 WHERE (\"LastName\" = 'Hendrix')")); + db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, where: p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=@Id, \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE (\"LastName\" = @0)")); - db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); + db.Update(new { FirstName = "JJ" }, where: p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + db.UpdateOnly(() => new Person { FirstName = "JJ" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + db.UpdateOnlyFields(new Person { FirstName = "JJ", Age = 27 }, p => new { p.FirstName, p.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"Age\"=@Age")); + + db.UpdateOnlyFields(new Person { FirstName = "JJ", Age = 27 }, new[] { "FirstName", "Age" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"Age\"=@Age")); - db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); - db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); + db.UpdateOnly(() => new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); - db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); + db.UpdateOnly(() => new Person { FirstName = "JJ" }, db.From().Where(p => p.LastName == "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); - db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"FirstName\" = 'Jimi')")); + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); - db.UpdateFmt(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + db.UpdateAdd(() => new Person { Age = 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age")); - db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + db.UpdateAdd(() => new Person { Age = 5 }, where: x => x.LastName == "Presley"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age WHERE (\"LastName\" = @0)")); + + db.UpdateAdd(() => new Person { Age = 5 }, db.From().Where(x => x.LastName == "Presley")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age WHERE (\"LastName\" = @0)")); db.Delete(new { FirstName = "Jimi", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + db.Delete(new Dictionary { ["FirstName"] = "Jimi", ["Age"] = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\"=@Id AND \"FirstName\"=@FirstName AND \"LastName\"=@LastName AND \"Age\"=@Age")); @@ -322,28 +315,22 @@ public void API_Sqlite_Examples() Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" = @0")); db.DeleteByIds(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); - db.DeleteFmt("Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + db.Delete("Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); - db.DeleteFmt(typeof(Person), "Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + db.Delete(typeof(Person), "Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); db.Delete(p => p.Age == 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - db.Delete(ev => ev.Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); db.Delete(db.From().Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - db.DeleteFmt(where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); - db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + db.Delete(db.From().Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); db.Save(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); diff --git a/tests/ServiceStack.OrmLite.Tests/Async/ApiMySqlTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/ApiMySqlTestsAsync.cs new file mode 100644 index 000000000..32b0b2c7f --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/ApiMySqlTestsAsync.cs @@ -0,0 +1,320 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLiteDialects(Dialect.AnyMySql)] + public class ApiMySqlTestsAsync : OrmLiteProvidersTestBase + { + public ApiMySqlTestsAsync(DialectContext context) : base(context) {} + + [Test] + public async Task API_MySql_Examples_Async() + { + var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + await db.InsertAsync(Person.Rockstars); + + await db.SelectAsync(x => x.Age > 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > @0)")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > @0)\nORDER BY `Id`")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > @0)")); + + await db.SingleAsync(x => x.Age == 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` = @0)\nLIMIT 1")); + + await db.SingleAsync(db.From().Where(x => x.Age == 42)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` = @0)\nLIMIT 1")); + + await db.ScalarAsync(x => Sql.Max(x.Age)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(`Age`) \nFROM `Person`")); + + await db.ScalarAsync(x => Sql.Max(x.Age), x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(`Age`) \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.CountAsync(x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.CountAsync(db.From().Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < @0)")); + + + await db.SelectAsync("Age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > 40")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + await db.SelectAsync("Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @age")); + + await db.SelectAsync("Age > @age", new[] { db.CreateParam("age",40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync("Age > @age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync(typeof(Person)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id` FROM `Person`")); + + await db.SelectAsync(typeof(Person), "Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id` FROM `Person` WHERE Age > @age")); + + await db.WhereAsync("Age", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); + + await db.WhereAsync(new { Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); + + await db.SelectByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` IN (@0,@1,@2)")); + + await db.SelectNonDefaultsAsync(new Person { Id = 1 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` = @Id")); + + await db.SelectNonDefaultsAsync("Age > @Age", new Person { Age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @Age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` = @Id")); + + await db.SingleAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); + + await db.SingleAsync("Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = @age")); + + await db.SingleAsync("Age = @age", new[] { db.CreateParam("age",42) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = @age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` = @Id")); + + await db.SingleWhereAsync("Age", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); + + await db.ScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` > @0)")); + await db.ScalarAsync(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM `Person`\nWHERE (`Age` > @0)")); + + await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); + + await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new[] { db.CreateParam("age",40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); + + await db.ColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `LastName` \nFROM `Person`\nWHERE (`Age` = @0)")); + + await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); + + await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age",27) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); + + await db.ColumnDistinctAsync(db.From().Select(x => x.Age).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Age` \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); + + await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); + + await db.LookupAsync(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Age`, `LastName` \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); + + await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); + + await db.DictionaryAsync(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `LastName` \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); + + await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); + + await db.ExistsAsync(x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM `Person`\nWHERE (`Age` < @0)\nLIMIT 1")); + + await db.ExistsAsync(db.From().Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM `Person`\nWHERE (`Age` < @0)\nLIMIT 1")); + + await db.ExistsAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); + + await db.ExistsAsync("Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = @age")); + await db.ExistsAsync("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); + + await db.SqlListAsync(db.From().Select("*").Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `LastName` \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < @0)")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); + + await db.InsertAsync(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); + + await db.InsertAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); + + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); + + + await db.InsertAllAsync(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `PersonWithAutoId` (`FirstName`,`Age`) VALUES (@FirstName,@Age)")); + + await db.InsertOnlyAsync(() => new PersonWithAutoId { FirstName = "Amy", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `PersonWithAutoId` (`FirstName`,`Age`) VALUES (@FirstName,@Age)")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); + + await db.UpdateAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur3", Age = 27 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur4", Age = 28 }); + + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); + + await db.UpdateAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); + + await db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `Id`=@Id, `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE (`LastName` = @0)")); + + await db.UpdateAsync(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName WHERE (`LastName` = @0)")); + + await db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName WHERE (`LastName` = @0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName WHERE (`LastName` = @0)")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName WHERE (`LastName` = @0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From().Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName WHERE (`FirstName` = @0)")); + + await db.UpdateAddAsync(() => new Person { Age = 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `Age`=`Age`+@Age")); + + await db.UpdateAddAsync(() => new Person { Age = 5 }, where: x => x.LastName == "Presley"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `Age`=`Age`+@Age WHERE (`LastName` = @0)")); + + await db.DeleteAsync(new { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `FirstName`=@FirstName AND `Age`=@Age")); + + await db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `Id`=@Id AND `FirstName`=@FirstName AND `LastName`=@LastName AND `Age`=@Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `FirstName`=@FirstName AND `Age`=@Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, + new Person { FirstName = "Janis", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `FirstName`=@FirstName AND `Age`=@Age")); + + await db.DeleteByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `Id` = @0")); + + await db.DeleteByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `Id` IN (@0,@1,@2)")); + + await db.DeleteAsync("Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = @age")); + + await db.DeleteAsync(typeof(Person), "Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = @age")); + + await db.DeleteAsync(p => p.Age == 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE (`Age` = @0)")); + + await db.DeleteAsync(db.From().Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE (`Age` = @0)")); + + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); + + await db.SaveAsync(new Person { Id = 12, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 13, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + + await db.SaveAllAsync(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); + + db.Dispose(); + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Async/ApiPostgreSqlTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/ApiPostgreSqlTestsAsync.cs new file mode 100644 index 000000000..162440806 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/ApiPostgreSqlTestsAsync.cs @@ -0,0 +1,319 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class ApiPostgreSqlTestsAsync : OrmLiteProvidersTestBase + { + public ApiPostgreSqlTestsAsync(DialectContext context) : base(context) {} + + [Test] + public async Task API_PostgreSql_Examples_Async() + { + var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + await db.InsertAsync(Person.Rockstars); + + await db.SelectAsync(x => x.Age > 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" > :0)")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" > :0)\nORDER BY \"id\"")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" > :0)")); + + await db.SingleAsync(x => x.Age == 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" = :0)\nLIMIT 1")); + + await db.SingleAsync(db.From().Where(x => x.Age == 42)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" = :0)\nLIMIT 1")); + + await db.ScalarAsync(x => Sql.Max(x.Age)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"age\") \nFROM \"person\"")); + + await db.ScalarAsync(x => Sql.Max(x.Age), x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"age\") \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.CountAsync(x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.CountAsync(db.From().Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.SelectAsync("age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age > 40")); + + await db.SelectAsync("SELECT * FROM person WHERE age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age > 40")); + + await db.SelectAsync("age > :Age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age > :Age")); + + await db.SelectAsync("SELECT * FROM person WHERE age > :Age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age > :Age")); + + await db.SelectAsync("SELECT * FROM person WHERE age > :Age", new[] { db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age > :Age")); + + await db.SelectAsync("age > :Age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age > :Age")); + + await db.SelectAsync("SELECT * FROM person WHERE age > :Age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age > :Age")); + + await db.SelectAsync(typeof(Person)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\" FROM \"person\"")); + + await db.SelectAsync(typeof(Person), "age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\" FROM \"person\" WHERE age > @age")); + + await db.WhereAsync("Age", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"age\" = :Age")); + + await db.WhereAsync(new { Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"age\" = :Age")); + + await db.SelectByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"id\" IN (:0,:1,:2)")); + + await db.SelectNonDefaultsAsync(new Person { Id = 1 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"id\" = :Id")); + + await db.SelectNonDefaultsAsync("age > :Age", new Person { Age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age > :Age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"id\" = :Id")); + + await db.SingleAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"age\" = :Age")); + + await db.SingleAsync("age = :Age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age = :Age")); + + await db.SingleAsync("age = :Age", new[] { db.CreateParam("age", 42) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age = :Age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"id\" = :Id")); + + await db.SingleWhereAsync("Age", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"age\" = :Age")); + + await db.ScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"person\"\nWHERE (\"age\" > :0)")); + await db.ScalarAsync(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"person\"\nWHERE (\"age\" > :0)")); + + await db.ScalarAsync("SELECT COUNT(*) FROM person WHERE age > :Age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM person WHERE age > :Age")); + + await db.ScalarAsync("SELECT COUNT(*) FROM person WHERE age > :Age", new[] { db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM person WHERE age > :Age")); + + await db.ColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"last_name\" \nFROM \"person\"\nWHERE (\"age\" = :0)")); + + await db.ColumnAsync("SELECT last_name FROM person WHERE age = :Age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT last_name FROM person WHERE age = :Age")); + + await db.ColumnAsync("SELECT last_name FROM person WHERE age = :Age", new[] { db.CreateParam("age", 27) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT last_name FROM person WHERE age = :Age")); + + await db.ColumnDistinctAsync(db.From().Select(x => x.Age).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"age\" \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.ColumnDistinctAsync("SELECT age FROM person WHERE age < :Age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT age FROM person WHERE age < :Age")); + + await db.ColumnDistinctAsync("SELECT age FROM person WHERE age < :Age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT age FROM person WHERE age < :Age")); + + await db.LookupAsync(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"age\", \"last_name\" \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.LookupAsync("SELECT age, last_name FROM person WHERE age < :Age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT age, last_name FROM person WHERE age < :Age")); + + await db.LookupAsync("SELECT age, last_name FROM person WHERE age < :Age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT age, last_name FROM person WHERE age < :Age")); + + await db.DictionaryAsync(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"last_name\" \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.DictionaryAsync("SELECT id, last_name FROM person WHERE age < :Age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT id, last_name FROM person WHERE age < :Age")); + + await db.DictionaryAsync("SELECT id, last_name FROM person WHERE age < :Age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT id, last_name FROM person WHERE age < :Age")); + + await db.ExistsAsync(x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"person\"\nWHERE (\"age\" < :0)\nLIMIT 1")); + + await db.ExistsAsync(db.From().Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"person\"\nWHERE (\"age\" < :0)\nLIMIT 1")); + + await db.ExistsAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE \"age\" = :Age")); + + await db.ExistsAsync("age = :Age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age = :Age")); + await db.ExistsAsync("SELECT * FROM person WHERE age = :Age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age = :Age")); + + await db.SqlListAsync(db.From().Select("*").Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.SqlListAsync("SELECT * FROM person WHERE age < :Age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age < :Age")); + + await db.SqlListAsync("SELECT * FROM person WHERE age < :Age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age < :Age")); + + await db.SqlListAsync("SELECT * FROM person WHERE age < :Age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age < :Age")); + + await db.SqlColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"last_name\" \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.SqlColumnAsync("SELECT last_name FROM person WHERE age < :Age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT last_name FROM person WHERE age < :Age")); + + await db.SqlColumnAsync("SELECT last_name FROM person WHERE age < :Age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT last_name FROM person WHERE age < :Age")); + + await db.SqlColumnAsync("SELECT last_name FROM person WHERE age < :Age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT last_name FROM person WHERE age < :Age")); + + await db.SqlScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"person\"\nWHERE (\"age\" < :0)")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM person WHERE age < :Age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM person WHERE age < :Age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM person WHERE age < :Age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM person WHERE age < :Age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM person WHERE age < :Age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM person WHERE age < :Age")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET last_name=@name WHERE id=:Id", new { name = "WaterHouse", id = 7 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET last_name=@name WHERE id=:Id")); + + + await db.InsertAsync(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person\" (\"id\",\"first_name\",\"last_name\",\"age\") VALUES (:Id,:FirstName,:LastName,:Age)")); + + await db.InsertAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); + + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person\" (\"id\",\"first_name\",\"last_name\",\"age\") VALUES (:Id,:FirstName,:LastName,:Age)")); + + + await db.InsertAllAsync(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person\" (\"id\",\"first_name\",\"last_name\",\"age\") VALUES (:Id,:FirstName,:LastName,:Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person_with_auto_id\" (\"first_name\",\"age\") VALUES (:FirstName,:Age)")); + + await db.InsertOnlyAsync(() => new PersonWithAutoId { FirstName = "Amy", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person_with_auto_id\" (\"first_name\",\"age\") VALUES (:FirstName,:Age)")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName, \"last_name\"=:LastName, \"age\"=:Age WHERE \"id\"=:Id")); + + await db.UpdateAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur3", Age = 27 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur4", Age = 28 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName, \"last_name\"=:LastName, \"age\"=:Age WHERE \"id\"=:Id")); + + await db.UpdateAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName, \"last_name\"=:LastName, \"age\"=:Age WHERE \"id\"=:Id")); + + await db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName, \"last_name\"=:LastName, \"age\"=:Age WHERE \"id\"=:Id")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"id\"=:Id, \"first_name\"=:FirstName, \"last_name\"=:LastName, \"age\"=:Age WHERE (\"last_name\" = :0)")); + + await db.UpdateAsync(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName WHERE (\"last_name\" = :0)")); + + await db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName WHERE (\"last_name\" = :0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName WHERE (\"last_name\" = :0)")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName WHERE (\"last_name\" = :0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From().Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName WHERE (\"first_name\" = :0)")); + + await db.UpdateAddAsync(() => new Person { Age = 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"age\"=\"age\"+:Age")); + + await db.UpdateAddAsync(() => new Person { Age = 5 }, where: x => x.LastName == "Presley"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"age\"=\"age\"+:Age WHERE (\"last_name\" = :0)")); + + await db.DeleteAsync(new { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE \"first_name\"=:FirstName AND \"age\"=:Age")); + + await db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE \"id\"=:Id AND \"first_name\"=:FirstName AND \"last_name\"=:LastName AND \"age\"=:Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE \"first_name\"=:FirstName AND \"age\"=:Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, + new Person { FirstName = "Janis", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE \"first_name\"=:FirstName AND \"age\"=:Age")); + + await db.DeleteByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE \"id\" = :0")); + + await db.DeleteByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE \"id\" IN (:0,:1,:2)")); + + await db.DeleteAsync("age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE age = @age")); + + await db.DeleteAsync(typeof(Person), "age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE age = @age")); + + await db.DeleteAsync(p => p.Age == 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE (\"age\" = :0)")); + + await db.DeleteAsync(db.From().Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE (\"age\" = :0)")); + + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person\" (\"id\",\"first_name\",\"last_name\",\"age\") VALUES (:Id,:FirstName,:LastName,:Age)")); + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName, \"last_name\"=:LastName, \"age\"=:Age WHERE \"id\"=:Id")); + + await db.SaveAsync(new Person { Id = 12, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 13, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + + await db.SaveAllAsync(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); + + db.Dispose(); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/ApiSqlServerTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/ApiSqlServerTestsAsync.cs new file mode 100644 index 000000000..229100a34 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/ApiSqlServerTestsAsync.cs @@ -0,0 +1,368 @@ +using System.Collections.Generic; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class ApiSqlServerTestsAsync : OrmLiteProvidersTestBase + { + public ApiSqlServerTestsAsync(DialectContext context) : base(context) {} + + private IDbConnection db; + + [SetUp] + public void SetUp() + { + db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + } + + [TearDown] + public void TearDown() + { + db.Dispose(); + } + + [Test] + public async Task API_SqlServer_Examples_Async() + { + await db.InsertAsync(Person.Rockstars); + + await db.SelectAsync(x => x.Age > 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.SingleAsync(x => x.Age == 42); + + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + } + + await db.SingleAsync(db.From().Where(x => x.Age == 42)); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + } + + await db.ScalarAsync(x => Sql.Max(x.Age)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"")); + + await db.ScalarAsync(x => Sql.Max(x.Age), x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.CountAsync(x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.CountAsync(db.From().Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + + await db.SelectAsync("Age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + await db.SelectAsync("Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new[] { db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync("Age > @age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync(typeof(Person)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\"")); + + await db.SelectAsync(typeof(Person), "Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > @age")); + + await db.WhereAsync("Age", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.WhereAsync(new { Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.SelectByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); + + await db.SelectNonDefaultsAsync(new Person { Id = 1 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); + + await db.SelectNonDefaultsAsync("Age > @Age", new Person { Age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @Age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); + + await db.SingleAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.SingleAsync("Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); + + await db.SingleAsync("Age = @age", new[] { db.CreateParam("age", 42) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); + + await db.SingleWhereAsync("Age", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.ScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + await db.ScalarAsync(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); + + await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new[] { db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); + + await db.ColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + + await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); + + await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age", 27) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); + + await db.ColumnDistinctAsync(db.From().Select(x => x.Age).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); + + await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); + + await db.LookupAsync(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); + + await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); + + await db.DictionaryAsync(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); + + await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); + + await db.ExistsAsync(x => x.Age < 50); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + } + + await db.ExistsAsync(db.From().Where(x => x.Age < 50)); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + } + + await db.ExistsAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.ExistsAsync("Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); + await db.ExistsAsync("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); + + await db.SqlListAsync(db.From().Select("*").Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new[] { db.CreateParam("age", 50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); + + + await db.InsertAsync(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + + await db.InsertAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); + + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + + + await db.InsertAllAsync(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.InsertOnlyAsync(() => new PersonWithAutoId { FirstName = "Amy", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur3", Age = 27 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur4", Age = 28 }); + + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=@Id, \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE (\"LastName\" = @0)")); + + await db.UpdateAsync(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From().Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); + + await db.UpdateAddAsync(() => new Person { Age = 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age")); + + await db.UpdateAddAsync(() => new Person { Age = 5 }, where: x => x.LastName == "Presley"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age WHERE (\"LastName\" = @0)")); + + await db.UpdateAddAsync(() => new Person { Age = 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age")); + + await db.UpdateAddAsync(() => new Person { Age = 5 }, where: x => x.LastName == "Presley"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age WHERE (\"LastName\" = @0)")); + + await db.DeleteAsync(new { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + + await db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\"=@Id AND \"FirstName\"=@FirstName AND \"LastName\"=@LastName AND \"Age\"=@Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, + new Person { FirstName = "Janis", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + + await db.DeleteByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" = @0")); + + await db.DeleteByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); + + await db.DeleteAsync("Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); + + await db.DeleteAsync(typeof(Person), "Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); + + await db.DeleteAsync(p => p.Age == 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + await db.DeleteAsync(db.From().Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.SaveAsync(new Person { Id = 12, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 13, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + + await db.SaveAllAsync(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/ApiSqliteTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/ApiSqliteTestsAsync.cs new file mode 100644 index 000000000..c4e84a0e7 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/ApiSqliteTestsAsync.cs @@ -0,0 +1,331 @@ +using System.Collections.Generic; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLiteDialects(Dialect.Sqlite)] + public class ApiSqliteTestsAsync : OrmLiteProvidersTestBase + { + public ApiSqliteTestsAsync(DialectContext context) : base(context) {} + + private IDbConnection db; + + [SetUp] + public void SetUp() + { + db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + } + + [TearDown] + public void TearDown() + { + db.Dispose(); + } + + [Test] + public async Task API_Sqlite_Examples_Async() + { + await db.InsertAsync(Person.Rockstars); + + await db.SelectAsync(x => x.Age > 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); + + await db.SelectAsync(db.From().Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.SingleAsync(x => x.Age == 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)\nLIMIT 1")); + + await db.SingleAsync(db.From().Where(x => x.Age == 42)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)\nLIMIT 1")); + + await db.ScalarAsync(x => Sql.Max(x.Age)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"")); + + await db.ScalarAsync(x => Sql.Max(x.Age), x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.CountAsync(x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.CountAsync(db.From().Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + + await db.SelectAsync("Age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > 40"); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + await db.SelectAsync("Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new[] { db.CreateParam("age",40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync("Age > @age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); + + await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); + + await db.SelectAsync(typeof(Person)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\"")); + + await db.SelectAsync(typeof(Person), "Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > @age")); + + await db.WhereAsync("Age", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.WhereAsync(new { Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.SelectByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); + + await db.SelectNonDefaultsAsync(new Person { Id = 1 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); + + await db.SelectNonDefaultsAsync("Age > @Age", new Person { Age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @Age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); + + await db.SingleAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.SingleAsync("Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); + + await db.SingleAsync("Age = @age", new[] { db.CreateParam("age", 42) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); + + await db.SingleByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); + + await db.SingleWhereAsync("Age", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.ScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + await db.ScalarAsync(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); + + await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new[] { db.CreateParam("age", 40) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); + + await db.ColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + + await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); + + await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new[] { db.CreateParam("age", 27) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); + + await db.ColumnDistinctAsync(db.From().Select(x => x.Age).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); + + await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); + + await db.LookupAsync(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); + + await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); + + await db.DictionaryAsync(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); + + await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); + + await db.ExistsAsync(x => x.Age < 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)\nLIMIT 1")); + + await db.ExistsAsync(db.From().Where(x => x.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT 'exists' \nFROM \"Person\"\nWHERE (\"Age\" < @0)\nLIMIT 1")); + + await db.ExistsAsync(new { Age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); + + await db.ExistsAsync("Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); + await db.ExistsAsync("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); + + await db.SqlListAsync(db.From().Select("*").Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < @0)")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new[] { db.CreateParam("age",50) }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); + + + await db.InsertAsync(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + + await db.InsertAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); + + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + + + await db.InsertAllAsync(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.InsertOnlyAsync(() => new PersonWithAutoId { FirstName = "Amy", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur3", Age = 27 }, + new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur4", Age = 28 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.UpdateAsync(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=@Id, \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE (\"LastName\" = @0)")); + + await db.UpdateAsync(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateOnlyAsync(() => new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"LastName\" = @0)")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From().Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); + + await db.UpdateAddAsync(() => new Person { Age = 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age")); + + await db.UpdateAddAsync(() => new Person { Age = 5 }, where: x => x.LastName == "Presley"); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Age\"=\"Age\"+@Age WHERE (\"LastName\" = @0)")); + + await db.DeleteAsync(new { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + + await db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\"=@Id AND \"FirstName\"=@FirstName AND \"LastName\"=@LastName AND \"Age\"=@Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + + await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, + new Person { FirstName = "Janis", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); + + await db.DeleteByIdAsync(1); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" = @0")); + + await db.DeleteByIdsAsync(new[] { 1, 2, 3 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (@0,@1,@2)")); + + await db.DeleteAsync("Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); + + await db.DeleteAsync(typeof(Person), "Age = @age", new { age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = @age")); + + await db.DeleteAsync(p => p.Age == 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + await db.DeleteAsync(db.From().Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); + await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); + + await db.SaveAsync(new Person { Id = 12, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 13, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + + await db.SaveAllAsync(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, + new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Async/AsyncTests.cs b/tests/ServiceStack.OrmLite.Tests/Async/AsyncTests.cs new file mode 100644 index 000000000..7e2331061 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/AsyncTests.cs @@ -0,0 +1,151 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLite] + public class AsyncTests : OrmLiteProvidersTestBase + { + public AsyncTests(DialectContext context) : base(context) {} + + [Test] + public async Task Can_Insert_and_SelectAsync() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + for (var i = 0; i < 3; i++) + { + await db.InsertAsync(new Poco { Id = i + 1, Name = ((char)('A' + i)).ToString() }); + } + + var results = (await db.SelectAsync()).Map(x => x.Name); + Assert.That(results, Is.EqualTo(new[] { "A", "B", "C" })); + + results = (await db.SelectAsync(x => x.Name == "A")).Map(x => x.Name); + Assert.That(results, Is.EqualTo(new[] { "A" })); + + results = (await db.SelectAsync(db.From().Where(x => x.Name == "A"))).Map(x => x.Name); + Assert.That(results, Is.EqualTo(new[] { "A" })); + } + } + + [Test] + public async Task Does_throw_async_errors() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + try + { + var results = await db.SelectAsync(db.From().Where("NotExists = 1")); + Assert.Fail("Should throw"); + } + catch (Exception ex) + { + Assert.That(ex.Message.ToLower(), Does.Contain("id") + .Or.Contain("notexists") + .Or.Contain("not_exists")); + } + + try + { + await db.InsertAsync(new DifferentPoco { NotExists = "Foo" }); + Assert.Fail("Should throw"); + } + catch (Exception ex) + { + Assert.That(ex.Message.ToLower(), Does.Contain("id") + .Or.Contain("notexists") + .Or.Contain("not_exists")); + } + + try + { + await db.InsertAllAsync(new[] { + new DifferentPoco { NotExists = "Foo" }, + new DifferentPoco { NotExists = "Bar" } + }); + Assert.Fail("Should throw"); + } + catch (Exception ex) + { + var innerEx = ex.UnwrapIfSingleException(); + Assert.That(innerEx.Message.ToLower(), Does.Contain("id") + .Or.Contain("notexists") + .Or.Contain("not_exists")); + } + + try + { + await db.UpdateAllAsync(new[] { + new DifferentPoco { NotExists = "Foo" }, + new DifferentPoco { NotExists = "Bar" } + }); + Assert.Fail("Should throw"); + } + catch (Exception ex) + { + var innerEx = ex.UnwrapIfSingleException(); + Assert.That(innerEx.Message.ToLower(), Does.Contain("id") + .Or.Contain("notexists") + .Or.Contain("not_exists")); + } + } + } + + [Alias("Poco")] + public class DifferentPoco + { + public int Id { get; set; } + public string NotExists { get; set; } + } + + [Test] + public async Task Test_Thread_Affinity() + { + var delayMs = 100; + var db = OpenDbConnection(); + + "Root: {0}".Print(Thread.CurrentThread.ManagedThreadId); + var task = Task.Factory.StartNew(() => + { + "Before Delay: {0}".Print(Thread.CurrentThread.ManagedThreadId); + return Task.Delay(delayMs); + }) + .Then(async t => + { + "After Delay: {0}".Print(Thread.CurrentThread.ManagedThreadId); + await Task.Delay(delayMs); + }) + .Then(async t => + { + "Before SQL: {0}".Print(Thread.CurrentThread.ManagedThreadId); + await db.ExistsAsync(x => x.Age < 50) + .Then(t1 => + { + "After SQL: {0}".Print(Thread.CurrentThread.ManagedThreadId); + return Task.Delay(delayMs); + }); + }) + .Then(async inner => + { + "Before Inner: {0}".Print(Thread.CurrentThread.ManagedThreadId); + await Task.Delay(delayMs); + "After Inner: {0}".Print(Thread.CurrentThread.ManagedThreadId); + }); + + await task; + "Await t: {0}".Print(Thread.CurrentThread.ManagedThreadId); + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Async/AutoQueryTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/AutoQueryTestsAsync.cs new file mode 100644 index 000000000..87f92006a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/AutoQueryTestsAsync.cs @@ -0,0 +1,187 @@ +using System; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLite] + public class AutoQueryTestsAsync : OrmLiteProvidersTestBase + { + public AutoQueryTestsAsync(DialectContext context) : base(context) {} + + public static Rockstar[] SeedRockstars = new[] { + new Rockstar { Id = 1, FirstName = "Jimi", LastName = "Hendrix", LivingStatus = LivingStatus.Dead, Age = 27, DateOfBirth = new DateTime(1942, 11, 27), DateDied = new DateTime(1970, 09, 18), }, + new Rockstar { Id = 2, FirstName = "Jim", LastName = "Morrison", Age = 27, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1943, 12, 08), DateDied = new DateTime(1971, 07, 03), }, + new Rockstar { Id = 3, FirstName = "Kurt", LastName = "Cobain", Age = 27, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1967, 02, 20), DateDied = new DateTime(1994, 04, 05), }, + new Rockstar { Id = 4, FirstName = "Elvis", LastName = "Presley", Age = 42, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1935, 01, 08), DateDied = new DateTime(1977, 08, 16), }, + new Rockstar { Id = 5, FirstName = "David", LastName = "Grohl", Age = 44, LivingStatus = LivingStatus.Alive, DateOfBirth = new DateTime(1969, 01, 14), }, + new Rockstar { Id = 6, FirstName = "Eddie", LastName = "Vedder", Age = 48, LivingStatus = LivingStatus.Alive, DateOfBirth = new DateTime(1964, 12, 23), }, + new Rockstar { Id = 7, FirstName = "Michael", LastName = "Jackson", Age = 50, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1958, 08, 29), DateDied = new DateTime(2009, 06, 05), }, + }; + + private static readonly Department2[] SeedDepartments = new[] + { + new Department2 { Id = 10, Name = "Dept 1" }, + new Department2 { Id = 20, Name = "Dept 2" }, + new Department2 { Id = 30, Name = "Dept 3" }, + }; + + public static DeptEmployee[] SeedEmployees = new[] + { + new DeptEmployee { Id = 1, DepartmentId = 10, FirstName = "First 1", LastName = "Last 1" }, + new DeptEmployee { Id = 2, DepartmentId = 20, FirstName = "First 2", LastName = "Last 2" }, + new DeptEmployee { Id = 3, DepartmentId = 30, FirstName = "First 3", LastName = "Last 3" }, + }; + + [Test] + public async Task Can_query_Rockstars_Async() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + await db.InsertAllAsync(SeedRockstars); + + var q = db.From() + .Where("Id < {0} AND Age = {1}", 3, 27); + + var results = await db.SelectAsync(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(q.Params.Count, Is.EqualTo(2)); + + q = db.From() + .Where("Id < {0}", 3) + .Or("Age = {0}", 27); + results = await db.SelectAsync(q); + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(q.Params.Count, Is.EqualTo(2)); + + q = db.From().Where("FirstName".SqlColumn(DialectProvider) + " = {0}", "Kurt"); + results = await db.SelectAsync(q); + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(q.Params.Count, Is.EqualTo(1)); + Assert.That(results[0].LastName, Is.EqualTo("Cobain")); + } + } + + [Test] + public async Task Can_query_Rockstars_with_ValueFormat() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + await db.InsertAllAsync(SeedRockstars); + + var q = db.From() + .Where("FirstName".SqlColumn(DialectProvider) + " LIKE {0}", "Jim%"); + + var results = await db.SelectAsync(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(q.Params.Count, Is.EqualTo(1)); + } + } + + [Test] + public async Task Can_query_Rockstars_with_IN_Query() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + await db.InsertAllAsync(SeedRockstars); + + var q = db.From() + .Where("FirstName".SqlColumn(DialectProvider) + " IN ({0})", new SqlInValues(new[] { "Jimi", "Kurt", "Jim" })); + + var results = await db.SelectAsync(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(q.Params.Count, Is.EqualTo(3)); + } + } + + [Test] + public async Task Does_query_Rockstars_Single_with_anon_SelectInto() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + await db.InsertAllAsync(SeedRockstars); + + var q = db.From() + .Where(x => x.FirstName == "Kurt") + .Select(x => new { x.Id, x.LastName }); + + var result = await db.SingleAsync(q); + Assert.That(result.LastName, Is.EqualTo("Cobain")); + Assert.That(q.Params.Count, Is.EqualTo(1)); + + var results = await db.SelectAsync(q); + Assert.That(results[0].LastName, Is.EqualTo("Cobain")); + Assert.That(q.Params.Count, Is.EqualTo(1)); + } + } + + [Test] + public async Task Can_Select_custom_fields_using_dynamic_Async() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.InsertAll(SeedDepartments); + db.InsertAll(SeedEmployees); + + var q = db.From() + .Join() + .Select( + (de, d2) => new { de.FirstName, de.LastName, d2.Name }); + + var results = await db.SelectAsync(q); + + var sb = new StringBuilder(); + foreach (var result in results) + { + if (!Dialect.AnyPostgreSql.HasFlag(Dialect)) + { + sb.AppendLine(result.FirstName + "," + result.LastName + "," + result.Name); + } + else + { + sb.AppendLine(result.first_name + "," + result.last_name + "," + result.Name); + } + } + + Assert.That(sb.ToString().NormalizeNewLines(), Is.EqualTo( + "First 1,Last 1,Dept 1\nFirst 2,Last 2,Dept 2\nFirst 3,Last 3,Dept 3")); + + q = db.From() + .Join() + .Select(d2 => new { d2.Name }); + + results = await db.SelectAsync(q); + + sb.Length = 0; + foreach (var result in results) + { + if (Dialect != Dialect.AnyPostgreSql) + { + sb.AppendLine(result.Name); + } + else + { + sb.AppendLine(result.Name); + } + } + + Assert.That(sb.ToString().NormalizeNewLines(), Is.EqualTo("Dept 1\nDept 2\nDept 3")); + } + } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/CustomSqlTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/CustomSqlTestsAsync.cs new file mode 100644 index 000000000..8a9f876fd --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/CustomSqlTestsAsync.cs @@ -0,0 +1,146 @@ +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Async +{ + public class LetterFrequency + { + [AutoIncrement] + public int Id { get; set; } + + public string Letter { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class CustomSqlTestsAsync : OrmLiteProvidersTestBase + { + public CustomSqlTestsAsync(DialectContext context) : base(context) {} + + private const string DropProcedureSql = @" + IF OBJECT_ID('spSearchLetters') IS NOT NULL + DROP PROCEDURE spSearchLetters"; + + private const string DropInsertProcedureSql = @" + IF OBJECT_ID('spInsertLetter') IS NOT NULL + DROP PROCEDURE spInsertLetter"; + + private const string CreateProcedureSql = @" + CREATE PROCEDURE spSearchLetters + ( + @pLetter varchar(10), + @pTotal int OUT + ) + AS + BEGIN + SELECT @pTotal = COUNT(*) FROM LetterFrequency WHERE Letter = @pLetter + SELECT * FROM LetterFrequency WHERE Letter = @pLetter + END"; + + private const string CreateInsertProcedureSql = @" + CREATE PROCEDURE spInsertLetter + ( + @pLetter varchar(10), + @pTotal int OUT + ) + AS + BEGIN + INSERT INTO LetterFrequency (Letter) + VALUES (@pLetter) + + SELECT @pTotal = COUNT(*) FROM LetterFrequency WHERE Letter = @pLetter + END"; + + [Test] + public async Task Can_execute_stored_procedure_using_SqlList_with_out_params() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); + await db.InsertAllAsync(rows); + + await db.ExecuteSqlAsync(DropProcedureSql); + await db.ExecuteSqlAsync(CreateProcedureSql); + + IDbDataParameter pTotal = null; + var results = await db.SqlListAsync("spSearchLetters", + cmd => { + cmd.CommandType = CommandType.StoredProcedure; + cmd.AddParam("pLetter", "C"); + pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); + }); + + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(pTotal.Value, Is.EqualTo("3")); + } + } + + [Test] + public async Task Can_execute_stored_procedure_using_SqlProc_with_out_params() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); + await db.InsertAllAsync(rows); + + await db.ExecuteSqlAsync(DropProcedureSql); + await db.ExecuteSqlAsync(CreateProcedureSql); + + var cmd = db.SqlProc("spSearchLetters", new { pLetter = "C" }); + + Assert.That(((OrmLiteCommand)cmd).IsDisposed, Is.False); + + var pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); + var results = await cmd.ConvertToListAsync(); + + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(pTotal.Value, Is.EqualTo("3")); + } + } + + [Test] + public async Task Can_execute_stored_procedure_using_SqlProc_with_out_params_NonQueryAsync() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x }); + await db.InsertAllAsync(rows); + + await db.ExecuteSqlAsync(DropInsertProcedureSql); + await db.ExecuteSqlAsync(CreateInsertProcedureSql); + + var cmd = db.SqlProc("spInsertLetter", new { pLetter = "C" }); + + Assert.That(((OrmLiteCommand)cmd).IsDisposed, Is.False); + + var pTotal = cmd.AddParam("pTotal", direction: ParameterDirection.Output); + await cmd.ExecNonQueryAsync(); + + Assert.That(pTotal.Value, Is.EqualTo("4")); + } + } + + [Test] + [NUnit.Framework.Ignore("Requires out-of-band SP")] + public async Task Can_execute_stored_procedure_returning_scalars() + { + using (var db = OpenDbConnection()) + { + using (var cmd = db.SqlProc( + "GetUserIdsFromEmailAddresses", new { EmailAddresses = "as@if.com" })) + { + var userIds = await cmd.ConvertToListAsync(); + + Assert.That(userIds.Count, Is.GreaterThan(0)); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/Issues/LoadSelectAmbiguousColumnIssue.cs b/tests/ServiceStack.OrmLite.Tests/Async/Issues/LoadSelectAmbiguousColumnIssue.cs new file mode 100644 index 000000000..8fc6ad9d1 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/Issues/LoadSelectAmbiguousColumnIssue.cs @@ -0,0 +1,125 @@ +using System; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Async.Issues +{ + public class AsyncProject : IHasId + { + [Alias("ProjectId")] + [Index(Unique = true)] + [AutoIncrement] + public int Id { get; set; } + + [Required] + [References(typeof(AsyncDepartment))] + public int DepartmentId { get; set; } + [Reference] + public AsyncDepartment AsyncDepartment { get; set; } + + [Required] + public string ProjectName { get; set; } + [Required] + public bool IsArchived { get; set; } + [Required] + public DateTime CreatedOn { get; set; } + } + + public class AsyncDepartment + { + [Alias("DepartmentId")] + [Index(Unique = true)] + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + } + + public class AsyncProjectTask : IHasId + { + [Alias("ProjectTaskId")] + [Index(Unique = true)] + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(AsyncProject))] + public int ProjectId { get; set; } + [Reference] + public AsyncProject AsyncProject { get; set; } + + [Required] + public string Description { get; set; } + [Required] + public DateTime CreatedOn { get; set; } + public DateTime? FinishedOn { get; set; } + [Required] + public int EstimatedHours { get; set; } + + [References(typeof(AsyncProjectTaskStatus))] + public int? ProjectTaskStatusId { get; set; } + [Reference] + public AsyncProjectTaskStatus AsyncProjectTaskStatus { get; set; } + + [Required] + public int Priority { get; set; } + [Required] + public int Order { get; set; } + } + + public class AsyncProjectTaskStatus : IHasId + { + [Alias("ProjectTaskStatusId")] + [Index(Unique = true)] + [AutoIncrement] + public int Id { get; set; } + [Required] + public string Description { get; set; } + } + + [TestFixtureOrmLite] + public class LoadSelectAmbiguousColumnIssue : OrmLiteProvidersTestBase + { + public LoadSelectAmbiguousColumnIssue(DialectContext context) : base(context) {} + + public class AsyncDeptEmployee //Ref of External Table + { + [PrimaryKey] + public int Id { get; set; } + } + + + [Test] + public async Task Can_select_columns_with_LoadSelectAsync() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + + int departmentId = 1; + int statusId = 1; + + var q = db.From() + .Join((pt, p) => pt.ProjectId == p.Id) + .Where(p => p.DepartmentId == departmentId || departmentId == 0) + .And(pt => pt.ProjectTaskStatusId == statusId || statusId == 0); + + var tasks = await db.LoadSelectAsync(q); + + tasks.PrintDump(); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/Issues/PredicateBuilderIssue.cs b/tests/ServiceStack.OrmLite.Tests/Async/Issues/PredicateBuilderIssue.cs new file mode 100644 index 000000000..4d27028cc --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/Issues/PredicateBuilderIssue.cs @@ -0,0 +1,52 @@ +using System.Threading.Tasks; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Async.Issues +{ + [TestFixtureOrmLite] + public class PredicateBuilderIssue : OrmLiteProvidersTestBase + { + public PredicateBuilderIssue(DialectContext context) : base(context) {} + + public class ItemList + { + public int Id { get; set; } + public string Brand { get; set; } + public string ItemDescription { get; set; } + public string Serial { get; set; } + public string ItemStatus { get; set; } + } + + public class Filter + { + public string Keyword { get; set; } + public string ItemStatus { get; set; } + } + + [Test] + public async Task Can_filter_with_predicate() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.Insert(new ItemList { Id = 1, Brand = "foobar" }); + + var filter = new Filter { Keyword = "foo" }; + var q = PredicateBuilder.True(); + + if (!string.IsNullOrWhiteSpace(filter.Keyword)) + { + q = q.And(i => i.Brand.Contains(filter.Keyword) || i.ItemDescription.Contains(filter.Keyword) || i.Serial.Contains(filter.Keyword)); + } + + if (!string.IsNullOrWhiteSpace(filter.ItemStatus)) + { + q = q.And(i => i.ItemStatus == filter.ItemStatus); + } + + var count = await db.CountAsync(db.From().Where(q)); + Assert.That(count, Is.EqualTo(1)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/Issues/SqlServerComputedColumnIssue.cs b/tests/ServiceStack.OrmLite.Tests/Async/Issues/SqlServerComputedColumnIssue.cs new file mode 100644 index 000000000..5532d3191 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/Issues/SqlServerComputedColumnIssue.cs @@ -0,0 +1,162 @@ +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; + +namespace ServiceStack.OrmLite.Tests.Async.Issues +{ + public class ComputeTest : IHasId + { + [PrimaryKey] + [Alias("EmployeeId")] + [AutoIncrement] + [Index(Unique = true)] + public int Id { get; set; } + + [Required] + public string FirstName { get; set; } + public string LastName { get; set; } + + [Required] + [Index(true)] + public string Username { get; set; } + + public string Password { get; set; } + + [Compute] + public string FullName { get; set; } + } + + public class TestExpression + { + [AutoIncrement] + public int Id { get; set; } + public string AccountName { get; set; } + public bool IsActive { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class SqlServerComputedColumnIssue : OrmLiteProvidersTestBase + { + public SqlServerComputedColumnIssue(DialectContext context) : base(context) {} + + private ComputeTest CreateTableAndGetRow() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.ExecuteSql(@" +CREATE TABLE [dbo].[ComputeTest]( + [EmployeeId] [int] IDENTITY(1,1) NOT NULL, + [FullName] AS (concat(ltrim(rtrim([FirstName])),' ',ltrim(rtrim([LastName])))) PERSISTED NOT NULL, + [FirstName] [nvarchar](55) NOT NULL, + [LastName] [nvarchar](55) NULL, + [Username] [nvarchar](55) NOT NULL, + [Password] [nvarchar](55) NULL + CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED +( + [EmployeeId] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY] +) ON [PRIMARY]"); + + var item = new ComputeTest + { + FirstName = "FirstName", + LastName = "LastName", + Username = "Username", + Password = "Password", + FullName = "Should be ignored", + }; + return item; + } + } + + [Test] + public void Can_Insert_and_Update_table_with_Computed_Column() + { + using (var db = OpenDbConnection()) + { + var item = CreateTableAndGetRow(); + + var id = db.Insert(item, selectIdentity: true); + + var row = db.LoadSingleById(id); + + Assert.That(row.FirstName, Is.EqualTo("FirstName")); + Assert.That(row.FullName, Is.EqualTo("FirstName LastName")); + + row.LastName = "Updated LastName"; + db.Update(row); + + row = db.LoadSingleById(id); + + Assert.That(row.FirstName, Is.EqualTo("FirstName")); + Assert.That(row.FullName, Is.EqualTo("FirstName Updated LastName")); + } + } + + [Test] + public async Task Can_Insert_and_Update_table_with_Computed_Column_async() + { + using (var db = OpenDbConnection()) + { + var item = CreateTableAndGetRow(); + + var row = await Create(item); + + Assert.That(row.FirstName, Is.EqualTo("FirstName")); + Assert.That(row.FullName, Is.EqualTo("FirstName LastName")); + + row.LastName = "Updated LastName"; + row = await Create(row); + + Assert.That(row.FirstName, Is.EqualTo("FirstName")); + Assert.That(row.FullName, Is.EqualTo("FirstName Updated LastName")); + } + } + + public virtual async Task Create(T obj) where T : IHasId + { + using (var db = OpenDbConnection()) + { + // if there is an id then INSERTS otherwise UPDATES + var id = obj.GetId().ConvertTo(); + + if (id > 0) + db.Update(obj); + else + id = db.Insert(obj, true); + + // returns the object inserted or updated + return await db.LoadSingleByIdAsync(id); + } + } + + [Test] + public async Task LoadSelect_can_query_and_orderBy() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new TestExpression {AccountName = "Foo", IsActive = true}); + db.Insert(new TestExpression {AccountName = "Bar", IsActive = false}); + + var rows = (await db.LoadSelectAsync(x => x.IsActive)) + .OrderBy(x => x.AccountName) + .ToList(); + + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].AccountName, Is.EqualTo("Foo")); + + rows = await db.LoadSelectAsync(db.From() + .Where(x => x.IsActive) + .OrderBy(x => x.AccountName)); + + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].AccountName, Is.EqualTo("Foo")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiMySqlLegacyTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiMySqlLegacyTestsAsync.cs new file mode 100644 index 000000000..412876db3 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiMySqlLegacyTestsAsync.cs @@ -0,0 +1,101 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Legacy; +using ServiceStack.OrmLite.Tests.Shared; +#pragma warning disable 618 +namespace ServiceStack.OrmLite.Tests.Async.Legacy +{ + [TestFixtureOrmLiteDialects(Dialect.AnyMySql)] + public class ApiMySqlLegacyTestsAsync : OrmLiteProvidersTestBase + { + public ApiMySqlLegacyTestsAsync(DialectContext context) : base(context) {} + + [Test] + public async Task API_MySql_Legacy_Examples_Async() + { + var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + await db.SelectAsync(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > @0)\nORDER BY `Id`")); + + await db.SelectAsync(q => q.Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > @0)")); + + await db.SingleAsync(q => q.Where(x => x.Age == 42)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` = @0)\nLIMIT 1")); + + await db.SelectFmtAsync("Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > 40")); + + await db.SelectFmtAsync("SELECT * FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + await db.SelectFmtAsync(typeof(Person), "Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id` FROM `Person` WHERE Age > 40")); + + await db.SingleFmtAsync("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = 42")); + + await db.ScalarFmtAsync("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); + + await db.ColumnFmtAsync("SELECT LastName FROM Person WHERE Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); + + await db.ColumnDistinctFmtAsync("SELECT Age FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); + + await db.LookupFmtAsync("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); + + await db.DictionaryFmtAsync("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); + + await db.ExistsFmtAsync("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = 42")); + await db.ExistsFmtAsync("SELECT * FROM Person WHERE Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `PersonWithAutoId` (`FirstName`,`Age`) VALUES (@FirstName,@Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `PersonWithAutoId` (`FirstName`,`Age`) VALUES (@FirstName,@Age)")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName WHERE (`FirstName` = @0)")); + + await db.UpdateFmtAsync(set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + await db.UpdateFmtAsync(table: "Person", set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + await db.DeleteFmtAsync("Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); + + await db.DeleteFmtAsync(typeof(Person), "Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); + + await db.DeleteAsync(q => q.Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE (`Age` = @0)")); + + await db.DeleteFmtAsync(where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); + + await db.DeleteFmtAsync(table: "Person", where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); + + db.Dispose(); + } + } +} +#pragma warning restore 618 diff --git a/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiPostgreSqlLegacyTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiPostgreSqlLegacyTestsAsync.cs new file mode 100644 index 000000000..2044ef007 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiPostgreSqlLegacyTestsAsync.cs @@ -0,0 +1,104 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Legacy; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async.Legacy +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class ApiPostgreSqlLegacyTestsAsync : OrmLiteProvidersTestBase + { + public ApiPostgreSqlLegacyTestsAsync(DialectContext context) : base(context) {} + +#pragma warning disable 618 + [Test] + public async Task API_PostgreSql_Legacy_Examples_Async() + { + var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + await db.InsertAsync(Person.Rockstars); + + await db.SelectAsync(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" > :0)\nORDER BY \"id\"")); + + await db.SelectAsync(q => q.Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" > :0)")); + + await db.SingleAsync(q => q.Where(x => x.Age == 42)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" \nFROM \"person\"\nWHERE (\"age\" = :0)\nLIMIT 1")); + + await db.SelectFmtAsync("age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age > 40")); + + await db.SelectFmtAsync("SELECT * FROM person WHERE age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age > 40")); + + await db.SelectFmtAsync(typeof(Person), "age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\" FROM \"person\" WHERE age > 40")); + + await db.SingleFmtAsync("age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age = 42")); + + await db.ScalarFmtAsync("SELECT COUNT(*) FROM person WHERE age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM person WHERE age > 40")); + + await db.ColumnFmtAsync("SELECT last_name FROM person WHERE age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT last_name FROM person WHERE age = 27")); + + await db.ColumnDistinctFmtAsync("SELECT age FROM person WHERE age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT age FROM person WHERE age < 50")); + + await db.LookupFmtAsync("SELECT age, last_name FROM person WHERE age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT age, last_name FROM person WHERE age < 50")); + + await db.DictionaryFmtAsync("SELECT id, last_name FROM person WHERE age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT id, last_name FROM person WHERE age < 50")); + + await db.ExistsFmtAsync("age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"id\", \"first_name\", \"last_name\", \"age\" FROM \"person\" WHERE age = 42")); + await db.ExistsFmtAsync("SELECT * FROM person WHERE age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM person WHERE age = 42")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET last_name={0} WHERE id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET last_name='WaterHouse' WHERE id=7")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person_with_auto_id\" (\"first_name\",\"age\") VALUES (:FirstName,:Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"person_with_auto_id\" (\"first_name\",\"age\") VALUES (:FirstName,:Age)")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET \"first_name\"=:FirstName WHERE (\"first_name\" = :0)")); + + await db.UpdateFmtAsync(set: "first_name = {0}".SqlFmt(DialectProvider, "JJ"), where: "last_name = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET first_name = 'JJ' WHERE last_name = 'Hendrix'")); + + await db.UpdateFmtAsync(table: "person", set: "first_name = {0}".SqlFmt(DialectProvider, "JJ"), where: "last_name = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"person\" SET first_name = 'JJ' WHERE last_name = 'Hendrix'")); + + await db.DeleteFmtAsync("age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE age = 27")); + + await db.DeleteFmtAsync(typeof(Person), "age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE age = 27")); + + await db.DeleteAsync(q => q.Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE (\"age\" = :0)")); + + await db.DeleteFmtAsync(where: "age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE age = 27")); + + await db.DeleteFmtAsync(table: "Person", where: "age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"person\" WHERE age = 27")); + + db.Dispose(); + } +#pragma warning restore 618 + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiSqlServerLegacyTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiSqlServerLegacyTestsAsync.cs new file mode 100644 index 000000000..d2e027d15 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiSqlServerLegacyTestsAsync.cs @@ -0,0 +1,112 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Legacy; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async.Legacy +{ + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class ApiSqlServerLegacyTestsAsync : OrmLiteProvidersTestBase + { + public ApiSqlServerLegacyTestsAsync(DialectContext context) : base(context) {} + +#pragma warning disable 618 + [Test] + public async Task API_SqlServer_Legacy_Examples_Async() + { + var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + await db.InsertAsync(Person.Rockstars); + + await db.SelectAsync(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); + + await db.SelectAsync(q => q.Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.SingleAsync(q => q.Where(x => x.Age == 42)); + + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + } + + await db.SelectFmtAsync("Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + await db.SelectFmtAsync("SELECT * FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + await db.SelectFmtAsync(typeof(Person), "Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); + + await db.SingleFmtAsync("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + + await db.ScalarFmtAsync("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); + + await db.ColumnFmtAsync("SELECT LastName FROM Person WHERE Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); + + await db.ColumnDistinctFmtAsync("SELECT Age FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); + + await db.LookupFmtAsync("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); + + await db.DictionaryFmtAsync("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); + + await db.ExistsFmtAsync("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + await db.ExistsFmtAsync("SELECT * FROM Person WHERE Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); + + await db.UpdateFmtAsync(set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + await db.UpdateFmtAsync(table: "Person", set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + await db.DeleteFmtAsync("Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + await db.DeleteFmtAsync(typeof(Person), "Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + await db.DeleteAsync(q => q.Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + await db.DeleteFmtAsync(where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + await db.DeleteFmtAsync(table: "Person", where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.Dispose(); + } +#pragma warning restore 618 + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiSqliteLegacyTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiSqliteLegacyTestsAsync.cs new file mode 100644 index 000000000..70b077462 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/Legacy/ApiSqliteLegacyTestsAsync.cs @@ -0,0 +1,104 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Legacy; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async.Legacy +{ + [TestFixtureOrmLiteDialects(Dialect.Sqlite)] + public class ApiSqliteLegacyTestsAsync : OrmLiteProvidersTestBase + { + public ApiSqliteLegacyTestsAsync(DialectContext context) : base(context) {} + +#pragma warning disable 618 + [Test] + public async Task API_Sqlite_Legacy_Examples_Async() + { + var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + await db.InsertAsync(Person.Rockstars); + + await db.SelectAsync(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); + + await db.SelectAsync(q => q.Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + await db.SingleAsync(q => q.Where(x => x.Age == 42)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)\nLIMIT 1")); + + await db.SelectFmtAsync("Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + await db.SelectFmtAsync("SELECT * FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + await db.SelectFmtAsync(typeof(Person), "Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); + + await db.SingleFmtAsync("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + + await db.ScalarFmtAsync("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); + + await db.ColumnFmtAsync("SELECT LastName FROM Person WHERE Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); + + await db.ColumnDistinctFmtAsync("SELECT Age FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); + + await db.LookupFmtAsync("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); + + await db.DictionaryFmtAsync("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); + + await db.ExistsFmtAsync("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + await db.ExistsFmtAsync("SELECT * FROM Person WHERE Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); + + var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); + + await db.UpdateFmtAsync(set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + await db.UpdateFmtAsync(table: "Person", set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + await db.DeleteFmtAsync("Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + await db.DeleteFmtAsync(typeof(Person), "Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + await db.DeleteAsync(q => q.Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + await db.DeleteFmtAsync(where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + await db.DeleteFmtAsync(table: "Person", where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.Dispose(); + } +#pragma warning restore 618 + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/LoadReferencesJoinTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/LoadReferencesJoinTestsAsync.cs new file mode 100644 index 000000000..3167960fb --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/LoadReferencesJoinTestsAsync.cs @@ -0,0 +1,179 @@ +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.UseCase; +using ServiceStack.Text; +using System.Text.RegularExpressions; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLite] + public class LoadReferencesJoinTestsAsync : OrmLiteProvidersTestBase + { + public LoadReferencesJoinTestsAsync(DialectContext context) : base(context) {} + + private IDbConnection db; + + [OneTimeSetUp] + public new void TestFixtureSetUp() + { + db = base.OpenDbConnection(); + ResetTables(); + } + + private void ResetTables() + { + CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table + + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + } + + [SetUp] + public void SetUp() + { + db.DeleteAll(); + db.DeleteAll(); + db.DeleteAll(); + db.DeleteAll(); + } + + [OneTimeTearDown] + public new void TestFixtureTearDown() + { + db.Dispose(); + } + + private Customer AddCustomerWithOrders() + { + var customer = new Customer + { + Name = "Customer 1", + PrimaryAddress = new CustomerAddress + { + AddressLine1 = "1 Australia Street", + Country = "Australia" + }, + Orders = new[] + { + new Order {LineItem = "Line 1", Qty = 1, Cost = 1.99m}, + new Order {LineItem = "Line 2", Qty = 2, Cost = 2.99m}, + }.ToList(), + }; + + db.Save(customer, references: true); + + return customer; + } + + [Test] + public async Task Can_populate_multiple_POCOs_using_SelectMulti2() + { + ResetTables(); + AddCustomerWithOrders(); + + var q = db.From() + .Join(); + + var tuples = await db.SelectMultiAsync(q); + + var sb = new StringBuilder(); + foreach (var tuple in tuples) + { + sb.AppendLine("Customer:"); + sb.AppendLine(tuple.Item1.Dump()); + sb.AppendLine("Customer Address:"); + sb.AppendLine(tuple.Item2.Dump()); + } + + Assert.That(sb.ToString().NormalizeNewLines().Trim(), Is.EqualTo( +@"Customer: +{ + Id: 1, + Name: Customer 1 +} +Customer Address: +{ + Id: 1, + CustomerId: 1, + AddressLine1: 1 Australia Street, + Country: Australia +}".NormalizeNewLines())); + } + + [Test] + public async Task Can_populate_multiple_POCOs_using_SelectMulti3() + { + ResetTables(); + AddCustomerWithOrders(); + + var q = db.From() + .Join() + .Join(); + + var tuples = await db.SelectMultiAsync(q); + + var sb = new StringBuilder(); + foreach (var tuple in tuples) + { + sb.AppendLine("Customer:"); + sb.AppendLine(tuple.Item1.Dump()); + sb.AppendLine("Customer Address:"); + sb.AppendLine(tuple.Item2.Dump()); + sb.AppendLine("Order:"); + sb.AppendLine(tuple.Item3.Dump()); + } + + AssertMultiCustomerOrderResults(sb); + } + + private static void AssertMultiCustomerOrderResults(StringBuilder sb) + { + Assert.That(Regex.Replace(sb.ToString(), @"\.99[0]+",".99").NormalizeNewLines().Trim(), Is.EqualTo( + @"Customer: +{ + Id: 1, + Name: Customer 1 +} +Customer Address: +{ + Id: 1, + CustomerId: 1, + AddressLine1: 1 Australia Street, + Country: Australia +} +Order: +{ + Id: 1, + CustomerId: 1, + LineItem: Line 1, + Qty: 1, + Cost: 1.99 +} +Customer: +{ + Id: 1, + Name: Customer 1 +} +Customer Address: +{ + Id: 1, + CustomerId: 1, + AddressLine1: 1 Australia Street, + Country: Australia +} +Order: +{ + Id: 2, + CustomerId: 1, + LineItem: Line 2, + Qty: 2, + Cost: 2.99 +}".NormalizeNewLines())); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/LoadReferencesTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/LoadReferencesTestsAsync.cs new file mode 100644 index 000000000..33217aca3 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/LoadReferencesTestsAsync.cs @@ -0,0 +1,204 @@ +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.UseCase; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLite] + public class LoadReferencesTestsAsync : OrmLiteProvidersTestBase + { + public LoadReferencesTestsAsync(DialectContext context) : base(context) {} + + private IDbConnection db; + + [OneTimeSetUp] + public new void TestFixtureSetUp() + { + db = base.OpenDbConnection(); + CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table + + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + } + + [SetUp] + public void SetUp() + { + db.DeleteAll(); + db.DeleteAll(); + db.DeleteAll(); + } + + [OneTimeTearDown] + public new void TestFixtureTearDown() + { + db.Dispose(); + } + + public static Customer GetCustomerWithOrders(string id = "1") + { + var customer = new Customer + { + Name = "Customer " + id, + PrimaryAddress = new CustomerAddress + { + AddressLine1 = id + " Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, + Orders = new[] + { + new Order {LineItem = "Line 1", Qty = 1, Cost = 1.99m}, + new Order {LineItem = "Line 2", Qty = 2, Cost = 2.99m}, + }.ToList(), + }; + return customer; + } + + [Test] + public async Task Can_Save_and_Load_References_Async() + { + var customer = new Customer + { + Name = "Customer 1", + PrimaryAddress = new CustomerAddress + { + AddressLine1 = "1 Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, + Orders = new[] { + new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, + new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, + }.ToList(), + }; + + await db.SaveAsync(customer); + + Assert.That(customer.Id, Is.GreaterThan(0)); + Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(0)); + + await db.SaveReferencesAsync(customer, customer.PrimaryAddress); + Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(customer.Id)); + + await db.SaveReferencesAsync(customer, customer.Orders); + Assert.That(customer.Orders.All(x => x.CustomerId == customer.Id)); + + var dbCustomer = await db.LoadSingleByIdAsync(customer.Id); + + dbCustomer.PrintDump(); + + Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null); + Assert.That(dbCustomer.Orders.Count, Is.EqualTo(2)); + } + + [Test] + public async Task Can_load_only_included_references_async() + { + var customer = new Customer + { + Name = "Customer 1", + PrimaryAddress = new CustomerAddress + { + AddressLine1 = "1 Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, + Orders = new[] { + new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, + new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, + }.ToList(), + }; + + await db.SaveAsync(customer); + Assert.That(customer.Id, Is.GreaterThan(0)); + + await db.SaveReferencesAsync(customer, customer.PrimaryAddress); + Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(customer.Id)); + + await db.SaveReferencesAsync(customer, customer.Orders); + Assert.That(customer.Orders.All(x => x.CustomerId == customer.Id)); + + // LoadSelectAsync overload 1 + var dbCustomers = await db.LoadSelectAsync(db.From().Where(q => q.Id == customer.Id), include: new[] { "PrimaryAddress" }); + Assert.That(dbCustomers.Count, Is.EqualTo(1)); + Assert.That(dbCustomers[0].Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomers[0].Orders, Is.Null); + Assert.That(dbCustomers[0].PrimaryAddress, Is.Not.Null); + + // LoadSelectAsync overload 2 + dbCustomers = await db.LoadSelectAsync(q => q.Id == customer.Id, include: new[] { "PrimaryAddress" }); + Assert.That(dbCustomers.Count, Is.EqualTo(1)); + Assert.That(dbCustomers[0].Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomers[0].Orders, Is.Null); + Assert.That(dbCustomers[0].PrimaryAddress, Is.Not.Null); + + // LoadSelectAsync overload 3 + dbCustomers = await db.LoadSelectAsync(db.From().Where(x => x.Id == customer.Id), include: new[] { "PrimaryAddress" }); + Assert.That(dbCustomers.Count, Is.EqualTo(1)); + Assert.That(dbCustomers[0].Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomers[0].Orders, Is.Null); + Assert.That(dbCustomers[0].PrimaryAddress, Is.Not.Null); + + // LoadSingleById overload 1 + var dbCustomer = await db.LoadSingleByIdAsync(customer.Id, include: new[] { "PrimaryAddress" }); + Assert.That(dbCustomer.Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null); + + // LoadSingleById overload 2 + dbCustomer = await db.LoadSingleByIdAsync(customer.Id, include: x => new { x.PrimaryAddress }); + Assert.That(dbCustomer.Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null); + + // Invalid field name + dbCustomers = await db.LoadSelectAsync(q => q.Id == customer.Id, include: new[] { "InvalidOption1", "InvalidOption2" }); + Assert.That(dbCustomers.All(x => x.Orders == null)); + Assert.That(dbCustomers.All(x => x.PrimaryAddress == null)); + + dbCustomer = await db.LoadSingleByIdAsync(customer.Id, include: new[] { "InvalidOption1", "InvalidOption2" }); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Null); + } + + [Test] + public async Task Can_Save_References_Async() + { + var customer = new Customer + { + Name = "Customer 1", + PrimaryAddress = new CustomerAddress + { + AddressLine1 = "1 Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, + Orders = new[] { + new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, + new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, + }.ToList(), + }; + + try + { + await db.SaveAsync(customer, references:true); + Assert.That(customer.Id, Is.GreaterThan(0)); + } + catch (Exception ex) + { + throw ex; + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/OrmLiteUpdateOnlyTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/OrmLiteUpdateOnlyTestsAsync.cs new file mode 100644 index 000000000..b39eaca96 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/OrmLiteUpdateOnlyTestsAsync.cs @@ -0,0 +1,51 @@ +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLite] + public class OrmLiteUpdateOnlyTestsAsync : OrmLiteProvidersTestBase + { + public OrmLiteUpdateOnlyTestsAsync(DialectContext context) : base(context) {} + + [Test] + public async Task Supports_different_ways_to_UpdateOnly() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + await db.InsertAsync(new Person + {Id = 1, FirstName = "OriginalFirst", LastName = "OriginalLast", Age = 100}); + + await db.UpdateOnlyAsync(() => new Person {FirstName = "UpdatedFirst", Age = 27}); + var row = (await db.SelectAsync()).First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + await db.DeleteAllAsync(); + await db.InsertAsync(new Person + {Id = 1, FirstName = "OriginalFirst", LastName = "OriginalLast", Age = 100}); + + await db.UpdateOnlyFieldsAsync(new Person {FirstName = "UpdatedFirst", Age = 27}, p => p.FirstName); + row = (await db.SelectAsync()).First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 100))); + + await db.DeleteAllAsync(); + await db.InsertAsync(new Person + {Id = 1, FirstName = "OriginalFirst", LastName = "OriginalLast", Age = 100}); + + await db.UpdateOnlyFieldsAsync(new Person {FirstName = "UpdatedFirst", Age = 27}, + p => new {p.FirstName, p.Age}); + row = (await db.SelectAsync()).First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + await db.DeleteAllAsync(); + await db.InsertAsync(new Person + {Id = 1, FirstName = "OriginalFirst", LastName = "OriginalLast", Age = 100}); + + await db.UpdateOnlyFieldsAsync(new Person {FirstName = "UpdatedFirst", Age = 27}, new[] {"FirstName", "Age"}); + row = (await db.SelectAsync()).First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/OrmLiteUpdateTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/OrmLiteUpdateTestsAsync.cs new file mode 100644 index 000000000..0c9da8756 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/OrmLiteUpdateTestsAsync.cs @@ -0,0 +1,287 @@ +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Models; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLite] + public class OrmLiteUpdateTestsAsync : OrmLiteProvidersTestBase + { + public OrmLiteUpdateTestsAsync(DialectContext context) : base(context) + { + OrmLiteUtils.PrintSql(); + } + + [Test] + public async Task Can_filter_update_method1_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db, 2); + + await ResetUpdateDateAsync(db); + await db.UpdateAsync( + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider), + new DefaultValuesUpdate {Id = 1, DefaultInt = 45 }, new DefaultValuesUpdate {Id = 2, DefaultInt = 72 }); + await VerifyUpdateDateAsync(db); + await VerifyUpdateDateAsync(db, 2); + } + + private async Task CreateAndInitializeAsync(IDbConnection db, int count = 1) + { + db.DropAndCreateTable(); + db.GetLastSql().Print(); + + DefaultValuesUpdate firstRow = null; + for (var i = 1; i <= count; i++) + { + var defaultValues = new DefaultValuesUpdate { Id = i }; + await db.InsertAsync(defaultValues); + + var row = await db.SingleByIdAsync(1); + row.PrintDump(); + Assert.That(row.DefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultIntNoDefault, Is.EqualTo(0)); + Assert.That(row.NDefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.NDefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.DefaultString, Is.EqualTo("String")); + + if (firstRow == null) + firstRow = row; + } + + return firstRow; + } + + private async Task ResetUpdateDateAsync(IDbConnection db) + { + var updateTime = new DateTime(2011, 1, 1, 1, 1, 1, DateTimeKind.Utc); + await db.UpdateAsync(new { UpdatedDateUtc = updateTime }, p => p.Id == 1); + } + + private async Task VerifyUpdateDateAsync(IDbConnection db, int id = 1) + { + var row = await db.SingleByIdAsync(id); + row.PrintDump(); + Assert.That(row.UpdatedDateUtc, Is.GreaterThan(DateTime.UtcNow - TimeSpan.FromMinutes(5))); + } + + [Test] + public async Task Can_filter_update_method2_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + await db.UpdateAsync(new DefaultValuesUpdate { Id = 1, DefaultInt = 2342 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_update_method3_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + var row = await db.SingleByIdAsync(1); + row.DefaultInt = 3245; + row.DefaultDouble = 978.423; + await db.UpdateAsync(row, cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_update_method4_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + await db.UpdateAsync(new { DefaultInt = 765 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_updateAll_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db, 2); + + await ResetUpdateDateAsync(db); + db.UpdateAll(new[] { new DefaultValuesUpdate { Id = 1, DefaultInt = 45 }, new DefaultValuesUpdate { Id = 2, DefaultInt = 72 } }, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + await VerifyUpdateDateAsync(db, 2); + } + + [Test] + public async Task Can_filter_updateOnly_method1_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + db.UpdateOnly(() => new DefaultValuesUpdate { DefaultInt = 345 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_updateOnly_method2_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + await db.UpdateOnlyAsync(() => new DefaultValuesUpdate { DefaultInt = 345 }, db.From().Where(p => p.Id == 1), + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_MySql_updateOnly_method2_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + await db.UpdateOnlyAsync(() => new DefaultValuesUpdate { DefaultInt = 345 }, db.From().Where(p => p.Id == 1), + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_updateOnly_method3_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + var row = await db.SingleByIdAsync(1); + row.DefaultDouble = 978.423; + await db.UpdateOnlyFieldsAsync(row, db.From().Update(p => p.DefaultDouble), + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_updateOnly_method4_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + var row = await db.SingleByIdAsync(1); + row.DefaultDouble = 978.423; + await db.UpdateOnlyFieldsAsync(row, p => p.DefaultDouble, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_updateOnly_method5_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + var row = await db.SingleByIdAsync(1); + row.DefaultDouble = 978.423; + await db.UpdateOnlyFieldsAsync(row, new[] { nameof(DefaultValuesUpdate.DefaultDouble) }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_updateAdd_expression_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + + var count = await db.UpdateAddAsync(() => new DefaultValuesUpdate { DefaultInt = 5, DefaultDouble = 7.2 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + + Assert.That(count, Is.EqualTo(1)); + var row = await db.SingleByIdAsync(1); + Assert.That(row.DefaultInt, Is.EqualTo(6)); + Assert.That(row.DefaultDouble, Is.EqualTo(8.3).Within(0.1)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_filter_updateAdd_SqlExpression_to_insert_date() + { + using var db = await OpenDbConnectionAsync(); + await CreateAndInitializeAsync(db); + + await ResetUpdateDateAsync(db); + + var where = db.From().Where(p => p.Id == 1); + var count = await db.UpdateAddAsync(() => new DefaultValuesUpdate { DefaultInt = 5, DefaultDouble = 7.2 }, @where, + cmd => cmd.SetUpdateDate(nameof(DefaultValuesUpdate.UpdatedDateUtc), DialectProvider)); + + Assert.That(count, Is.EqualTo(1)); + var row = await db.SingleByIdAsync(1); + Assert.That(row.DefaultInt, Is.EqualTo(6)); + Assert.That(row.DefaultDouble, Is.EqualTo(8.3).Within(0.1)); + await VerifyUpdateDateAsync(db); + } + + [Test] + public async Task Can_updated_with_ExecuteSql_and_db_params_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + + db.Insert(new PocoUpdateAsync { Id = 1, Name = "A" }); + db.Insert(new PocoUpdateAsync { Id = 2, Name = "B" }); + + var result = await db.ExecuteSqlAsync($"UPDATE {DialectProvider.GetQuotedTableName("PocoUpdateAsync")} SET name = @name WHERE id = @id", new { id = 2, name = "UPDATED" }); + Assert.That(result, Is.EqualTo(1)); + + var row = await db.SingleByIdAsync(2); + Assert.That(row.Name, Is.EqualTo("UPDATED")); + } + + [Test] + public async Task Does_UpdateAdd_using_AssignmentExpression_async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + await db.InsertAllAsync(Person.Rockstars); + + var count = await db.UpdateAddAsync(() => new Person { FirstName = "JJ", Age = 1 }, @where: p => p.LastName == "Hendrix"); + Assert.That(count, Is.EqualTo(1)); + + var hendrix = Person.Rockstars.First(x => x.LastName == "Hendrix"); + var kurt = Person.Rockstars.First(x => x.LastName == "Cobain"); + + var row = await db.SingleAsync(p => p.LastName == "Hendrix"); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + Assert.That(row.Age, Is.EqualTo(hendrix.Age + 1)); + + count = await db.UpdateAddAsync(() => new Person { FirstName = "KC", Age = hendrix.Age + 1 }, @where: p => p.LastName == "Cobain"); + Assert.That(count, Is.EqualTo(1)); + + row = await db.SingleAsync(p => p.LastName == "Cobain"); + Assert.That(row.FirstName, Is.EqualTo("KC")); + Assert.That(row.Age, Is.EqualTo(kurt.Age + hendrix.Age + 1)); + } + + public class PocoUpdateAsync + { + public int Id { get; set; } + public string Name { get; set; } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/SelectAsyncTests.cs b/tests/ServiceStack.OrmLite.Tests/Async/SelectAsyncTests.cs new file mode 100644 index 000000000..dcfc0782f --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/SelectAsyncTests.cs @@ -0,0 +1,55 @@ +using System; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; + +namespace ServiceStack.OrmLite.Tests.Async +{ + public class PocoWithBytes : IHasGuidId + { + [PrimaryKey] + public Guid Id { get; set; } + + public byte[] Image { get; set; } + + public string ContentType { get; set; } + } + + [TestFixtureOrmLite] + public class SelectAsyncTests : OrmLiteProvidersTestBase + { + public SelectAsyncTests(DialectContext context) : base(context) {} + + [Test] + public async Task Can_SELECT_SingleAsync() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + await db.InsertAsync(new Poco { Id = 1 }); + + var row = await db.SingleAsync(db.From().Where(x => x.Id == 1)); + + Assert.That(row.Id, Is.EqualTo(1)); + } + } + + [Test] + public async Task Can_SELECT_SingleAsyncForStrangeClass() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var bar = new PocoWithBytes { Id = Guid.NewGuid(), Image = new byte[1024 * 10], ContentType = "image/jpeg" }; + await db.InsertAsync(bar); + + var blah = await db.SingleAsync(db.From().Where(x => x.Id == bar.Id)); + Assert.That(blah, Is.Not.Null); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/SqlExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/Async/SqlExpressionTests.cs new file mode 100644 index 000000000..69a1a4874 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/SqlExpressionTests.cs @@ -0,0 +1,214 @@ +using System.Collections.Generic; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.UseCase; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLite] + public class SqlExpressionTests : OrmLiteProvidersTestBase + { + public SqlExpressionTests(DialectContext context) : base(context) {} + + public static void InitLetters(IDbConnection db) + { + db.DropAndCreateTable(); + + db.Insert(new LetterFrequency { Letter = "A" }); + db.Insert(new LetterFrequency { Letter = "B" }); + db.Insert(new LetterFrequency { Letter = "B" }); + db.Insert(new LetterFrequency { Letter = "C" }); + db.Insert(new LetterFrequency { Letter = "C" }); + db.Insert(new LetterFrequency { Letter = "C" }); + db.Insert(new LetterFrequency { Letter = "D" }); + db.Insert(new LetterFrequency { Letter = "D" }); + db.Insert(new LetterFrequency { Letter = "D" }); + db.Insert(new LetterFrequency { Letter = "D" }); + } + + [Test] + public async Task Can_Select_as_List_Object_Async() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + + var query = db.From() + .Select("COUNT(*), MAX(Id), MIN(Id), Sum(Id)"); + + query.ToSelectStatement().Print(); + + var results = await db.SelectAsync>(query); + + Assert.That(results.Count, Is.EqualTo(1)); + + var result = results[0]; + Assert.That(result[0], Is.EqualTo(10)); + Assert.That(result[1], Is.EqualTo(10)); + Assert.That(result[2], Is.EqualTo(1)); + Assert.That(result[3], Is.EqualTo(55)); + + results.PrintDump(); + } + } + + [Test] + public async Task Can_Select_as_Dictionary_Object_Async() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + + var query = db.From() + .Select("COUNT(*) count, MAX(Id) max, MIN(Id) min, Sum(Id) sum"); + + query.ToSelectStatement().Print(); + + var results = await db.SelectAsync>(query); + + Assert.That(results.Count, Is.EqualTo(1)); + //results.PrintDump(); + + var result = results[0]; + Assert.That(result["count"], Is.EqualTo(10)); + Assert.That(result["max"], Is.EqualTo(10)); + Assert.That(result["min"], Is.EqualTo(1)); + Assert.That(result["sum"], Is.EqualTo(55)); + } + } + + [Test] + [IgnoreDialect(Tests.Dialect.AnyMySql, "doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery")] + [IgnoreDialect(Tests.Dialect.AnySqlServer, "generates Windowing function \"... WHERE CustomerId IN (SELECT * FROM ...)\" when should generate \"... WHERE CustomerId IN (SELECT Id FROM ...)\"")] + public void Can_select_limit_on_Table_with_References() + { + using (var db = OpenDbConnection()) + { + CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var customer1 = LoadReferencesTests.GetCustomerWithOrders("1"); + db.Save(customer1, references: true); + + var customer2 = LoadReferencesTests.GetCustomerWithOrders("2"); + db.Save(customer2, references: true); + + var results = db.LoadSelect(db.From() + .OrderBy(x => x.Id) + .Limit(1, 1)); + + //db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("Customer 2")); + Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street")); + Assert.That(results[0].Orders.Count, Is.EqualTo(2)); + + results = db.LoadSelect(db.From() + .Join() + .OrderBy(x => x.Id) + .Limit(1, 1)); + + db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("Customer 2")); + Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street")); + Assert.That(results[0].Orders.Count, Is.EqualTo(2)); + } + } + + [Test] + [IgnoreDialect(Tests.Dialect.AnyMySql, "doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery")] + [IgnoreDialect(Tests.Dialect.AnySqlServer, "generates Windowing function \"... WHERE CustomerId IN (SELECT * FROM ...)\" when should generate \"... WHERE CustomerId IN (SELECT Id FROM ...)\"")] + public async Task Can_select_limit_on_Table_with_References_Async() + { + using (var db = OpenDbConnection()) + { + CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var customer1 = LoadReferencesTests.GetCustomerWithOrders("1"); + db.Save(customer1, references: true); + + var customer2 = LoadReferencesTests.GetCustomerWithOrders("2"); + db.Save(customer2, references: true); + + var results = await db.LoadSelectAsync(db.From() + .OrderBy(x => x.Id) + .Limit(1, 1)); + + //db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("Customer 2")); + Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street")); + Assert.That(results[0].Orders.Count, Is.EqualTo(2)); + + results = await db.LoadSelectAsync(db.From() + .Join() + .OrderBy(x => x.Id) + .Limit(1, 1)); + + db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("Customer 2")); + Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street")); + Assert.That(results[0].Orders.Count, Is.EqualTo(2)); + } + } + + [Test] + public void Can_select_custom_GroupBy() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + + var q = db.From() + .GroupBy("Letter") + .Select(x => new { x.Letter, Count = Sql.Count("*") }); + + var results = db.Dictionary(q); + + Assert.That(results, Is.EquivalentTo(new Dictionary + { + { "A", 1 }, + { "B", 2 }, + { "C", 3 }, + { "D", 4 }, + })); + } + } + + [Test] + public void Can_select_custom_GroupBy_KeyValuePairs() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + + var q = db.From() + .GroupBy("Letter") + .Select(x => new { x.Letter, Count = Sql.Count("*") }); + + var results = db.KeyValuePairs(q); + + Assert.That(results, Is.EquivalentTo(new List> + { + new KeyValuePair("A", 1), + new KeyValuePair("B", 2), + new KeyValuePair("C", 3), + new KeyValuePair("D", 4), + })); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Async/SqlServerProviderTestsAsync.cs b/tests/ServiceStack.OrmLite.Tests/Async/SqlServerProviderTestsAsync.cs new file mode 100644 index 000000000..24b13f3d8 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Async/SqlServerProviderTestsAsync.cs @@ -0,0 +1,254 @@ +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Async +{ + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class SqlServerProviderTestsAsync : OrmLiteProvidersTestBase + { + public SqlServerProviderTestsAsync(DialectContext context) : base(context) {} + + private IDbConnection db; + + [SetUp] + public void TestFixtureSetUp() + { + db = OpenDbConnection(); + } + + [TearDown] + public void TearDown() + { + db.Dispose(); + } + + [Test] + public async Task Can_SqlList_StoredProc_returning_Table_Async() + { + var sql = @"CREATE PROCEDURE dbo.DummyTable + @Times integer +AS +BEGIN + SET NOCOUNT ON; + + CREATE TABLE #Temp + ( + Id integer NOT NULL, + Name nvarchar(50) COLLATE DATABASE_DEFAULT NOT NULL + ); + + declare @i int + set @i=1 + WHILE @i < @Times + BEGIN + INSERT INTO #Temp (Id, Name) VALUES (@i, CAST(@i as nvarchar)) + SET @i = @i + 1 + END + + SELECT * FROM #Temp; + + DROP TABLE #Temp; +END;"; + await db.ExecuteSqlAsync("IF OBJECT_ID('DummyTable') IS NOT NULL DROP PROC DummyTable"); + await db.ExecuteSqlAsync(sql); + + var expected = 0; + 10.Times(i => expected += i); + + var results = await db.SqlListAsync("EXEC DummyTable @Times", new { Times = 10 }); + results.PrintDump(); + Assert.That(results.Sum(x => x.Id), Is.EqualTo(expected)); + + results = await db.SqlListAsync("EXEC DummyTable 10"); + Assert.That(results.Sum(x => x.Id), Is.EqualTo(expected)); + + results = await db.SqlListAsync("EXEC DummyTable @Times", new Dictionary { { "Times", 10 } }); + Assert.That(results.Sum(x => x.Id), Is.EqualTo(expected)); + } + + [Test] + public async Task Can_SqlColumn_StoredProc_returning_Column_Async() + { + var sql = @"CREATE PROCEDURE dbo.DummyColumn + @Times integer +AS +BEGIN + SET NOCOUNT ON; + + CREATE TABLE #Temp + ( + Id integer NOT NULL, + ); + + declare @i int + set @i=1 + WHILE @i < @Times + BEGIN + INSERT INTO #Temp (Id) VALUES (@i) + SET @i = @i + 1 + END + + SELECT * FROM #Temp; + + DROP TABLE #Temp; +END;"; + await db.ExecuteSqlAsync("IF OBJECT_ID('DummyColumn') IS NOT NULL DROP PROC DummyColumn"); + await db.ExecuteSqlAsync(sql); + + var expected = 0; + 10.Times(i => expected += i); + + var results = await db.SqlColumnAsync("EXEC DummyColumn @Times", new { Times = 10 }); + results.PrintDump(); + Assert.That(results.Sum(), Is.EqualTo(expected)); + + results = await db.SqlColumnAsync("EXEC DummyColumn 10"); + Assert.That(results.Sum(), Is.EqualTo(expected)); + + results = await db.SqlColumnAsync("EXEC DummyColumn @Times", new Dictionary { { "Times", 10 } }); + Assert.That(results.Sum(), Is.EqualTo(expected)); + } + + [Test] + public async Task Can_SqlColumn_StoredProc_returning_StringColumn_Async() + { + var sql = @"CREATE PROCEDURE dbo.DummyColumn + @Times integer +AS +BEGIN + SET NOCOUNT ON; + + CREATE TABLE #Temp + ( + Name nvarchar(50) not null + ); + + declare @i int + set @i=0 + WHILE @i < @Times + BEGIN + INSERT INTO #Temp (Name) VALUES (CAST(NEWID() AS nvarchar(50))) + SET @i = @i + 1 + END + + SELECT * FROM #Temp; + + DROP TABLE #Temp; +END;"; + await db.ExecuteSqlAsync("IF OBJECT_ID('DummyColumn') IS NOT NULL DROP PROC DummyColumn"); + await db.ExecuteSqlAsync(sql); + + // This produces a compiler error + var results = await db.SqlColumnAsync("EXEC DummyColumn @Times", new { Times = 10 }); + results.PrintDump(); + Assert.That(results.Count, Is.EqualTo(10)); + } + + [Test] + public async Task Can_SqlScalar_StoredProc_returning_Scalar_Async() + { + var sql = @"CREATE PROCEDURE dbo.DummyScalar + @Times integer +AS +BEGIN + SET NOCOUNT ON; + + SELECT @Times AS Id +END;"; + await db.ExecuteSqlAsync("IF OBJECT_ID('DummyScalar') IS NOT NULL DROP PROC DummyScalar"); + await db.ExecuteSqlAsync(sql); + + const int expected = 10; + + var result = await db.SqlScalarAsync("EXEC DummyScalar @Times", new { Times = 10 }); + result.PrintDump(); + Assert.That(result, Is.EqualTo(expected)); + + result = await db.SqlScalarAsync("EXEC DummyScalar 10"); + Assert.That(result, Is.EqualTo(expected)); + + result = await db.SqlScalarAsync("EXEC DummyScalar @Times", new Dictionary { { "Times", 10 } }); + Assert.That(result, Is.EqualTo(expected)); + + result = await db.SqlScalarAsync("SELECT 10"); + Assert.That(result, Is.EqualTo(expected)); + } + + [Test] + public async Task Can_SqlScalar_StoredProc_passing_null_parameter_Async() + { + const string sql = @"CREATE PROCEDURE dbo.DummyScalar + @Times integer +AS +BEGIN + SET NOCOUNT ON; + + SELECT @Times AS Id +END;"; + await db.ExecuteSqlAsync("IF OBJECT_ID('DummyScalar') IS NOT NULL DROP PROC DummyScalar"); + await db.ExecuteSqlAsync(sql); + + var result = await db.SqlScalarAsync("EXEC DummyScalar @Times", new { Times = (int?)null }); + Assert.That(result, Is.Null); + + result = await db.SqlScalarAsync("EXEC DummyScalar NULL"); + Assert.That(result, Is.Null); + + result = await db.SqlScalarAsync("EXEC DummyScalar @Times", new Dictionary { { "Times", null } }); + Assert.That(result, Is.Null); + + result = await db.SqlScalarAsync("SELECT NULL"); + Assert.That(result, Is.Null); + } + + [Test] + public async Task Can_SqlList_StoredProc_passing_null_parameter_Async() + { + const string sql = @"CREATE PROCEDURE dbo.DummyProc + @Name nvarchar(50) +AS +BEGIN + SET NOCOUNT ON; + + SELECT 1 AS Id, 'Name_1' AS Name WHERE @Name IS NULL + UNION ALL + SELECT 2 AS Id, 'Name_2' AS Name WHERE @Name IS NOT NULL + UNION ALL + SELECT 3 AS Id, 'Name_3' AS Name WHERE @Name IS NULL + +END;"; + await db.ExecuteSqlAsync("IF OBJECT_ID('DummyProc') IS NOT NULL DROP PROC DummyProc"); + await db.ExecuteSqlAsync(sql); + + var results = await db.SqlColumnAsync("EXEC DummyProc @Name", new { Name = (string)null }); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(results[0].Name, Is.EqualTo("Name_1")); + Assert.That(results[1].Name, Is.EqualTo("Name_3")); + } + + [Test] + public async Task Can_SqlList_StoredProc_receiving_only_first_column_and_null_Async() + { + const string sql = @"CREATE PROCEDURE dbo.DummyScalar +AS +BEGIN + SET NOCOUNT ON; + + SELECT NULL AS Id, 'Name_1' AS Name + UNION ALL + SELECT NULL AS Id, 'Name_2' AS Name +END;"; + await db.ExecuteSqlAsync("IF OBJECT_ID('DummyScalar') IS NOT NULL DROP PROC DummyScalar"); + await db.ExecuteSqlAsync(sql); + + var results = await db.SqlColumnAsync("EXEC DummyScalar"); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(results[0], Is.Null); + Assert.That(results[1], Is.Null); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/AutoIdTests.cs b/tests/ServiceStack.OrmLite.Tests/AutoIdTests.cs new file mode 100644 index 000000000..812cc3fb0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/AutoIdTests.cs @@ -0,0 +1,248 @@ +using System; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests +{ + public class GuidAutoId + { + [AutoId] + public Guid Id { get; set; } + + public string Name { get; set; } + } + + [TestFixtureOrmLite] + [NonParallelizable] + public class AutoIdTests : OrmLiteProvidersTestBase + { + public AutoIdTests(DialectContext context) : base(context) {} + + [Test] + public void Does_populate_and_return_new_guid_on_insert() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var guidA = new GuidAutoId { Name = "A" }; + var guidB = new GuidAutoId { Name = "B" }; + + db.Insert(guidA); + db.Insert(guidB); + + Assert.That(guidA.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidB.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidA.Id, Is.Not.EqualTo(guidB)); + + var dbA = db.SingleById(guidA.Id); + Assert.That(dbA.Name, Is.EqualTo(guidA.Name)); + + var dbB = db.SingleById(guidB.Id); + Assert.That(dbB.Name, Is.EqualTo(guidB.Name)); + } + + [Test] + public async Task Does_populate_and_return_new_guid_on_insert_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + + var guidA = new GuidAutoId { Name = "A" }; + var guidB = new GuidAutoId { Name = "B" }; + + await db.InsertAsync(guidA); + await db.InsertAsync(guidB); + + Assert.That(guidA.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidB.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidA.Id, Is.Not.EqualTo(guidB)); + + var dbA = await db.SingleByIdAsync(guidA.Id); + Assert.That(dbA.Name, Is.EqualTo(guidA.Name)); + + var dbB = await db.SingleByIdAsync(guidB.Id); + Assert.That(dbB.Name, Is.EqualTo(guidB.Name)); + } + + [Test] + public void Does_populate_and_return_new_guid_on_insert_ObjectDictionary() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var guidA = new GuidAutoId { Name = "A" }.ToObjectDictionary(); + var guidB = new GuidAutoId { Name = "B" }.ToObjectDictionary(); + + db.Insert(guidA); + db.Insert(guidB, selectIdentity:true); + + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidB[nameof(GuidAutoId.Id)], Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.Not.EqualTo(guidB)); + + var dbA = db.SingleById(guidA[nameof(GuidAutoId.Id)]); + Assert.That(dbA.Name, Is.EqualTo(guidA[nameof(GuidAutoId.Name)])); + + var dbB = db.SingleById(guidB[nameof(GuidAutoId.Id)]); + Assert.That(dbB.Name, Is.EqualTo(guidB[nameof(GuidAutoId.Name)])); + } + + [Test] + public async Task Does_populate_and_return_new_guid_on_insert_ObjectDictionary_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + + var guidA = new GuidAutoId { Name = "A" }.ToObjectDictionary(); + var guidB = new GuidAutoId { Name = "B" }.ToObjectDictionary(); + + await db.InsertAsync(guidA); + await db.InsertAsync(guidB, selectIdentity:true); + + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidB[nameof(GuidAutoId.Id)], Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.Not.EqualTo(guidB)); + + var dbA = await db.SingleByIdAsync(guidA[nameof(GuidAutoId.Id)]); + Assert.That(dbA.Name, Is.EqualTo(guidA[nameof(GuidAutoId.Name)])); + + var dbB = await db.SingleByIdAsync(guidB[nameof(GuidAutoId.Id)]); + Assert.That(dbB.Name, Is.EqualTo(guidB[nameof(GuidAutoId.Name)])); + } + + [Test] + public void Does_populate_and_return_existing_guid_on_insert_ObjectDictionary() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + var aGuid = Guid.NewGuid(); + var bGuid = Guid.NewGuid(); + + var guidA = new GuidAutoId { Id = aGuid, Name = "A" }.ToObjectDictionary(); + var guidB = new GuidAutoId { Id = bGuid, Name = "B" }.ToObjectDictionary(); + + db.Insert(guidA); + db.Insert(guidB, selectIdentity:true); + + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.EqualTo(aGuid)); + Assert.That(guidB[nameof(GuidAutoId.Id)], Is.EqualTo(bGuid)); + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.Not.EqualTo(guidB)); + + var dbA = db.SingleById(guidA[nameof(GuidAutoId.Id)]); + Assert.That(dbA.Name, Is.EqualTo(guidA[nameof(GuidAutoId.Name)])); + + var dbB = db.SingleById(guidB[nameof(GuidAutoId.Id)]); + Assert.That(dbB.Name, Is.EqualTo(guidB[nameof(GuidAutoId.Name)])); + } + + [Test] + public async Task Does_populate_and_return_existing_guid_on_insert_ObjectDictionary_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + var aGuid = Guid.NewGuid(); + var bGuid = Guid.NewGuid(); + + var guidA = new GuidAutoId { Id = aGuid, Name = "A" }.ToObjectDictionary(); + var guidB = new GuidAutoId { Id = bGuid, Name = "B" }.ToObjectDictionary(); + + await db.InsertAsync(guidA); + await db.InsertAsync(guidB, selectIdentity:true); + + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.EqualTo(aGuid)); + Assert.That(guidB[nameof(GuidAutoId.Id)], Is.EqualTo(bGuid)); + Assert.That(guidA[nameof(GuidAutoId.Id)], Is.Not.EqualTo(guidB)); + + var dbA = await db.SingleByIdAsync(guidA[nameof(GuidAutoId.Id)]); + Assert.That(dbA.Name, Is.EqualTo(guidA[nameof(GuidAutoId.Name)])); + + var dbB = await db.SingleByIdAsync(guidB[nameof(GuidAutoId.Id)]); + Assert.That(dbB.Name, Is.EqualTo(guidB[nameof(GuidAutoId.Name)])); + } + + [Test] + public void Does_populate_and_return_new_guid_on_save() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var guidA = new GuidAutoId { Name = "A" }; + var guidB = new GuidAutoId { Name = "B" }; + + db.Save(guidA); + db.Save(guidB); + + Assert.That(guidA.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidB.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidA.Id, Is.Not.EqualTo(guidB)); + + var dbA = db.SingleById(guidA.Id); + Assert.That(dbA.Name, Is.EqualTo(guidA.Name)); + + var dbB = db.SingleById(guidB.Id); + Assert.That(dbB.Name, Is.EqualTo(guidB.Name)); + } + + [Test] + public async Task Does_populate_and_return_new_guid_on_save_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + + var guidA = new GuidAutoId { Name = "A" }; + var guidB = new GuidAutoId { Name = "B" }; + + await db.SaveAsync(guidA); + await db.SaveAsync(guidB); + + Assert.That(guidA.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidB.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(guidA.Id, Is.Not.EqualTo(guidB)); + + var dbA = await db.SingleByIdAsync(guidA.Id); + Assert.That(dbA.Name, Is.EqualTo(guidA.Name)); + + var dbB = await db.SingleByIdAsync(guidB.Id); + Assert.That(dbB.Name, Is.EqualTo(guidB.Name)); + } + + [Test] + public void Uses_existing_Guid_Id_if_not_Empty() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var existingGuid = Guid.NewGuid(); + var guidA = new GuidAutoId { Id = existingGuid, Name = "A" }; + + db.Insert(guidA); + + Assert.That(guidA.Id, Is.EqualTo(existingGuid)); + + var fromDb = db.SingleById(existingGuid); + + Assert.That(fromDb.Id, Is.EqualTo(existingGuid)); + } + + [Test] + public void Uses_existing_Guid_Id_if_not_Empty_for_row_inserts() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var existingGuid = Guid.NewGuid(); + var guidA = new GuidAutoId { Id = existingGuid, Name = "A" }; + + db.Exec(cmd => { + cmd.CommandText = DialectProvider.ToInsertRowStatement(cmd, guidA); + DialectProvider.SetParameterValues(cmd, guidA); + cmd.ExecuteNonQuery(); + }); + + var fromDb = db.SingleById(existingGuid); + Assert.That(fromDb.Id, Is.EqualTo(existingGuid)); + } + } + +} diff --git a/tests/ServiceStack.OrmLite.Tests/AutoQueryTests.cs b/tests/ServiceStack.OrmLite.Tests/AutoQueryTests.cs new file mode 100644 index 000000000..bd864d0cb --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/AutoQueryTests.cs @@ -0,0 +1,514 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public class Rockstar + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public int? Age { get; set; } + public DateTime DateOfBirth { get; set; } + public DateTime? DateDied { get; set; } + public LivingStatus LivingStatus { get; set; } + } + + public class RockstarAlbum + { + public int Id { get; set; } + public int RockstarId { get; set; } + public string Name { get; set; } + } + + public class RockstarWithAlbum + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public int Age { get; set; } + public int RockstarId { get; set; } + public string RockstarAlbumName { get; set; } + public int RockstarAlbumId { get; set; } + } + + public class RockstarAlt + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public int? Age { get; set; } + } + + public enum LivingStatus + { + Alive, + Dead + } + + public class DeptEmployee + { + [PrimaryKey] + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + [References(typeof(Department2))] + public int DepartmentId { get; set; } + + [Reference] + public Department2 Department { get; set; } + } + + public class Department2 + { + [PrimaryKey] + public int Id { get; set; } + public string Name { get; set; } + } + + + [TestFixtureOrmLite] + public class AutoQueryTests : OrmLiteProvidersTestBase + { + public AutoQueryTests(DialectContext context) : base(context) {} + + public static Rockstar[] SeedRockstars = new[] { + new Rockstar { Id = 1, FirstName = "Jimi", LastName = "Hendrix", LivingStatus = LivingStatus.Dead, Age = 27, DateOfBirth = new DateTime(1942, 11, 27), DateDied = new DateTime(1970, 09, 18), }, + new Rockstar { Id = 2, FirstName = "Jim", LastName = "Morrison", Age = 27, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1943, 12, 08), DateDied = new DateTime(1971, 07, 03), }, + new Rockstar { Id = 3, FirstName = "Kurt", LastName = "Cobain", Age = 27, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1967, 02, 20), DateDied = new DateTime(1994, 04, 05), }, + new Rockstar { Id = 4, FirstName = "Elvis", LastName = "Presley", Age = 42, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1935, 01, 08), DateDied = new DateTime(1977, 08, 16), }, + new Rockstar { Id = 5, FirstName = "David", LastName = "Grohl", Age = 44, LivingStatus = LivingStatus.Alive, DateOfBirth = new DateTime(1969, 01, 14), }, + new Rockstar { Id = 6, FirstName = "Eddie", LastName = "Vedder", Age = 48, LivingStatus = LivingStatus.Alive, DateOfBirth = new DateTime(1964, 12, 23), }, + new Rockstar { Id = 7, FirstName = "Michael", LastName = "Jackson", Age = 50, LivingStatus = LivingStatus.Dead, DateOfBirth = new DateTime(1958, 08, 29), DateDied = new DateTime(2009, 06, 05), }, + }; + + public static RockstarAlbum[] SeedAlbums = new[] { + new RockstarAlbum { Id = 10, RockstarId = 1, Name = "Electric Ladyland" }, + new RockstarAlbum { Id = 11, RockstarId = 3, Name = "Nevermind" }, + new RockstarAlbum { Id = 12, RockstarId = 7, Name = "Thriller" }, + }; + + private static readonly Department2[] SeedDepartments = new[] + { + new Department2 { Id = 10, Name = "Dept 1" }, + new Department2 { Id = 20, Name = "Dept 2" }, + new Department2 { Id = 30, Name = "Dept 3" }, + }; + + public static DeptEmployee[] SeedEmployees = new[] + { + new DeptEmployee { Id = 1, DepartmentId = 10, FirstName = "First 1", LastName = "Last 1" }, + new DeptEmployee { Id = 2, DepartmentId = 20, FirstName = "First 2", LastName = "Last 2" }, + new DeptEmployee { Id = 3, DepartmentId = 30, FirstName = "First 3", LastName = "Last 3" }, + }; + + [Test] + public void Can_query_Rockstars() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(SeedRockstars); + + var q = db.From() + .Where("Id < {0} AND Age = {1}", 3, 27); + + var results = db.Select(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(q.Params.Count, Is.EqualTo(2)); + + q = db.From() + .Where("Id < {0}", 3) + .Or("Age = {0}", 27); + results = db.Select(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(q.Params.Count, Is.EqualTo(2)); + + q = db.From().Where("FirstName".SqlColumn(DialectProvider) + " = {0}", "Kurt"); + results = db.Select(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(q.Params.Count, Is.EqualTo(1)); + Assert.That(results[0].LastName, Is.EqualTo("Cobain")); + } + + [Test] + public void Can_query_Rockstars_with_ValueFormat() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(SeedRockstars); + + var q = db.From() + .Where("FirstName".SqlColumn(DialectProvider) + " LIKE {0}", "Jim%"); + + var results = db.Select(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(q.Params.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_query_Rockstars_with_IN_Query() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(SeedRockstars); + + var q = db.From() + .Where("FirstName".SqlColumn(DialectProvider) + " IN ({0})", new SqlInValues(new[] { "Jimi", "Kurt", "Jim" }, DialectProvider)); + + var results = db.Select(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(3)); + Assert.That(q.Params.Count, Is.EqualTo(3)); + } + + [Test] + public void Does_query_Rockstars_Single_with_anon_SelectInto() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(SeedRockstars); + + var q = db.From() + .Where(x => x.FirstName == "Kurt") + .Select(x => new { x.Id, x.LastName }); + + var result = db.Single(q); + Assert.That(result.LastName, Is.EqualTo("Cobain")); + Assert.That(q.Params.Count, Is.EqualTo(1)); + + var results = db.Select(q); + Assert.That(results[0].LastName, Is.EqualTo("Cobain")); + Assert.That(q.Params.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_use_dynamic_apis_on_Custom_Select() + { + using var db = OpenDbConnection(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.InsertAll(SeedDepartments); + db.InsertAll(SeedEmployees); + + var q = db.From().Select(new[] { "FirstName" }).Take(2); + + var resultsMap = db.Select>(q); + Assert.That(resultsMap.Count, Is.EqualTo(2)); + var row = new Dictionary(resultsMap[0], StringComparer.OrdinalIgnoreCase); + Assert.That(row.ContainsKey("FirstName".SqlTableRaw(DialectProvider))); + Assert.That(!row.ContainsKey("Id".SqlTableRaw(DialectProvider))); + + var resultsList = db.Select>(q); + Assert.That(resultsList.Count, Is.EqualTo(2)); + Assert.That(resultsList[0].Count, Is.EqualTo(1)); + + var resultsDynamic = db.Select(q); + Assert.That(resultsDynamic.Count, Is.EqualTo(2)); + var map = (IDictionary)resultsDynamic[0]; + Assert.That(map.ContainsKey("FirstName".SqlTableRaw(DialectProvider))); + Assert.That(!map.ContainsKey("Id".SqlTableRaw(DialectProvider))); + + resultsDynamic = db.Select(q.ToSelectStatement()); + Assert.That(resultsDynamic.Count, Is.EqualTo(2)); + map = (IDictionary)resultsDynamic[0]; + Assert.That(map.ContainsKey("FirstName".SqlTableRaw(DialectProvider))); + Assert.That(!map.ContainsKey("Id".SqlTableRaw(DialectProvider))); + } + + [Test] + public void Does_only_populate_Select_fields() + { + using var db = OpenDbConnection(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.InsertAll(SeedDepartments); + db.InsertAll(SeedEmployees); + + var q = db.From() + .Join() + .Select(new[] { "departmentid" }); + + var results = db.Select(q); + + Assert.That(results.All(x => x.Id == 0)); + Assert.That(results.All(x => x.DepartmentId >= 10)); + + q = db.From() + .Join() + .Select(new[] { "id", "departmentid" }); + + results = db.Select(q); + + results.PrintDump(); + + Assert.That(results.All(x => x.Id > 0 && x.Id < 10)); + Assert.That(results.All(x => x.DepartmentId >= 10)); + } + + [Test] + public void Does_only_populate_Select_fields_wildcard() + { + using var db = OpenDbConnection(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.InsertAll(SeedDepartments); + db.InsertAll(SeedEmployees); + + var q = db.From() + .Join() + .Select(new[] { "departmentid", "deptemployee.*" }); + + Assert.That(q.OnlyFields, Is.EquivalentTo(new[] { + "departmentid", "Id", "FirstName", "LastName" + })); + + var results = db.Select(q); + Assert.That(results.All(x => x.Id >= 0)); + Assert.That(results.All(x => x.DepartmentId >= 10)); + Assert.That(results.All(x => x.FirstName != null)); + Assert.That(results.All(x => x.LastName != null)); + + q = db.From() + .Join() + .Select(new[] { "departmentid", "department", "department2.*" }); + + Assert.That(q.OnlyFields, Is.EquivalentTo(new[] { + "departmentid", "department", "Id", "Name" + })); + + results = db.LoadSelect(q, include: q.OnlyFields); + + Assert.That(results.All(x => x.Id > 0 && x.Id < 10)); + Assert.That(results.All(x => x.DepartmentId >= 10)); + Assert.That(results.All(x => x.Department.Id >= 10)); + Assert.That(results.All(x => x.Department.Name != null)); + } + + [Test] + public void Does_only_populate_LoadSelect_fields() + { + using var db = OpenDbConnection(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.InsertAll(SeedDepartments); + db.InsertAll(SeedEmployees); + + var q = db.From() + .Join() + .Select(new[] { "departmentid" }); + + var results = db.LoadSelect(q); + results.PrintDump(); + + Assert.That(results.All(x => x.Id == 0)); + Assert.That(results.All(x => x.DepartmentId >= 10)); + + q = db.From() + .Join() + .Select(new[] { "id", "departmentid" }); + + results = db.LoadSelect(q); + results.PrintDump(); + + Assert.That(results.All(x => x.Id > 0 && x.Id < 10)); + Assert.That(results.All(x => x.DepartmentId >= 10)); + } + + [Test] + public void Can_Select_custom_fields_using_dynamic() + { + using var db = OpenDbConnection(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.InsertAll(SeedDepartments); + db.InsertAll(SeedEmployees); + + var q = db.From() + .Join() + .Select( + (de, d2) => new { de.FirstName, de.LastName, d2.Name }); + var results = db.Select(q); + db.GetLastSql().Print(); + + var sb = new StringBuilder(); + foreach (var result in results) + { + if (Dialect.AnyPostgreSql.HasFlag(Dialect)) + sb.AppendLine(result.first_name + "," + result.last_name + "," + result.Name); + else if (Dialect.Firebird.HasFlag(Dialect)) + sb.AppendLine(result.FIRSTNAME + "," + result.LASTNAME + "," + result.NAME); + else + sb.AppendLine(result.FirstName + "," + result.LastName + "," + result.Name); + } + + Assert.That(sb.ToString().NormalizeNewLines(), Is.EqualTo( + "First 1,Last 1,Dept 1\nFirst 2,Last 2,Dept 2\nFirst 3,Last 3,Dept 3")); + + q = db.From() + .Join() + .Select(d2 => new { d2.Name }); + + results = db.Select(q); + + sb.Length = 0; + foreach (var result in results) + { + if (Dialect.AnyPostgreSql.HasFlag(Dialect)) + sb.AppendLine(result.Name); + else if (Dialect.Firebird.HasFlag(Dialect)) + sb.AppendLine(result.NAME); + else + sb.AppendLine(result.Name); + } + + Assert.That(sb.ToString().NormalizeNewLines(), Is.EqualTo("Dept 1\nDept 2\nDept 3")); + } + + [Test] + public void Can_select_custom_fields_using_ValueTuple() + { + using var db = OpenDbConnection(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.InsertAll(SeedDepartments); + db.InsertAll(SeedEmployees); + + var q = db.From() + .Join() + .OrderBy(x => x.Id) + .Select( + (de, d2) => new { de.Id, de.LastName, d2.Name }); + + var results = db.Select<(int id, string lastName, string deptName)>(q); + + Assert.That(results.Count, Is.EqualTo(3)); + for (var i = 0; i < results.Count; i++) + { + var row = results[i]; + var count = i + 1; + Assert.That(row.id, Is.EqualTo(count)); + Assert.That(row.lastName, Is.EqualTo("Last " + count)); + Assert.That(row.deptName, Is.EqualTo("Dept " + count)); + } + } + + [Test] + public void Can_group_by_multiple_columns() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.InsertAll(SeedRockstars); + db.InsertAll(SeedAlbums); + + var q = db.From() + .Join() + .GroupBy((r, a) => new { r.Id, AlbumId = a.Id, r.FirstName, r.LastName, a.Name }) + .Select((r,a) => new + { + r.Id, + AlbumId = a.Id, + r.FirstName, + r.LastName, + a.Name + }); + + var results = db.Select<(int id, int albumId, string firstName, string album)>(q); + + Assert.That(results.Count, Is.EqualTo(3)); + } + + [Test] + public void Can_query_Rockstars_with_Distinct_Fields() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(SeedRockstars); + // Add another Michael Rockstar + db.Insert(new Rockstar { Id = 8, FirstName = "Michael", LastName = "Bolton", Age = 64, LivingStatus = LivingStatus.Alive, DateOfBirth = new DateTime(1953,02,26) }); + + var q = db.From(); + q.SelectDistinct(new[]{ "FirstName" }); + + var results = db.LoadSelect(q, include:q.OnlyFields); + + results.PrintDump(); + Assert.That(results.All(x => x.Id == 0)); + Assert.That(results.Count(x => x.FirstName == "Michael"), Is.EqualTo(1)); + } + + public class FeatureRequest + { + public int Id { get; set; } + public int Up { get; set; } + public int Down { get; set; } + [CustomSelect("up - down")] + public int Points { get; set; } + } + + [Test] + public void Can_select_custom_select_column() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new FeatureRequest {Id = i + 1, Up = (i + 1) * 2, Down = i + 1})); + + var q = db.From() + .Select(new[]{ "id", "up", "down", "points" }); + + var results = db.Select(q); + + results.PrintDump(); + + Assert.That(results.Map(x => x.Points), Is.EqualTo(new[]{ 1, 2, 3 })); + } + + [Test] + public void Can_order_by_custom_select_column() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new FeatureRequest {Id = i + 1, Up = (i + 1) * 2, Down = i + 1})); + + var q = db.From() + .Select(new[]{ "id", "up", "down", "points" }) + .OrderByDescending(x => x.Points); + + var results = db.Select(q); + + results.PrintDump(); + + Assert.That(results.Map(x => x.Points), Is.EqualTo(new[]{ 3, 2, 1 })); + } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/CaptureSqlCommandFilterTests.cs b/tests/ServiceStack.OrmLite.Tests/CaptureSqlCommandFilterTests.cs new file mode 100644 index 000000000..df944f439 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/CaptureSqlCommandFilterTests.cs @@ -0,0 +1,268 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class CaptureSqlCommandFilterTests : OrmLiteProvidersTestBase + { + public CaptureSqlCommandFilterTests(DialectContext context) : base(context) {} + + [Test] + public void Can_capture_command_each_type_of_API() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + db.CreateTable(); + db.Select(x => x.Age > 40); + db.Single(x => x.Age == 42); + db.Count(x => x.Age < 50); + db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse" }); + db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" }); + db.Delete(new { FirstName = "Jimi", Age = 27 }); + db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", + new { age = 50 }); + db.SqlList("exec sp_name @firstName, @age", + new { firstName = "aName", age = 1 }); + db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}" + .SqlFmt(DialectProvider, "WaterHouse", 7)); + + captured.SqlCommandHistory.PrintDump(); + } + + [Test] + public void Can_capture_command_CreateTable_APIs() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + } + + using (var captured = new CaptureSqlFilter()) + using (var db = OpenDbConnection()) + { + int i = 0; + i++; db.CreateTable(); + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Does.Contain("create table person")); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i) + .Or.EqualTo(i + 1)); //Check table if exists + + captured.SqlCommandHistory.PrintDump(); + + } + } + + [Test] + public void Can_capture_command_Select_APIs() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Select(x => x.Age > 40); + + var p = "@0"; //Normalized + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Is.EqualTo("select id, firstname, lastname, age from person where (age > {0})".Fmt(p))); + + i++; db.Select(db.From().Where(x => x.Age > 40)); + i++; db.Select("Age > 40"); + i++; db.Select("SELECT * FROM Person WHERE Age > 40"); + i++; db.Select("Age > @age", new { age = 40 }); + i++; db.Select("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); + i++; db.Select("Age > @age", new Dictionary { { "age", 40 } }); + i++; db.Where("Age", 27); + i++; db.Where(new { Age = 27 }); + i++; db.SelectByIds(new[] { 1, 2, 3 }); + i++; db.SelectByIds(new[] { 1, 2, 3 }); + i++; db.SelectNonDefaults(new Person { Id = 1 }); + i++; db.SelectNonDefaults("Age > @Age", new Person { Age = 40 }); + i++; db.SelectLazy().ToList(); + i++; db.WhereLazy(new { Age = 27 }).ToList(); + i++; db.Select(); + i++; db.Single(x => x.Age == 42); + i++; db.Single(db.From().Where(x => x.Age == 42)); + i++; db.Single(new { Age = 42 }); + i++; db.Single("Age = @age", new { age = 42 }); + i++; db.SingleById(1); + i++; db.SingleWhere("Age", 42); + i++; db.Exists(new { Age = 42 }); + i++; db.Exists("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i)); + + captured.SqlCommandHistory.PrintDump(); + } + + [Test] + public void Can_capture_command_all_Single_Apis() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Single(x => x.Age == 42); + + var p = "@0"; //Normalized + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Is.EqualTo("select id, firstname, lastname, age from person where (age = {0}) limit 1".Fmt(p)). //Sqlite + Or.EqualTo("select top 1 id, firstname, lastname, age from person where (age = {0})".Fmt(p)). //SQLServer < 2012 + Or.EqualTo("select id, firstname, lastname, age from person where (age = {0}) order by 1 offset 0 rows fetch next 1 rows only".Fmt(p)). //SQLServer >= 2012 + Or.EqualTo("select first 1 id, firstname, lastname, age from person where (age = {0})".Fmt(p))); //Firebird + + i++; db.Exists("Age = @age", new { age = 42 }); + i++; db.Single(db.From().Where(x => x.Age == 42)); + i++; db.Single(new { Age = 42 }); + i++; db.Single("Age = @age", new { age = 42 }); + i++; db.SingleById(1); + i++; db.Exists("Age = @age", new { age = 42 }); + i++; db.SingleWhere("Age", 42); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i)); + + captured.SqlCommandHistory.PrintDump(); + } + + [Test] + public void Can_capture_command_all_Scalar_Apis() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Scalar(x => Sql.Max(x.Age)); + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Is.EqualTo("select max(age) from person")); + + i++; db.Scalar(x => Sql.Max(x.Age)); + i++; db.Scalar(x => Sql.Max(x.Age), x => x.Age < 50); + i++; db.Count(x => x.Age < 50); + i++; db.Count(db.From().Where(x => x.Age < 50)); + i++; db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); + + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i)); + + captured.SqlCommandHistory.PrintDump(); + } + + + [Test] + public void Can_capture_command_Update_Apis() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Does.StartWith("update person set firstname=@firstname, lastname=@lastname")); + + i++; db.Update(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + i++; db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + i++; db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); + i++; db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + i++; db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From().Update(p => p.FirstName)); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i)); + + captured.SqlCommandHistory.PrintDump(); + } + + [Test] + public void Can_capture_command_Delete_Apis() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Delete(new { FirstName = "Jimi", Age = 27 }); + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Is.EqualTo("delete from person where firstname=@firstname and age=@age")); + + i++; db.Delete(new { FirstName = "Jimi", Age = 27 }); + i++; db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + i++; db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }); + i++; db.DeleteById(1); + i++; db.DeleteByIds(new[] { 1, 2, 3 }); + i++; db.Delete("Age = @age", new { age = 27 }); + i++; db.Delete(typeof(Person), "Age = @age", new { age = 27 }); + i++; db.Delete(p => p.Age == 27); + i++; db.Delete(db.From().Where(p => p.Age == 27)); + i++; db.Delete("Age = @age", new { age = 27 }); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i)); + + captured.SqlCommandHistory.PrintDump(); + } + + [Test] + public void Can_capture_command_CustomSql_Apis() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Is.EqualTo("select lastname from person where age < @age")); + + i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); + i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + + i++; db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + i++; db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); + + i++; db.SqlList("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 }); + i++; db.SqlScalar("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 }); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i)); + + captured.SqlCommandHistory.PrintDump(); + } + + [Test] + public void Can_capture_command_Insert_Apis() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + + Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(), + Does.StartWith("insert into person (id,firstname,lastname,age) values")); + + i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + i++; db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); + i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); + + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i)); + + captured.SqlCommandHistory.PrintDump(); + } + + [Test] + public void Can_capture_basic_Query() + { + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + db.Where(new { Age = 27 }); + + captured.SqlCommandHistory[0].PrintDump(); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/CaptureSqlFilterTests.cs b/tests/ServiceStack.OrmLite.Tests/CaptureSqlFilterTests.cs index defef31ec..54cb7f49c 100644 --- a/tests/ServiceStack.OrmLite.Tests/CaptureSqlFilterTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/CaptureSqlFilterTests.cs @@ -6,33 +6,32 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class CaptureSqlFilterTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class CaptureSqlFilterTests : OrmLiteProvidersTestBase { + public CaptureSqlFilterTests(DialectContext context) : base(context) {} + [Test] public void Can_capture_each_type_of_API() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - db.CreateTable(); - db.Select(x => x.Age > 40); - db.Single(x => x.Age == 42); - db.Count(x => x.Age < 50); - db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse" }); - db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" }); - db.Delete(new { FirstName = "Jimi", Age = 27 }); - db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", - new { age = 50 }); - db.SqlList("exec sp_name @firstName, @age", - new { firstName = "aName", age = 1 }); - db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}" - .SqlFmt("WaterHouse", 7)); - - var sql = string.Join(";\n\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + db.CreateTable(); + db.Select(x => x.Age > 40); + db.Single(x => x.Age == 42); + db.Count(x => x.Age < 50); + db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse" }); + db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" }); + db.Delete(new { FirstName = "Jimi", Age = 27 }); + db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", + new { age = 50 }); + db.SqlList("exec sp_name @firstName, @age", + new { firstName = "aName", age = 1 }); + db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}" + .SqlFmt(DialectProvider, "WaterHouse", 7)); + + var sql = string.Join(";\n\n", captured.SqlStatements.ToArray()); + sql.Print(); } [Test] @@ -50,9 +49,10 @@ public void Can_capture_CreateTable_APIs() i++; db.CreateTable(); Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.StringStarting("create table person")); + Does.Contain("create table person")); - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i) + .Or.EqualTo(i + 1)); //Check table if exists var sql = string.Join(";\n", captured.SqlStatements.ToArray()); sql.Print(); @@ -62,227 +62,205 @@ public void Can_capture_CreateTable_APIs() [Test] public void Can_capture_Select_APIs() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - int i = 0; - i++; db.Select(x => x.Age > 40); - - Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.EqualTo("select id, firstname, lastname, age from person where (age > 40)")); - - i++; db.Select(q => q.Where(x => x.Age > 40)); - i++; db.Select(db.From().Where(x => x.Age > 40)); - i++; db.Select("Age > 40"); - i++; db.Select("SELECT * FROM Person WHERE Age > 40"); - i++; db.Select("Age > @age", new { age = 40 }); - i++; db.Select("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); - i++; db.Select("Age > @age", new Dictionary { { "age", 40 } }); - i++; db.SelectFmt("Age > {0}", 40); - i++; db.SelectFmt("SELECT * FROM Person WHERE Age > {0}", 40); - i++; db.Where("Age", 27); - i++; db.Where(new { Age = 27 }); - i++; db.SelectByIds(new[] { 1, 2, 3 }); - i++; db.SelectByIds(new[] { 1, 2, 3 }); - i++; db.SelectNonDefaults(new Person { Id = 1 }); - i++; db.SelectNonDefaults("Age > @Age", new Person { Age = 40 }); - i++; db.SelectLazy().ToList(); - i++; db.WhereLazy(new { Age = 27 }).ToList(); - i++; db.Select(); - i++; db.Single(x => x.Age == 42); - i++; db.Single(db.From().Where(x => x.Age == 42)); - i++; db.Single(new { Age = 42 }); - i++; db.Single("Age = @age", new { age = 42 }); - i++; db.SingleById(1); - i++; db.SingleWhere("Age", 42); - i++; db.Exists(new { Age = 42 }); - i++; db.Exists("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); - i++; db.ExistsFmt("Age = {0}", 42); - i++; db.ExistsFmt("SELECT * FROM Person WHERE Age = {0}", 42); - - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); - - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Select(x => x.Age > 40); + + Assert.That(captured.SqlStatements.Last().NormalizeSql(), + Is.EqualTo("select id, firstname, lastname, age from person where (age > 40)"). + Or.EqualTo("select id, firstname, lastname, age from person where (age > @0)")); + + i++; db.Select(db.From().Where(x => x.Age > 40)); + i++; db.Select("Age > 40"); + i++; db.Select("SELECT * FROM Person WHERE Age > 40"); + i++; db.Select("Age > @age", new { age = 40 }); + i++; db.Select("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); + i++; db.Select("Age > @age", new Dictionary { { "age", 40 } }); + i++; db.Where("Age", 27); + i++; db.Where(new { Age = 27 }); + i++; db.SelectByIds(new[] { 1, 2, 3 }); + i++; db.SelectByIds(new[] { 1, 2, 3 }); + i++; db.SelectNonDefaults(new Person { Id = 1 }); + i++; db.SelectNonDefaults("Age > @Age", new Person { Age = 40 }); + i++; db.SelectLazy().ToList(); + i++; db.WhereLazy(new { Age = 27 }).ToList(); + i++; db.Select(); + i++; db.Single(x => x.Age == 42); + i++; db.Single(db.From().Where(x => x.Age == 42)); + i++; db.Single(new { Age = 42 }); + i++; db.Single("Age = @age", new { age = 42 }); + i++; db.SingleById(1); + i++; db.SingleWhere("Age", 42); + i++; db.Exists(new { Age = 42 }); + i++; db.Exists("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); + + Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + + var sql = string.Join(";\n", captured.SqlStatements.ToArray()); + sql.Print(); } [Test] public void Can_capture_all_Single_Apis() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - int i = 0; - i++; db.Single(x => x.Age == 42); - - Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.EqualTo("select id, firstname, lastname, age from person where (age = 42) limit 1"). - Or.EqualTo("select top 1 id, firstname, lastname, age from person where (age = 42)"). - Or.EqualTo("select id, firstname, lastname, age from person where (age = 42) order by 1 offset 0 rows fetch next 1 rows only"). //VistaDB - Or.EqualTo("select * from (\r select ssormlite1.*, rownum rnum from (\r select id, firstname, lastname, age from person where (age = 42) order by person.id) ssormlite1\r where rownum <= 0 + 1) ssormlite2 where ssormlite2.rnum > 0")); //Oracle - - i++; db.ExistsFmt("Age = {0}", 42); - i++; db.Single(db.From().Where(x => x.Age == 42)); - i++; db.Single(new { Age = 42 }); - i++; db.Single("Age = @age", new { age = 42 }); - i++; db.SingleFmt("Age = {0}", 42); - i++; db.SingleById(1); - i++; db.ExistsFmt("Age = {0}", 42); - i++; db.SingleWhere("Age", 42); - - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); - - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Single(x => x.Age == 42); + + var p = "@0"; //Normalized + + Assert.That(captured.SqlStatements.Last().NormalizeSql(), + Is.EqualTo("select id, firstname, lastname, age from person where (age = {0}) limit 1".Fmt(p)). //sqlite + Or.EqualTo("select top 1 id, firstname, lastname, age from person where (age = {0})".Fmt(p)). //SqlServer + Or.EqualTo("select id, firstname, lastname, age from person where (age = {0}) order by 1 offset 0 rows fetch next 1 rows only".Fmt(p)). //SqlServer 2012+ + Or.EqualTo("select first 1 id, firstname, lastname, age from person where (age = {0})".Fmt(p)). //Firebird + Or.EqualTo("select * from (\r select ssormlite1.*, rownum rnum from (\r select id, firstname, lastname, age from person where (age = {0}) order by person.id) ssormlite1\r where rownum <= 0 + 1) ssormlite2 where ssormlite2.rnum > 0".Fmt(p)) //Oracle + ); + + i++; db.Exists("Age = @age", new { age = 42 }); + i++; db.Single(db.From().Where(x => x.Age == 42)); + i++; db.Single(new { Age = 42 }); + i++; db.Single("Age = @age", new { age = 42 }); + i++; db.SingleById(1); + i++; db.Exists("Age = @age", new { age = 42 }); + i++; db.SingleWhere("Age", 42); + + Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + + var sql = string.Join(";\n", captured.SqlStatements.ToArray()); + sql.Print(); } [Test] public void Can_capture_all_Scalar_Apis() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - int i = 0; - i++; db.Scalar(x => Sql.Max(x.Age)); + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Scalar(x => Sql.Max(x.Age)); - Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.EqualTo("select max(age) from person")); + Assert.That(captured.SqlStatements.Last().NormalizeSql(), + Is.EqualTo("select max(age) from person")); - i++; db.Scalar(x => Sql.Max(x.Age)); - i++; db.Scalar(x => Sql.Max(x.Age), x => x.Age < 50); - i++; db.Count(x => x.Age < 50); - i++; db.Count(db.From().Where(x => x.Age < 50)); - i++; db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); - i++; db.ScalarFmt("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); + i++; db.Scalar(x => Sql.Max(x.Age)); + i++; db.Scalar(x => Sql.Max(x.Age), x => x.Age < 50); + i++; db.Count(x => x.Age < 50); + i++; db.Count(db.From().Where(x => x.Age < 50)); + i++; db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); - i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); - i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + var sql = string.Join(";\n", captured.SqlStatements.ToArray()); + sql.Print(); } [Test] public void Can_capture_Update_Apis() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - int i = 0; - i++; db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - - Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.StringStarting("update person set firstname=@firstname, lastname=@lastname")); - - i++; db.Update(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - i++; db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - i++; db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); - i++; db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - i++; db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - i++; db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName); - i++; db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); - i++; db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); - i++; db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - i++; db.UpdateFmt(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - i++; db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); - - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + + Assert.That(captured.SqlStatements.Last().NormalizeSql(), + Does.StartWith("update person set firstname=@firstname, lastname=@lastname")); + + i++; db.Update(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + i++; db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); + i++; db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); + i++; db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + i++; db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From().Update(p => p.FirstName)); + i++; db.UpdateOnlyFields(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + + Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + + var sql = string.Join(";\n", captured.SqlStatements.ToArray()); + sql.Print(); } [Test] public void Can_capture_Delete_Apis() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - int i = 0; - i++; db.Delete(new { FirstName = "Jimi", Age = 27 }); - - Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.EqualTo("delete from person where firstname=@firstname and age=@age")); - - i++; db.Delete(new { FirstName = "Jimi", Age = 27 }); - i++; db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - i++; db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }); - i++; db.DeleteById(1); - i++; db.DeleteByIds(new[] { 1, 2, 3 }); - i++; db.DeleteFmt("Age = {0}", 27); - i++; db.DeleteFmt(typeof(Person), "Age = {0}", 27); - i++; db.Delete(p => p.Age == 27); - i++; db.Delete(ev => ev.Where(p => p.Age == 27)); - i++; db.Delete(db.From().Where(p => p.Age == 27)); - i++; db.DeleteFmt(where: "Age = {0}".SqlFmt(27)); - i++; db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(27)); - - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); - - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Delete(new { FirstName = "Jimi", Age = 27 }); + + Assert.That(captured.SqlStatements.Last().NormalizeSql(), + Is.EqualTo("delete from person where firstname=@firstname and age=@age")); + + i++; db.Delete(new { FirstName = "Jimi", Age = 27 }); + i++; db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); + i++; db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }); + i++; db.DeleteById(1); + i++; db.DeleteByIds(new[] { 1, 2, 3 }); + i++; db.Delete("Age = @age", new { age = 27 }); + i++; db.Delete(typeof(Person), "Age = @age", new { age = 27 }); + i++; db.Delete(p => p.Age == 27); + i++; db.Delete(db.From().Where(p => p.Age == 27)); + + Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + + var sql = string.Join(";\n", captured.SqlStatements.ToArray()); + sql.Print(); } [Test] public void Can_capture_CustomSql_Apis() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - int i = 0; - i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.EqualTo("select lastname from person where age < @age")); + Assert.That(captured.SqlStatements.Last().NormalizeSql(), + Is.EqualTo("select lastname from person where age < @age")); - i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); - i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); - i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); + i++; db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); + i++; db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - i++; db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7)); - i++; db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); + i++; db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + i++; db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); - i++; db.SqlList("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 }); - i++; db.SqlScalar("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 }); + i++; db.SqlList("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 }); + i++; db.SqlScalar("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 }); - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + var sql = string.Join(";\n", captured.SqlStatements.ToArray()); + sql.Print(); } [Test] public void Can_capture_Insert_Apis() { - using (var captured = new CaptureSqlFilter()) - using (var db = OpenDbConnection()) - { - int i = 0; - i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + using var captured = new CaptureSqlFilter(); + using var db = OpenDbConnection(); + int i = 0; + i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(captured.SqlStatements.Last().NormalizeSql(), - Is.StringStarting("insert into person (id,firstname,lastname,age) values")); + Assert.That(captured.SqlStatements.Last().NormalizeSql(), + Does.Contain("insert into person (id,firstname,lastname,age) values")); - i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - i++; db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); - i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => ev.Insert(p => new { p.FirstName, p.Age })); - i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => db.From().Insert(p => new { p.FirstName, p.Age })); + i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); + i++; db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); + i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); - Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); + Assert.That(captured.SqlStatements.Count, Is.EqualTo(i)); - var sql = string.Join(";\n", captured.SqlStatements.ToArray()); - sql.Print(); - } + var sql = string.Join(";\n", captured.SqlStatements.ToArray()); + sql.Print(); } } diff --git a/tests/ServiceStack.OrmLite.Tests/CheckConstraintTests.cs b/tests/ServiceStack.OrmLite.Tests/CheckConstraintTests.cs new file mode 100644 index 000000000..f13a499b5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/CheckConstraintTests.cs @@ -0,0 +1,68 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public class CheckConstraintTest + { + [AutoIncrement] + public int Id { get; set; } + + [Required] + [CheckConstraint("Age > 1")] + public int Age { get; set; } + + [CheckConstraint("Name IS NOT NULL")] + public string Name { get; set; } + } + + [TestFixtureOrmLite] + public class CheckConstraintTests : OrmLiteProvidersTestBase + { + public CheckConstraintTests(DialectContext context) : base(context) {} + + [Test] + [IgnoreDialect(Dialect.MySql, new[]{ MySqlDb.V5_5, MySqlDb.V10_1 }, "Check constraints supported from MariaDb 10.2.1 onwards")] + public void Does_create_table_with_CheckConstraints() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.GetLastSql().Print(); + + try + { + db.Insert(new CheckConstraintTest { Age = 1 }); + Assert.Fail("Should fail"); + } + catch (Exception ex) + { + Assert.That(ex.Message.ToLower(), Does.Contain("age")); + Assert.That(ex.Message.ToLower(), Does.Contain("constraint")); + } + + try + { + db.Insert(new CheckConstraintTest { Age = 2 }); + Assert.Fail("Should fail"); + } + catch (Exception ex) + { + ex.Message.Print(); + Assert.That(ex.Message.ToLower(), Does.Contain("name")); + Assert.That(ex.Message.ToLower(), Does.Contain("constraint")); + } + } + + [Test] + public void Can_insert_record_passing_check_constraints() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new CheckConstraintTest { Age = 2, Name = "foo" }); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/CompositeKeyTests.cs b/tests/ServiceStack.OrmLite.Tests/CompositeKeyTests.cs index a14c616ab..375f231f9 100644 --- a/tests/ServiceStack.OrmLite.Tests/CompositeKeyTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/CompositeKeyTests.cs @@ -4,36 +4,34 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class CompositeKeyTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class CompositeKeyTests : OrmLiteProvidersTestBase { + public CompositeKeyTests(DialectContext context) : base(context) {} + const long SubId1Value = 1; const long SubId2Value = 1; [Test] public void Can_select_single_from_empty_composite_key_table() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - var result = db.Single(ck => ck.SubId1 == SubId1Value && ck.SubId2 == SubId2Value); - Assert.That(result, Is.Null); - } + var result = db.Single(ck => ck.SubId1 == SubId1Value && ck.SubId2 == SubId2Value); + Assert.That(result, Is.Null); } [Test] public void Can_select_single_from_composite_key_table_with_one_matching_row() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - InsertData(db, 1); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + InsertData(db, 1); - var result = db.Single(ck => ck.SubId1 == SubId1Value && ck.SubId2 == SubId2Value); - Assert.That(result.SubId1, Is.EqualTo(SubId1Value)); - Assert.That(result.SubId2, Is.EqualTo(SubId2Value)); - } + var result = db.Single(ck => ck.SubId1 == SubId1Value && ck.SubId2 == SubId2Value); + Assert.That(result.SubId1, Is.EqualTo(SubId1Value)); + Assert.That(result.SubId2, Is.EqualTo(SubId2Value)); } private void InsertData(IDbConnection db, int count) @@ -48,15 +46,13 @@ private void InsertData(IDbConnection db, int count) [Test] public void Can_select_single_from_composite_key_table_with_several_matching_rows() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - InsertData(db, 4); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + InsertData(db, 4); - var result = db.Single(ck => ck.SubId1 == SubId1Value && ck.SubId2 == SubId2Value); - Assert.That(result.SubId1, Is.EqualTo(SubId1Value)); - Assert.That(result.SubId2, Is.EqualTo(SubId2Value)); - } + var result = db.Single(ck => ck.SubId1 == SubId1Value && ck.SubId2 == SubId2Value); + Assert.That(result.SubId1, Is.EqualTo(SubId1Value)); + Assert.That(result.SubId2, Is.EqualTo(SubId2Value)); } public class CompositeKey diff --git a/tests/ServiceStack.OrmLite.Tests/ConflictResolutionTests.cs b/tests/ServiceStack.OrmLite.Tests/ConflictResolutionTests.cs new file mode 100644 index 000000000..62d97e4c3 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/ConflictResolutionTests.cs @@ -0,0 +1,83 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class ConflictResolutionTests : OrmLiteProvidersTestBase + { + public ConflictResolutionTests(DialectContext context) : base(context) {} + + [Test] + public void Can_change_conflict_resolution_with_Insert() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var row = new ModelWithIdAndName(1); + db.Insert(row, dbCmd => dbCmd.OnConflictIgnore()); + + //Equivalent to: + db.Insert(row, dbCmd => dbCmd.OnConflict(ConflictResolution.Ignore)); + } + + [Test] + public async Task Can_change_conflict_resolution_with_Insert_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + + var row = new ModelWithIdAndName(1); + await db.InsertAsync(row, dbCmd => dbCmd.OnConflictIgnore()); + + //Equivalent to: + await db.InsertAsync(row, dbCmd => dbCmd.OnConflict(ConflictResolution.Ignore)); + } + + [Test] + public void Can_change_conflict_resolution_with_Insert_AutoIncrement() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var row = new ModelWithIdAndName(1); + var insertId = db.Insert(row, dbCmd => dbCmd.OnConflictIgnore(), selectIdentity: true); + Assert.That(insertId, Is.GreaterThan(0)); + } + + [Test] + public async Task Can_change_conflict_resolution_with_Insert_AutoIncrement_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + + var row = new ModelWithIdAndName(1); + var insertId = await db.InsertAsync(row, dbCmd => dbCmd.OnConflictIgnore(), selectIdentity: true); + Assert.That(insertId, Is.GreaterThan(0)); + } + + [Test] + public void Can_change_conflict_resolution_with_InsertAll() + { + using var db = OpenDbConnection(); + var rows = 5.Times(i => new ModelWithIdAndName(i)); + + db.DropAndCreateTable(); + + db.InsertAll(rows, dbCmd => dbCmd.OnConflictIgnore()); + } + + [Test] + public async Task Can_change_conflict_resolution_with_InsertAll_Async() + { + OrmLiteUtils.PrintSql(); + using var db = await OpenDbConnectionAsync(); + var rows = 5.Times(i => new ModelWithIdAndName(i)); + + db.DropAndCreateTable(); + + await db.InsertAllAsync(rows, dbCmd => dbCmd.OnConflictIgnore()); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ConverterTests.cs b/tests/ServiceStack.OrmLite.Tests/ConverterTests.cs new file mode 100644 index 000000000..c6d1f6e82 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/ConverterTests.cs @@ -0,0 +1,365 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Globalization; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class ConverterTests : OrmLiteProvidersTestBase + { + public ConverterTests(DialectContext context) : base(context) {} + + private struct TestStruct {} + + [Test] + public void FromDbValue_does_not_throw_Exception() + { + var dialectProvider = DialectProvider; + var convertedValue = dialectProvider.FromDbValue(12345, typeof(TestStruct)); + Assert.That(convertedValue, Is.Null); + } + + [Test] + public void ToDbValue_does_not_throw_Exception() + { + var dialectProvider = DialectProvider; + var convertedValue = dialectProvider.ToDbValue (89.123456789, typeof(decimal)); + Assert.AreEqual(convertedValue, 89.123456789); + } + + [Test] + public void ToQuotedString_FloatConverter_not_throw_Exception() + { + var floatConverter = new FloatConverter(); + floatConverter.ToQuotedString(typeof(decimal), 89.123456789); + floatConverter.ToQuotedString(typeof(float), 89.123456789); + floatConverter.ToQuotedString(typeof(double), 89.123456789); + } + + [Test] + public void ToQuotedString_LegacyFloatConverter_throw_Exception() + { + Assert.Catch(typeof(InvalidCastException), () => + { + var floatConverter = new LegacyFloatConverter(); + floatConverter.ToQuotedString(typeof(decimal), 89.123456789); + floatConverter.ToQuotedString(typeof(float), 89.123456789); + floatConverter.ToQuotedString(typeof(double), 89.123456789); + }); + } + + [Test] + public void Can_insert_update_and_select_AllTypes() + { + using var db = OpenDbConnection(); + if (Dialect == Dialect.Firebird) //Exceeds row limit + DialectProvider.GetStringConverter().MaxColumnDefinition = "VARCHAR(4000)"; + + db.DropAndCreateTable(); + db.GetLastSql().Print(); + + var rows = 3.Times(i => AllTypes.Create(i)); + + db.InsertAll(rows); + + var lastRow = rows.Last(); + + var dbRow = db.SingleById(lastRow.Id); + + Assert.That(dbRow, Is.EqualTo(lastRow)); + + Assert.That(db.Single(x => x.NullableId == lastRow.NullableId), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.Byte == lastRow.Byte), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.Short == lastRow.Short), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.Int == lastRow.Int), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.Long == lastRow.Long), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.UShort == lastRow.UShort), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.UInt == lastRow.UInt), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.ULong == lastRow.ULong), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.Decimal == lastRow.Decimal), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.String == lastRow.String), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.DateTime == lastRow.DateTime), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.TimeSpan == lastRow.TimeSpan), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.DateTimeOffset == lastRow.DateTimeOffset), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.Guid == lastRow.Guid), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.Char == lastRow.Char), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.NullableDateTime == lastRow.NullableDateTime), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.NullableTimeSpan == lastRow.NullableTimeSpan), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.CustomText == lastRow.CustomText), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.MaxText == lastRow.MaxText), Is.EqualTo(lastRow)); + Assert.That(db.Single(x => x.CustomDecimal == lastRow.CustomDecimal), Is.EqualTo(lastRow)); + + Assert.That(db.Single(db.From().Where(x => x.Bool == lastRow.Bool).OrderByDescending(x => x.Id)), Is.EqualTo(lastRow)); + + var updatedRows = 3.Times(i => + { + var updated = AllTypes.Create(i + 3); + updated.Id = i + 1; + db.Update(updated); + return updated; + }); + + var lastUpdatedRow = updatedRows.Last(); + var dbUpdatedRow = db.SingleById(lastUpdatedRow.Id); + Assert.That(dbUpdatedRow, Is.EqualTo(lastUpdatedRow)); + + if (Dialect == Dialect.Firebird) + DialectProvider.GetStringConverter().MaxColumnDefinition = null; + } + } + + public class AllTypes + { + public int Id { get; set; } + public int? NullableId { get; set; } + public byte Byte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public float Float { get; set; } + public double Double { get; set; } + public decimal Decimal { get; set; } + public string String { get; set; } + public DateTime DateTime { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTimeOffset DateTimeOffset { get; set; } + public Guid Guid { get; set; } + public bool Bool { get; set; } + public char Char { get; set; } + public DateTime? NullableDateTime { get; set; } + public TimeSpan? NullableTimeSpan { get; set; } + public byte[] ByteArray { get; set; } + public char[] CharArray { get; set; } + public int[] IntArray { get; set; } + public long[] LongArray { get; set; } + public string[] StringArray { get; set; } + public List StringList { get; set; } + public Dictionary StringMap { get; set; } + public Dictionary IntStringMap { get; set; } + public SubType SubType { get; set; } + public List SubTypes { get; set; } + + [StringLength(100)] + public string CustomText { get; set; } + + [StringLength(StringLengthAttribute.MaxText)] + public string MaxText { get; set; } + + [DecimalLength(10,2)] + public decimal CustomDecimal { get; set; } + + protected bool Equals(AllTypes other) + { + return Id == other.Id && + NullableId == other.NullableId && + Byte == other.Byte && + Short == other.Short && + Int == other.Int && + Long == other.Long && + UShort == other.UShort && + UInt == other.UInt && + ULong == other.ULong && + Float.Equals(other.Float) && + Double.Equals(other.Double) && + Decimal == other.Decimal && + string.Equals(String, other.String) && + DateTime.Equals(other.DateTime) && + TimeSpan.Equals(other.TimeSpan) && + DateTimeOffset.Equals(other.DateTimeOffset) && + Guid.Equals(other.Guid) && + Bool == other.Bool && + Char == other.Char && + NullableDateTime.Equals(other.NullableDateTime) && + NullableTimeSpan.Equals(other.NullableTimeSpan) && + ByteArray.SequenceEqual(other.ByteArray) && + CharArray.SequenceEqual(other.CharArray) && + IntArray.SequenceEqual(other.IntArray) && + LongArray.SequenceEqual(other.LongArray) && + StringArray.SequenceEqual(other.StringArray) && + StringList.SequenceEqual(other.StringList) && + StringMap.SequenceEqual(other.StringMap) && + IntStringMap.SequenceEqual(other.IntStringMap) && + SubType.Equals(other.SubType) && + SubTypes.SequenceEqual(other.SubTypes) && + CustomText == other.CustomText && + MaxText == other.MaxText && + CustomDecimal.Equals(other.CustomDecimal); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((AllTypes)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Id; + hashCode = (hashCode * 397) ^ NullableId.GetHashCode(); + hashCode = (hashCode * 397) ^ Byte.GetHashCode(); + hashCode = (hashCode * 397) ^ Short.GetHashCode(); + hashCode = (hashCode * 397) ^ Int; + hashCode = (hashCode * 397) ^ Long.GetHashCode(); + hashCode = (hashCode * 397) ^ UShort.GetHashCode(); + hashCode = (hashCode * 397) ^ (int)UInt; + hashCode = (hashCode * 397) ^ ULong.GetHashCode(); + hashCode = (hashCode * 397) ^ Float.GetHashCode(); + hashCode = (hashCode * 397) ^ Double.GetHashCode(); + hashCode = (hashCode * 397) ^ Decimal.GetHashCode(); + hashCode = (hashCode * 397) ^ (String != null ? String.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ DateTime.GetHashCode(); + hashCode = (hashCode * 397) ^ TimeSpan.GetHashCode(); + hashCode = (hashCode * 397) ^ DateTimeOffset.GetHashCode(); + hashCode = (hashCode * 397) ^ Guid.GetHashCode(); + hashCode = (hashCode * 397) ^ Bool.GetHashCode(); + hashCode = (hashCode * 397) ^ Char.GetHashCode(); + hashCode = (hashCode * 397) ^ NullableDateTime.GetHashCode(); + hashCode = (hashCode * 397) ^ NullableTimeSpan.GetHashCode(); + hashCode = (hashCode * 397) ^ (ByteArray != null ? ByteArray.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (CharArray != null ? CharArray.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (StringArray != null ? StringArray.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (IntArray != null ? IntArray.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LongArray != null ? LongArray.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (StringList != null ? StringList.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (StringMap != null ? StringMap.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (IntStringMap != null ? IntStringMap.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (SubType != null ? SubType.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (SubTypes != null ? SubTypes.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (CustomText != null ? CustomText.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (MaxText != null ? MaxText.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ CustomDecimal.GetHashCode(); + return hashCode; + } + } + + public static AllTypes Create(int i) + { + return new AllTypes + { + Id = i + 1, + NullableId = i + 2, + Byte = (byte)(i + 3), + Short = (short)(i + 4), + Int = i + 5, + Long = i + 6, + UShort = (ushort)(i + 7), + UInt = (uint)(i + 8), + ULong = (ulong)(i + 9), + Float = (float)(i + 10.1), + Double = i + 11.5, + Decimal = (decimal)(i + 12.1), + String = "String" + i, + DateTime = new DateTime(2000 + i, (i + 1) % 12, (i + 1) % 28), + TimeSpan = new TimeSpan(i, i, i, i, i), + DateTimeOffset = new DateTimeOffset(new DateTime(2000 + i, (i + 1) % 12, (i + 1) % 28)), + Guid = Guid.NewGuid(), + Bool = i % 2 == 0, + Char = (char)(i + 65), //TODO: NPGSQL fails on \0 + NullableDateTime = new DateTime(2000 + i, (i + 1) % 12, (i + 1) % 28), + NullableTimeSpan = new TimeSpan(i, i, i, i, i), + ByteArray = new[] { (byte)i, (byte)(i + 1) }, + CharArray = new[] { (char)('A' + i), (char)('A' + i + 1) }, //TODO: NPGSQL fails on \u0001 + IntArray = new[] { i, i + 1 }, + LongArray = new[] { (long)i, i + 1 }, + StringArray = new[] { i.ToString() }, + StringList = new List { i.ToString() }, + StringMap = new Dictionary { { "Key" + i, "Value" + i } }, + IntStringMap = new Dictionary { { i, "Value" + i } }, + SubType = new SubType + { + Id = i, + Name = "Name" + i, + }, + SubTypes = new List + { + new SubType + { + Id = i, + Name = "Name" + i, + }, + new SubType + { + Id = i + 1, + Name = "Name" + i + 1, + }, + }, + CustomText = "CustomText" + i, + MaxText = "MaxText" + i, + CustomDecimal = i + 13.13M, + }; + } + } + + public class SubType + { + public int Id { get; set; } + public string Name { get; set; } + + protected bool Equals(SubType other) + { + return Id == other.Id && string.Equals(Name, (string)other.Name); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((SubType)obj); + } + + public override int GetHashCode() + { + unchecked + { + return (Id * 397) ^ (Name != null ? Name.GetHashCode() : 0); + } + } + } + + //A copy of the original implementation code + internal class LegacyFloatConverter : NativeValueOrmLiteConverter + { + public override string ColumnDefinition => "DOUBLE"; + public override DbType DbType => DbType.Single; + + public override object ToDbValue(Type fieldType, object value) + { + return this.ConvertNumber(fieldType, value); + } + + public override object FromDbValue(Type fieldType, object value) + { + return this.ConvertNumber(fieldType, value); + } + + public override string ToQuotedString(Type fieldType, object value) + { + var typeCode = fieldType.GetTypeCode(); + switch (typeCode) + { + case TypeCode.Single: + return ((float)value).ToString(CultureInfo.InvariantCulture); + case TypeCode.Double: + return ((double)value).ToString(CultureInfo.InvariantCulture); + case TypeCode.Decimal: + return ((decimal)value).ToString(CultureInfo.InvariantCulture); + } + + return base.ToQuotedString(fieldType, value); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/CustomConverterTests.cs b/tests/ServiceStack.OrmLite.Tests/CustomConverterTests.cs new file mode 100644 index 000000000..faea01167 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/CustomConverterTests.cs @@ -0,0 +1,53 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServer.Converters; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public class PocoWithTime + { + [AutoIncrement] + public int Id { get; set; } + + public TimeSpan TimeSpan { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class CustomConverterTests : OrmLiteProvidersTestBase + { + public CustomConverterTests(DialectContext context) : base(context) {} + + [Test] + public void Can_override_SqlServer_Time_Converter() + { + using var db = OpenDbConnection(); + var hold = DialectProvider.GetConverter(); + DialectProvider.RegisterConverter( + new SqlServerTimeConverter()); + + db.DropAndCreateTable(); + + var sql = db.GetLastSql(); + Assert.That(sql, Does.Contain("\"TimeSpan\" TIME NOT NULL")); + sql.Print(); + + //SQL Server can't do < 1 day and only 3ms precision + var oneTime = new TimeSpan(0, 1, 1, 1, 3); + + db.Insert(new PocoWithTime { TimeSpan = oneTime }); + + Assert.That(db.Single(x => x.TimeSpan == oneTime).TimeSpan, + Is.EqualTo(oneTime).Within(TimeSpan.FromSeconds(1))); + + sql = db.GetLastSql(); + sql.Print(); + + Assert.That(sql, Does.Contain("\"TimeSpan\" = '01:01:01.0030000'"). + Or.Contain("\"TimeSpan\" = CAST(@0 AS TIME))")); + + DialectProvider.RegisterConverter(hold); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/CustomSelectTests.cs b/tests/ServiceStack.OrmLite.Tests/CustomSelectTests.cs new file mode 100644 index 000000000..5d649ad25 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/CustomSelectTests.cs @@ -0,0 +1,41 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests +{ + public class CustomSelectModel + { + [PrimaryKey] + public Guid DeviceId { get; set; } + + [CustomSelect("NULL")] + public Guid SiteId { get; set; } + + [CustomSelect("NULL")] + public Guid GroupId { get; set; } + } + + public class CustomSelectTests : OrmLiteTestBase + { + [Test] + public void Does_IgnoreOnInsert() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var row = new CustomSelectModel + { + DeviceId = Guid.NewGuid(), + GroupId = Guid.NewGuid(), + SiteId = Guid.NewGuid(), + }; + + db.Insert(row); + + db.Update(row); + + db.Save(row); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/CustomSqlExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/CustomSqlExpressionTests.cs new file mode 100644 index 000000000..f082d8bd1 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/CustomSqlExpressionTests.cs @@ -0,0 +1,849 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Sqlite; + + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLiteDialects(Dialect.Sqlite)] + public class CustomSqlExpressionTests : OrmLiteProvidersTestBase + { + public CustomSqlExpressionTests(DialectContext context) : base(context) + { + // override the default sqlite provider and dbfactory with the custom one + var customSqlServerDialectProvider = new CustomSqlServerDialectProvider(); + DialectProvider = customSqlServerDialectProvider; + DbFactory = new OrmLiteConnectionFactory(SqliteDb.MemoryConnection, customSqlServerDialectProvider, false); + } + + [SetUp] + public void Setup() + { + using var db = OpenDbConnection(); + db.DropTable(); + + db.CreateTable(); + db.Insert(new WaybillBase + { + Id = 1, + Number = 100, + Name = "first", + Id1 = Guid.Parse("11111111-1111-1111-1111-111111111111"), + Id2 = Guid.Parse("51111111-1111-1111-1111-111111111111"), + Date = DateTime.Parse("2001-01-01"), + Amount = 20M + }); + db.Insert(new WaybillBase + { + Id = 2, + Number = 200, + Name = "second", + Id1 = Guid.Parse("22222222-2222-2222-2222-222222222222"), + Id2 = Guid.Parse("52222222-2222-2222-2222-222222222222"), + Date = DateTime.Parse("2002-01-01"), + Amount = 30M + }); + db.Insert(new WaybillBase + { + Id = 3, + Number = 300, + Name = "third", + Id1 = Guid.Parse("33333333-3333-3333-3333-333333333333"), + Id2 = Guid.Parse("53333333-3333-3333-3333-333333333333"), + Date = DateTime.Parse("2003-01-01"), + Amount = 40M + }); + + db.DropTable(); + + db.CreateTable(); + db.Insert(new SeparateWaybillIn { Id = 1, DateBegin = DateTime.Parse("2014-01-01"), DateEnd = DateTime.Parse("2014-01-03"), Note = "firstNote"}); + db.Insert(new SeparateWaybillIn { Id = 2, DateBegin = DateTime.Parse("2015-01-01"), DateEnd = DateTime.Parse("2015-01-03"), Note = "secondNote" }); + db.Insert(new SeparateWaybillIn { Id = 3, DateBegin = DateTime.Parse("2016-01-01"), DateEnd = DateTime.Parse("2016-01-03"), Note = "thirdNote" }); + } + + [Test] + public void Can_Where_using_constant_filter1() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty == "WaybillVirtPropertyValue"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter2() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty == "Any"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter3() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty != "WaybillVirtPropertyValue"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter4() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty != "Any"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter5() + { + using var db = OpenDbConnection(); + Expression> filter = x => + x.VirtProperty == "WaybillVirtPropertyValue" || x.VirtProperty2 == "WaybillVirtPropertyValue2"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter6() + { + using var db = OpenDbConnection(); + Expression> filter = x => + x.VirtProperty == "WaybillVirtPropertyValue" && x.VirtProperty2 == "WaybillVirtPropertyValue2"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter7() + { + using var db = OpenDbConnection(); + Expression> filter = x => + x.VirtProperty == "WaybillVirtPropertyValue" || x.VirtProperty2 == "Any"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter8() + { + using var db = OpenDbConnection(); + Expression> filter = x => + x.VirtProperty == "WaybillVirtPropertyValue" && x.VirtProperty2 == "Any"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter9() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.BoolVirtProperty; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter10() + { + using var db = OpenDbConnection(); + Expression> filter = x => !x.BoolVirtProperty; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter11() + { + using var db = OpenDbConnection(); + Expression> filter = x => + x.BoolVirtProperty && x.VirtProperty == "WaybillVirtPropertyValue"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter12() + { + using var db = OpenDbConnection(); + Expression> filter = x => + !x.BoolVirtProperty || x.VirtProperty == "WaybillVirtPropertyValue"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter13() + { + using var db = OpenDbConnection(); + Expression> filter = x => !x.BoolVirtProperty && + x.VirtProperty == "WaybillVirtPropertyValue" && + x.Number == 100; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(1, target.Count); + } + + [Test] + public void Can_Where_using_constant_filter14() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.Number == 100 && + (x.BoolVirtProperty || + x.VirtProperty == "WaybillVirtPropertyValue"); + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(1, target.Count); + } + + [Test] + public void Can_Select_hierarchy_classes1() + { + using var db = OpenDbConnection(); + var q1 = db.From(); + q1.PrefixFieldWithTableName = true; + q1.Select(x => new {x.Name, x.Number}); + q1.SelectInto(QueryType.Select); + var sql1 = q1.SelectExpression; + + var q2 = db.From(); + q2.PrefixFieldWithTableName = true; + q2.Select(x => new {x.Name, x.Number}); + q2.SelectInto(QueryType.Select); + var sql2 = q2.SelectExpression; + + Assert.AreEqual(sql1, sql2); + } + + [Test] + public void Can_Select_hierarchy_classes2() + { + using var db = OpenDbConnection(); + var q = db.From(); + q.PrefixFieldWithTableName = true; + q.Join((x, y) => x.Id == y.Id); + q.Where(x => x.Name == "first" && x.Note == "firstNote"); + var target = db.Select(q); + + Assert.AreEqual(1, target.Count); + + var obj = target[0]; + Assert.AreEqual(DateTime.Parse("2014-01-01"), obj.DateBegin); + } + + [Test] + public void Can_Select_hierarchy_classes3() + { + using var db = OpenDbConnection(); + var q = db.From(); + q.PrefixFieldWithTableName = true; + q.Join((x, y) => x.Id == y.Id); + q.Where(x => x.Name == "first" && x.Note == "firstNote"); + q.Select(new[] {nameof(WaybillBase.Number)}); + var target = db.Column(q); + + Assert.AreEqual(1, target.Count); + + var obj = target[0]; + Assert.AreEqual(100, obj); + } + + [Test] + public void Can_Select_hierarchy_classes4() + { + using var db = OpenDbConnection(); + var q = db.From(); + q.PrefixFieldWithTableName = true; + q.Join((x, y) => x.Id == y.Id); + q.Where(x => x.Name == "first" && x.Note == "firstNote"); + q.OrderByFields(nameof(WaybillBase.Number)); + var target = db.Select(q); + + Assert.AreEqual(1, target.Count); + + var obj = target[0]; + Assert.AreEqual(DateTime.Parse("2014-01-01"), obj.DateBegin); + } + + [Test] + public void Can_Where_using_constant_orderBy1() + { + using var db = OpenDbConnection(); + Expression> filter = x => !x.BoolVirtProperty; + Expression> orderBy = x => x.BoolVirtProperty; + var q = db.From().Where(filter).OrderBy(orderBy); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_constant_orderBy2() + { + using var db = OpenDbConnection(); + Expression> filter = x => !x.BoolVirtProperty && + x.VirtPropertyEmpty != "WaybillVirtPropertyValue" && + x.Number == 100; + Expression> orderBy = x => x.VirtPropertyEmpty; + var q = db.From().Where(filter).OrderBy(orderBy); + var target = db.Select(q); + Assert.AreEqual(1, target.Count); + } + + [Test] + public void Can_Where_using_constant_conditionalOrderBy() + { + using var db = OpenDbConnection(); + Expression> filter = x => !x.BoolVirtProperty && + x.VirtPropertyEmpty != "WaybillVirtPropertyValue" && + x.Number == 100; + Expression> orderBy = x => x.Number > 0 ? x.VirtPropertyEmpty : x.Name; + var q = db.From().Where(filter).OrderBy(orderBy); + var target = db.Select(q); + Assert.AreEqual(1, target.Count); + } + + [Test] + public void Can_Where_using_constant_func_where() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty.StartsWith("Way"); + Expression> orderBy = x => x.Name; + var q = db.From().Where(filter).OrderByDescending(orderBy); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Select_using_constant() + { + using var db = OpenDbConnection(); + Expression> filter = x => !x.BoolVirtProperty && + x.VirtPropertyEmpty != "WaybillVirtPropertyValue" && + x.Number == 100; + + Expression> select = x => x.VirtProperty; + var q = db.From().Where(filter).Select(@select); + var target = db.Column(q); + Assert.AreEqual(1, target.Count); + Assert.AreEqual("WaybillVirtPropertyValue", target[0]); + } + + [Test] + public void Can_Where_using_guid_constant_conditional() + { + using var db = OpenDbConnection(); + Expression> filter = x => + (x.Number > 0 ? x.GuidVirtProperty : x.Id1) == Guid.Parse("00000000-0000-0000-0000-000000000000"); + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_null_constant_conditional() + { + using var db = OpenDbConnection(); + Expression> filter = x => + (x.Number == 0 ? x.VirtPropertyNull : x.Name) == "first"; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(1, target.Count); + } + + [Test] + public void Can_Where_using_datetime_constant_conditional() + { + using var db = OpenDbConnection(); + Expression> filter = x => + (x.Number > 0 ? x.DateVirtProperty : x.Date) == DateTime.Parse("2000-01-01"); + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_int_constant_conditional() + { + using var db = OpenDbConnection(); + Expression> filter = x => (x.Number > 0 ? x.IntVirtProperty : x.Number) == 5; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_decimal_constant_conditional() + { + using var db = OpenDbConnection(); + Expression> filter = x => + (x.Number > 0 ? x.DecimalVirtProperty : x.Amount) == 10M; + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_GroupBy_using_constant() + { + using var db = OpenDbConnection(); + Expression> filter = x => + (x.Number > 0 ? x.DecimalVirtProperty : x.Amount) == 10M; + var q = db.From() + .Where(filter) + .GroupBy(x => x.VirtPropertyEmpty); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Having_using_constant() + { + using var db = OpenDbConnection(); + OrmLiteUtils.PrintSql(); + Expression> filter = x => + (x.Number > 0 ? x.DecimalVirtProperty : x.Amount) == 10M; + var q = db.From().Where(filter).Select(x => x.Name) + .GroupBy(x => x.Name) + .Having(x => x.VirtProperty == "WaybillVirtPropertyValue"); + var target = db.Column(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty1() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty.Length == 0; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty2() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty.Length == 24; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty3() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty.Length == 0 && x.Id > 0; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty4() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtPropertyNull.Length == 0; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty5() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtPropertyNull.Length == 0 && x.Id > 0; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty6() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.BoolVirtProperty != null; //should be always true + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where null")); + + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty7() + { + using var db = OpenDbConnection(); + Expression> filter = x => null != x.BoolVirtProperty; //should be always true + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where null")); + + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty8() + { + using var db = OpenDbConnection(); + Expression> filter = x => null != x.BoolVirtProperty && x.Id > 0; + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where null")); + + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty9() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.BoolVirtProperty == null; //should be always false + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where not (null)")); + + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty10() + { + using var db = OpenDbConnection(); + Expression> filter = x => null == x.BoolVirtProperty; //should be always false + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where not (null)")); + + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty11() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.NullableTrueBoolVirtProperty == null; + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where null")); + + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty12() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.NullableTrueBoolVirtProperty != null; + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where not (null)")); + + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty13() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.NullableNullBoolVirtProperty == null; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty14() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.NullableNullBoolVirtProperty != null; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty15() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.NullableNullBoolVirtProperty == true; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty16() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.BoolVirtProperty != false; + + var q = db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("where null")); + + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty17() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtPropertyNull == null; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty18() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtPropertyNull != null; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty19() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtPropertyNull == "null"; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty20() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty == null; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Where_using_StringLengthVirtualProperty21() + { + using var db = OpenDbConnection(); + Expression> filter = x => x.VirtProperty == "WaybillVirtPropertyValue"; + + var q = db.From().Where(filter); + var target = db.Select(q); + Assert.AreEqual(3, target.Count); + } + } + + public class ObjectBase + { + [PrimaryKey] + public int Id { get; set; } + } + + public class WaybillBase : ObjectBase + { + public int Number { get; set; } + + public string Name { get; set; } + + public Guid Id1 { get; set; } + + public Guid Id2 { get; set; } + + public DateTime Date { get; set; } + + public decimal Amount { get; set; } + + [DataAnnotations.Ignore] + public string VirtProperty => "WaybillVirtPropertyValue"; + + [DataAnnotations.Ignore] + public string VirtProperty2 => "WaybillVirtPropertyValue2"; + + [DataAnnotations.Ignore] + public string VirtPropertyEmpty => String.Empty; + + [DataAnnotations.Ignore] + public string VirtPropertyNull => null; + + [DataAnnotations.Ignore] + public bool BoolVirtProperty => false; + + [DataAnnotations.Ignore] + public bool? NullableTrueBoolVirtProperty => true; + + [DataAnnotations.Ignore] + public bool? NullableNullBoolVirtProperty => null; + + [DataAnnotations.Ignore] + public Guid GuidVirtProperty => Guid.Parse("00000000-0000-0000-0000-000000000000"); + + [DataAnnotations.Ignore] + public DateTime DateVirtProperty => DateTime.Parse("2000-01-01"); + + [DataAnnotations.Ignore] + public int IntVirtProperty => 5; + + [DataAnnotations.Ignore] + public decimal DecimalVirtProperty => 10M; + } + + public class WaybillIn : WaybillBase + { + public DateTime DateBegin { get; set; } + + public DateTime DateEnd { get; set; } + + public string Note { get; set; } + } + + /// + /// Class only for creating the table and population it with data. + /// + [Alias(nameof(WaybillIn))] + public class SeparateWaybillIn + { + public int Id { get; set; } + + public DateTime DateBegin { get; set; } + + public DateTime DateEnd { get; set; } + + public string Note { get; set; } + } + + public class CustomSqlServerDialectProvider : SqliteOrmLiteDialectProvider + { + public override SqlExpression SqlExpression() + { + return new CustomSqlExpression(this); + } + } + + public class CustomSqlExpression : SqliteExpression + { + public CustomSqlExpression(IOrmLiteDialectProvider dialectProvider) : base(dialectProvider) + { + } + + protected override Object GetMemberExpression(MemberExpression m) + { + if (m.Member.DeclaringType == typeof(WaybillBase)) + { + if (m.Member.Name == nameof(WaybillBase.VirtProperty)) + return "WaybillVirtPropertyValue"; + if (m.Member.Name == nameof(WaybillBase.VirtProperty2)) + return "WaybillVirtPropertyValue2"; + if (m.Member.Name == nameof(WaybillBase.VirtPropertyEmpty)) + return String.Empty; + if (m.Member.Name == nameof(WaybillBase.VirtPropertyNull)) + return null; + if (m.Member.Name == nameof(WaybillBase.BoolVirtProperty)) + return false; + if (m.Member.Name == nameof(WaybillBase.NullableTrueBoolVirtProperty)) + return true; + if (m.Member.Name == nameof(WaybillBase.NullableNullBoolVirtProperty)) + return null; + if (m.Member.Name == nameof(WaybillBase.GuidVirtProperty)) + return Guid.Parse("00000000-0000-0000-0000-000000000000"); + if (m.Member.Name == nameof(WaybillBase.DateVirtProperty)) + return DateTime.Parse("2000-01-01"); + if (m.Member.Name == nameof(WaybillBase.IntVirtProperty)) + return 5; + if (m.Member.Name == nameof(WaybillBase.DecimalVirtProperty)) + return 10M; + } + + return base.GetMemberExpression(m); + } + + protected override string GetQuotedColumnName(ModelDefinition tableDef, string memberName) + { + if (useFieldName) + { + var actualTableDefForMember = GetCurrentTableDef(tableDef, memberName); + if (tableDef.ModelName != actualTableDefForMember.ModelName) + { + CreateHierarchyJoin(actualTableDefForMember, tableDef); + } + + return base.GetQuotedColumnName(actualTableDefForMember, memberName); + } + + return base.GetQuotedColumnName(tableDef, memberName); + } + + protected virtual void CreateHierarchyJoin(ModelDefinition actualHierarchyTableDef, ModelDefinition mainHierarchyTableDef) + { + } + + private ModelDefinition GetCurrentTableDef(ModelDefinition tableDef, string memberName) + { + var curType = tableDef.ModelType; + var nonInheritedProperties = GetCurrentPropertiesWithoutBase(tableDef); + while (curType != null && !nonInheritedProperties.Contains(memberName)) + { + curType = curType.BaseType; + nonInheritedProperties = GetCurrentPropertiesWithoutBase(curType?.GetModelMetadata()); + } + + return curType?.GetModelMetadata() ?? tableDef; + } + + protected virtual List GetCurrentPropertiesWithoutBase(ModelDefinition currentModelDef) + { + if (currentModelDef == null) return null; + + var baseType = currentModelDef.ModelType; + var res = new List { currentModelDef.PrimaryKey.Name }; + + res.AddRange(baseType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Select(a => a.Name)); + + return res; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/CustomSqlTests.cs b/tests/ServiceStack.OrmLite.Tests/CustomSqlTests.cs index 6819d467a..d70031a00 100644 --- a/tests/ServiceStack.OrmLite.Tests/CustomSqlTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/CustomSqlTests.cs @@ -1,6 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.Expression; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests @@ -14,6 +17,12 @@ public class PocoTable [CustomField("DECIMAL(18,4)")] public decimal? DecimalColumn { get; set; } + + [CustomField(OrmLiteVariables.MaxText)] //= {MAX_TEXT} + public string MaxText { get; set; } + + [CustomField(OrmLiteVariables.MaxTextUnicode)] //= {NMAX_TEXT} + public string MaxUnicodeText { get; set; } } [PreCreateTable("CREATE INDEX udxNoTable on NonExistingTable (Name);")] @@ -35,6 +44,16 @@ public class ModelWithSeedDataSql public string Name { get; set; } } + [PostCreateTable("INSERT INTO ModelWithSeedDataSqlMulti (Name) VALUES ('Foo')"), + PostCreateTable("INSERT INTO ModelWithSeedDataSqlMulti (Name) VALUES ('Bar')")] + public class ModelWithSeedDataSqlMulti + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + } + public class DynamicAttributeSeedData { [AutoIncrement] @@ -61,114 +80,212 @@ public class ModelWithPostDropSql public string Name { get; set; } } - [TestFixture] - public class CustomSqlTests - : OrmLiteTestBase + [PreDropTable("-- PreDropTable")] + [PostDropTable("-- PostDropTable")] + [PreCreateTable("-- PreCreateTable")] + [PostCreateTable("-- PostCreateTable")] + public class ModelWithPreAndPostDrop { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + } + + [TestFixtureOrmLite] + public class CustomSqlTests : OrmLiteProvidersTestBase + { + public CustomSqlTests(DialectContext context) : base(context) {} + [Test] public void Can_create_field_with_custom_sql() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + OrmLiteConfig.BeforeExecFilter = cmd => cmd.GetDebugString().Print(); + + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - var createTableSql = db.GetLastSql().NormalizeSql(); + var createTableSql = db.GetLastSql().NormalizeSql(); - createTableSql.Print(); + createTableSql.Print(); - Assert.That(createTableSql, Is.StringContaining("charcolumn char(20) null")); - Assert.That(createTableSql, Is.StringContaining("decimalcolumn decimal(18,4) null")); + if (Dialect != Dialect.Firebird) + { + Assert.That(createTableSql, Does.Contain("charcolumn char(20) null")); + Assert.That(createTableSql, Does.Contain("decimalcolumn decimal(18,4) null")); + } + else + { + Assert.That(createTableSql, Does.Contain("charcolumn char(20)")); + Assert.That(createTableSql, Does.Contain("decimalcolumn decimal(18,4)")); } } [Test] public void Does_execute_CustomSql_before_table_created() { - using (var db = OpenDbConnection()) + using var db = OpenDbConnection(); + try { - try - { - db.CreateTable(); - Assert.Fail("Should throw"); - } - catch (Exception) - { - Assert.That(!db.TableExists("ModelWithPreCreateSql".SqlColumn())); - } + db.CreateTable(); + Assert.Fail("Should throw"); + } + catch (Exception) + { + Assert.That(!db.TableExists("ModelWithPreCreateSql".SqlColumn(DialectProvider))); } } [Test] + [IgnoreDialect(Dialect.AnyOracle | Dialect.AnyPostgreSql, "multiple SQL statements need to be wrapped in an anonymous block")] public void Does_execute_CustomSql_after_table_created() { - SuppressIfOracle("For Oracle need wrap multiple SQL statements in an anonymous block"); - if (Dialect == Dialect.PostgreSql || Dialect == Dialect.Oracle) return; + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + var seedDataNames = db.Select().ConvertAll(x => x.Name); - var seedDataNames = db.Select().ConvertAll(x => x.Name); + Assert.That(seedDataNames, Is.EquivalentTo(new[] {"Foo", "Bar"})); + } - Assert.That(seedDataNames, Is.EquivalentTo(new[] { "Foo", "Bar" })); - } + [Test] + [IgnoreDialect(Dialect.AnyOracle | Dialect.AnyPostgreSql, "multiple SQL statements need to be wrapped in an anonymous block")] + public void Does_execute_multi_CustomSql_after_table_created() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var seedDataNames = db.Select().ConvertAll(x => x.Name); + + Assert.That(seedDataNames, Is.EquivalentTo(new[] {"Foo", "Bar"})); } [Test] + [IgnoreDialect(Dialect.AnyOracle | Dialect.AnyPostgreSql, "multiple SQL statements need to be wrapped in an anonymous block")] public void Does_execute_CustomSql_after_table_created_using_dynamic_attribute() { - SuppressIfOracle("For Oracle need wrap multiple SQL statements in an anonymous block"); - typeof(DynamicAttributeSeedData) .AddAttributes(new PostCreateTableAttribute( - "INSERT INTO {0} (Name) VALUES ('Foo');".Fmt("DynamicAttributeSeedData".SqlTable()) + - "INSERT INTO {0} (Name) VALUES ('Bar');".Fmt("DynamicAttributeSeedData".SqlTable()))); + "INSERT INTO {0} (Name) VALUES ('Foo');".Fmt("DynamicAttributeSeedData".SqlTable(DialectProvider)) + + "INSERT INTO {0} (Name) VALUES ('Bar');".Fmt("DynamicAttributeSeedData".SqlTable(DialectProvider)))); - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - var seedDataNames = db.Select().ConvertAll(x => x.Name); + var seedDataNames = db.Select().ConvertAll(x => x.Name); - Assert.That(seedDataNames, Is.EquivalentTo(new[] { "Foo", "Bar" })); - } + Assert.That(seedDataNames, Is.EquivalentTo(new[] {"Foo", "Bar"})); + } + + [Test] + public void Does_execute_PostCreateTable_and_PreDropTable() + { + OrmLiteUtils.PrintSql(); + using var db = OpenDbConnection(); + db.CreateTable(true); } [Test] public void Does_execute_CustomSql_before_table_dropped() { - using (var db = OpenDbConnection()) + using var db = OpenDbConnection(); + db.CreateTable(); + try { - db.CreateTable(); - try - { - db.DropTable(); - Assert.Fail("Should throw"); - } - catch (Exception) - { - Assert.That(db.TableExists("ModelWithPreDropSql".SqlTableRaw())); - } + db.DropTable(); + Assert.Fail("Should throw"); + } + catch (Exception) + { + Assert.That(db.TableExists("ModelWithPreDropSql".SqlTableRaw(DialectProvider))); } } [Test] public void Does_execute_CustomSql_after_table_dropped() { - using (var db = OpenDbConnection()) + using var db = OpenDbConnection(); + db.CreateTable(); + try { - db.CreateTable(); - try - { - db.DropTable(); - Assert.Fail("Should throw"); - } - catch (Exception) - { - Assert.That(!db.TableExists("ModelWithPostDropSql")); - } + db.DropTable(); + Assert.Fail("Should throw"); + } + catch (Exception) + { + Assert.That(!db.TableExists("ModelWithPostDropSql")); } } + public class CustomSelectTest + { + public int Id { get; set; } + public int Width { get; set; } + public int Height { get; set; } + + [CustomSelect("Width * Height")] + public int Area { get; set; } + } + + [Test] + public void Can_select_custom_field_expressions() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new CustomSelectTest {Id = 1, Width = 10, Height = 5}); + + var row = db.SingleById(1); + + Assert.That(row.Area, Is.EqualTo(10 * 5)); + } + + [Test] + public void Can_Count_Distinct() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency {Letter = x}); + + db.InsertAll(rows); + + var count = db.Count(db.From().Select(x => x.Letter)); + Assert.That(count, Is.EqualTo(rows.Count)); + + count = db.Scalar(db.From().Select(x => Sql.Count(x.Letter))); + Assert.That(count, Is.EqualTo(rows.Count)); + + var distinctCount = db.Scalar(db.From().Select(x => Sql.CountDistinct(x.Letter))); + Assert.That(distinctCount, Is.EqualTo(rows.Map(x => x.Letter).Distinct().Count())); + + distinctCount = db.Scalar(db.From().Select("COUNT(DISTINCT Letter)")); + Assert.That(distinctCount, Is.EqualTo(rows.Map(x => x.Letter).Distinct().Count())); + } + + [Test] + public void Does_select_aliases_on_constant_expressions() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Insert(new LetterFrequency { Letter = "A" }); + + var q = db.From() + .Select(x => new + { + param = 1, + descr = x.Letter, + str = "hi", + date = DateTime.UtcNow + }); + + var results = db.Select>(q)[0]; + + Assert.That(results["param"], Is.EqualTo(1)); + Assert.That(results["descr"], Is.EqualTo("A")); + Assert.That(results["str"], Is.EqualTo("hi")); + Assert.That(results["date"], Is.Not.Empty); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/DateTimeOffsetTests.cs b/tests/ServiceStack.OrmLite.Tests/DateTimeOffsetTests.cs index 93acc1f32..62afd2d1b 100644 --- a/tests/ServiceStack.OrmLite.Tests/DateTimeOffsetTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/DateTimeOffsetTests.cs @@ -6,17 +6,20 @@ namespace ServiceStack.OrmLite.Tests { - public class DateTimeOffsetTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class DateTimeOffsetTests : OrmLiteProvidersTestBase { + public DateTimeOffsetTests(DialectContext context) : base(context) {} + private IDbConnection db; - [TestFixtureSetUp] - public new void TestFixtureSetUp() + [OneTimeSetUp] + public void TestFixtureSetUp() { db = base.OpenDbConnection(); } - [TestFixtureTearDown] + [OneTimeTearDown] public void TestFixtureTearDown() { db.Dispose(); @@ -118,5 +121,54 @@ public void CanPersistAndRetrieveNullableDateTimeOffset() Assert.That(actual.HasValue); Assert.That(actual.Value.Date, Is.EqualTo(now.Date)); } + + [TestCase("2012-08-12 -08:00")] + [TestCase("2012-08-12 0:10:35 +12:00")] + [TestCase("2012-08-12 23:10:35.288546 -08:00")] + public void CanQueryDateTimeOffsetWithWhereExpression(string startTimeString) + { + var time = DateTimeOffset.Parse(startTimeString); + db.DropAndCreateTable(); + db.Insert(new NullableDateTimeOffsetWithStartAndEndTime { Id = 1, StartTime = time.AddHours(-1), EndTime = time }); + var expression = db.From() + .Where(p => p.StartTime == null || p.StartTime < time); + + var result = db.LoadSelect(expression).FirstOrDefault(); + var diff = time - result.EndTime; + + //MySql doesn't support ms, SqlServer has +/- .03 precision + Assert.That(diff.Value, + Is.LessThan(TimeSpan.FromSeconds(1)). + Or.GreaterThanOrEqualTo(TimeSpan.FromSeconds(0))); + } + + [TestCase("2012-08-12")] + [TestCase("2012-08-12 0:10:35")] + [TestCase("2012-08-12 23:10:35.288546")] + public void CanQueryDateTimeWithWhereExpression(string startTimeString) + { + var time = DateTime.Parse(startTimeString); + db.DropAndCreateTable(); + db.Insert(new NullableDateTimeWithStartAndEndTime { Id = 1, StartTime = time.AddHours(-1), EndTime = time }); + var expression = db.From() + .Where(p => p.StartTime == null || p.StartTime < time); + + var result = db.LoadSelect(expression).First(); + Assert.That(result.EndTime, Is.EqualTo(time).Within(TimeSpan.FromSeconds(1))); + } + + public class NullableDateTimeOffsetWithStartAndEndTime + { + public int Id { get; set; } + public DateTimeOffset? StartTime { get; set; } + public DateTimeOffset? EndTime { get; set; } + } + + public class NullableDateTimeWithStartAndEndTime + { + public int Id { get; set; } + public DateTime? StartTime { get; set; } + public DateTime? EndTime { get; set; } + } } -} \ No newline at end of file +} diff --git a/tests/ServiceStack.OrmLite.Tests/DateTimeTests.cs b/tests/ServiceStack.OrmLite.Tests/DateTimeTests.cs new file mode 100644 index 000000000..43e0f1f72 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/DateTimeTests.cs @@ -0,0 +1,232 @@ +using System; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + [NonParallelizable] + public class DateTimeTests : OrmLiteProvidersTestBase + { + public DateTimeTests(DialectContext context) : base(context) {} + + [Test] + public void Can_insert_and_query_with_Unspecified_DateStyle() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + DateTime dateTime; + DateTimeObject x; + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Local); + x = InsertAndSelectDateTime(db, dateTime); + Assert.AreEqual(x.Test, dateTime); + Assert.AreEqual(x.Test, x.TestNullable.Value); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.IsNotNull(x); + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Utc); + x = InsertAndSelectDateTime(db, dateTime); + Assert.AreEqual(x.Test, dateTime); + Assert.AreEqual(x.Test, x.TestNullable.Value); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.IsNotNull(x); + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Unspecified); + x = InsertAndSelectDateTime(db, dateTime); + Assert.AreEqual(x.Test, dateTime); + Assert.AreEqual(x.Test, x.TestNullable.Value); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.IsNotNull(x); + } + + [Test] + public void Does_return_Local_Dates_with_Local_DateStyle() + { + using var db = OpenDbConnection(); + var dialectProvider = DialectProvider; + var hold = dialectProvider.GetDateTimeConverter().DateStyle; + dialectProvider.GetDateTimeConverter().DateStyle = DateTimeKind.Local; + + db.DropAndCreateTable(); + + DateTime dateTime; + DateTimeObject x; + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Local); + x = InsertAndSelectDateTime(db, dateTime); + Assert.AreEqual(DateTimeKind.Local, x.Test.Kind); + Assert.AreEqual(DateTimeKind.Local, x.TestNullable.Value.Kind); + Assert.AreEqual(x.Test, x.TestNullable.Value); + Assert.AreEqual(x.Test.ToUniversalTime(), dateTime.ToUniversalTime()); + Assert.AreEqual(x.Test.ToLocalTime(), dateTime.ToLocalTime()); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.IsNotNull(x); + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Utc); + x = InsertAndSelectDateTime(db, dateTime); + Assert.AreEqual(DateTimeKind.Local, x.Test.Kind); + Assert.AreEqual(DateTimeKind.Local, x.TestNullable.Value.Kind); + Assert.AreEqual(x.Test, x.TestNullable.Value); + Assert.AreEqual(x.Test.ToUniversalTime(), dateTime.ToUniversalTime()); + Assert.AreEqual(x.Test.ToLocalTime(), dateTime.ToLocalTime()); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.IsNotNull(x); + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Unspecified); + x = InsertAndSelectDateTime(db, dateTime); + Assert.AreEqual(DateTimeKind.Local, x.Test.Kind); + Assert.AreEqual(DateTimeKind.Local, x.TestNullable.Value.Kind); + Assert.AreEqual(x.Test, x.TestNullable.Value); + Assert.AreEqual(x.Test.ToUniversalTime(), dateTime); + Assert.AreEqual(x.Test.ToLocalTime(), dateTime.ToLocalTime()); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + db.GetLastSql().Print(); + Assert.IsNotNull(x); + + dialectProvider.GetDateTimeConverter().DateStyle = hold; + } + + [Test] + public void Does_return_UTC_Dates_with_UTC_DateStyle() + { + using var db = OpenDbConnection(); + var dialectProvider = DialectProvider; + var hold = dialectProvider.GetDateTimeConverter().DateStyle; + dialectProvider.GetDateTimeConverter().DateStyle = DateTimeKind.Utc; + + db.DropAndCreateTable(); + + DateTime dateTime; + DateTimeObject x; + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Local); + x = InsertAndSelectDateTime(db, dateTime); + Assert.That(x.Test.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(x.TestNullable.Value.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(x.Test, Is.EqualTo(x.TestNullable.Value)); + Assert.That(x.Test.ToUniversalTime(), Is.EqualTo(dateTime.ToUniversalTime())); + Assert.That(x.Test.ToLocalTime(), Is.EqualTo(dateTime.ToLocalTime())); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.That(x, Is.Not.Null); + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Utc); + x = InsertAndSelectDateTime(db, dateTime); + Assert.That(x.Test.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(x.TestNullable.Value.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(x.Test, Is.EqualTo(x.TestNullable.Value)); + Assert.That(x.Test.ToUniversalTime(), Is.EqualTo(dateTime.ToUniversalTime())); + Assert.That(x.Test.ToLocalTime(), Is.EqualTo(dateTime.ToLocalTime())); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.That(x, Is.Not.Null); + + dateTime = new DateTime(2012, 1, 1, 1, 1, 1, DateTimeKind.Unspecified); + x = InsertAndSelectDateTime(db, dateTime); + Assert.That(x.Test.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(x.TestNullable.Value.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(x.Test, Is.EqualTo(x.TestNullable.Value)); + Assert.That(x.Test.ToUniversalTime(), Is.EqualTo(dateTime)); + Assert.That(x.Test.ToLocalTime(), Is.EqualTo(dateTime.ToLocalTime())); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.That(x, Is.Not.Null); + + dialectProvider.GetDateTimeConverter().DateStyle = hold; + } + + [Test] + public void Log_dialect_behavior() + { + Dialect.ToString().Print(); + + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var dateStyles = new[] { DateTimeKind.Local, DateTimeKind.Utc, DateTimeKind.Unspecified }; + + foreach (var dateStyle in dateStyles) + { + db.DeleteAll(); + + var dateTime = new DateTime(2012, 1, 1, 1, 1, 1, dateStyle); + + "#1 IN: {0} ({1}), UTC: {2}, Local: {3}".Print( + dateTime.Kind, + dateTime, + dateTime.ToUniversalTime(), + dateTime.ToLocalTime()); + + using (var cmd = db.OpenCommand()) + { + cmd.CommandText = "INSERT INTO {0} VALUES({1}, {2})" + .Fmt(nameof(DateTimeObject).SqlTable(DialectProvider), + DialectProvider.GetParam("p1"), + DialectProvider.GetParam("p2")); + + cmd.Parameters.Add(cmd.CreateParam("p1", dateTime)); + cmd.Parameters.Add(cmd.CreateParam("p2", dateTime)); + + cmd.ExecuteNonQuery(); + } + + using (var cmd = db.OpenCommand()) + { + cmd.CommandText = "SELECT * FROM {0}".Fmt(nameof(DateTimeObject).SqlTable(DialectProvider)); + + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + var dbDateTime = reader.GetDateTime(0); + "#1 IN: {0} ({1}), OUT: {2} ({3})".Print( + dateTime.Kind, + dateTime, + dbDateTime.Kind, + dbDateTime); + } + } + } + } + } + + [Test] + public void Can_Select_Date_with_SqlList() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var dateTime = new DateTime(2001, 1, 1, 1, 1, 1); + db.DeleteAll(); + db.Insert(new DateTimeObject { Test = dateTime, TestNullable = dateTime }); + + var row = db.SqlList( + "SELECT * FROM {0} WHERE Test = @dateTime".Fmt("DateTimeObject".SqlTable(DialectProvider)), new { dateTime }); + Assert.That(dateTime, Is.EqualTo(row[0].Test)); + + row = db.SqlList( + "SELECT * FROM {0} WHERE {1} = @dateTime".Fmt("DateTimeObject".SqlTable(DialectProvider), "TestNullable".SqlColumn(DialectProvider)), new { dateTime }); + Assert.That(dateTime, Is.EqualTo(row[0].TestNullable)); + + DateTime? nullableDate = dateTime; + row = db.SqlList( + "SELECT * FROM {0} WHERE {1} = @nullableDate".Fmt("DateTimeObject".SqlTable(DialectProvider), "TestNullable".SqlColumn(DialectProvider)), new { nullableDate }); + Assert.That(dateTime, Is.EqualTo(row[0].TestNullable)); + } + + private static DateTimeObject InsertAndSelectDateTime(IDbConnection db, DateTime dateTime) + { + db.DeleteAll(); + db.Insert(new DateTimeObject { Test = dateTime, TestNullable = dateTime }); + var x = db.Select().First(); + return x; + } + + private class DateTimeObject + { + public DateTime Test { get; set; } + public DateTime? TestNullable { get; set; } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/DbExtensionTests.cs b/tests/ServiceStack.OrmLite.Tests/DbExtensionTests.cs new file mode 100644 index 000000000..585d8c86e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/DbExtensionTests.cs @@ -0,0 +1,32 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Issues; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class DbExtensionTests : OrmLiteProvidersTestBase + { + public DbExtensionTests(DialectContext context) : base(context) {} + + [Test] + public void Can_get_TableName() + { + using var db = OpenDbConnection(); + var table1 = db.GetTableName(); + var quotedTable1 = db.GetQuotedTableName(); + + Assert.That(table1.ToLower(), Is.EqualTo("table1")); + Assert.That(quotedTable1.ToLower(), Is.EqualTo("\"table1\"").Or.EqualTo("`table1`")); + + if (Dialect == Dialect.Sqlite) + { + var tableSchema = db.GetTableName(); + var quotedTableSchema = db.GetQuotedTableName(); + + Assert.That(tableSchema, Is.EqualTo("Schema_ModelWithSchema")); + Assert.That(quotedTableSchema, Is.EqualTo("\"Schema_ModelWithSchema\"")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/DbScriptTests.cs b/tests/ServiceStack.OrmLite.Tests/DbScriptTests.cs new file mode 100644 index 000000000..0200a4b9f --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/DbScriptTests.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.Script; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class DbScriptTests : OrmLiteProvidersTestBase + { + public DbScriptTests(DialectContext context) : base(context) {} + + [Test] + public async Task Can_retrieve_single_record_with_param() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedRockstars); + + var args = new Dictionary {{"id", 3}}; + var tableName = "Rockstar".SqlTable(DialectProvider); + var result = db.Single($"SELECT * FROM {tableName} WHERE Id = @id", args); + Assert.That(result.FirstName, Is.EqualTo("Kurt")); + + result = await db.SingleAsync($"SELECT * FROM {tableName} WHERE Id = @id", args); + Assert.That(result.FirstName, Is.EqualTo("Kurt")); + + result = await db.SingleAsync($"SELECT * FROM {tableName} WHERE Id = @id", new { id = 3 }); + Assert.That(result.FirstName, Is.EqualTo("Kurt")); + } + + [Test] + public async Task Can_call_dbSingle_with_param() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedRockstars); + + var firstName = "FirstName".SqlColumn(DialectProvider).StripDbQuotes(); + + var args = new Dictionary { { "id", 3 }}; + + var filter = new DbScripts { DbFactory = base.DbFactory }; + + var result = filter.dbSingle(default, $"SELECT * FROM Rockstar WHERE Id = @id", args); + + var objDictionary = (Dictionary)result; + Assert.That(objDictionary[firstName], Is.EqualTo("Kurt")); + + var asyncFilter = new DbScriptsAsync { DbFactory = base.DbFactory }; + result = await asyncFilter.dbSingle(default, $"SELECT * FROM Rockstar WHERE Id = @id", args); + + objDictionary = (Dictionary)result; + Assert.That(objDictionary[firstName], Is.EqualTo("Kurt")); + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/DefaultValueTests.cs b/tests/ServiceStack.OrmLite.Tests/DefaultValueTests.cs new file mode 100644 index 000000000..02835a2f6 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/DefaultValueTests.cs @@ -0,0 +1,654 @@ +using System; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.Models; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + [IgnoreDialect(Dialect.MySql, MySqlDb.V5_5, "You cannot set the default for a date column to be the value of a function such as NOW() or CURRENT_DATE. The exception is that you can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP column")] + public class DefaultValueTests : OrmLiteProvidersTestBase + { + public DefaultValueTests(DialectContext context) : base(context) {} + + [Test] + public void Can_create_table_with_DefaultValues() + { + using var db = OpenDbConnection(); + var row = CreateAndInitialize(db); + + var expectedDate = !Dialect.HasFlag(Dialect.Firebird) + ? DateTime.UtcNow.Date + : DateTime.Now.Date; + + Assert.That(row.CreatedDateUtc, Is.GreaterThan(expectedDate)); + Assert.That(row.NCreatedDateUtc, Is.GreaterThan(expectedDate)); + } + + private DefaultValues CreateAndInitialize(IDbConnection db, int count = 1) + { + db.DropAndCreateTable(); + db.GetLastSql().Print(); + + DefaultValues firstRow = null; + for (var i = 1; i <= count; i++) + { + var defaultValues = new DefaultValues { Id = i }; + db.Insert(defaultValues); + + var row = db.SingleById(1); + row.PrintDump(); + Assert.That(row.DefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultIntNoDefault, Is.EqualTo(0)); + Assert.That(row.NDefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.NDefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.DefaultString, Is.EqualTo("String")); + + if (firstRow == null) + firstRow = row; + } + + return firstRow; + } + + [Test] + public void Can_use_ToUpdateStatement_to_generate_inline_SQL() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db); + + var row = db.SingleById(1); + row.DefaultIntNoDefault = 42; + + var sql = db.ToUpdateStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + row = db.SingleById(1); + + Assert.That(row.DefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultIntNoDefault, Is.EqualTo(42)); + Assert.That(row.NDefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.NDefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.DefaultString, Is.EqualTo("String")); + } + + [Test] + public void Can_filter_update_method1_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db, 2); + + ResetUpdateDate(db); + db.Update(cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider), + new DefaultValues { Id = 1, DefaultInt = 45, CreatedDateUtc = DateTime.Now }, + new DefaultValues { Id = 2, DefaultInt = 72, CreatedDateUtc = DateTime.Now }); + VerifyUpdateDate(db); + VerifyUpdateDate(db, id: 2); + } + + private static void ResetUpdateDate(IDbConnection db) + { + var updateTime = new DateTime(2011, 1, 1, 1, 1, 1, DateTimeKind.Utc); + db.Update(new { UpdatedDateUtc = updateTime }, p => p.Id == 1); + } + + private void VerifyUpdateDate(IDbConnection db, int id = 1) + { + var row = db.SingleById(id); + row.PrintDump(); + + if (!Dialect.HasFlag(Dialect.AnyMySql)) //not returning UTC + Assert.That(row.UpdatedDateUtc, Is.GreaterThan(DateTime.UtcNow - TimeSpan.FromMinutes(5))); + } + + [Test] + public void Can_filter_update_method2_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.Update(new DefaultValues { Id = 1, DefaultInt = 2342, CreatedDateUtc = DateTime.Now }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + + [Test] + public void Can_filter_update_method3_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultInt = 3245; + row.DefaultDouble = 978.423; + db.Update(row, cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + + [Test] + public void Can_filter_update_method4_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.Update(new { DefaultInt = 765 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + + [Test] + public void Can_filter_updateAll_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db, 2); + + ResetUpdateDate(db); + db.UpdateAll(new [] { new DefaultValues { Id = 1, DefaultInt = 45, CreatedDateUtc = DateTime.Now }, + new DefaultValues { Id = 2, DefaultInt = 72, CreatedDateUtc = DateTime.Now } }, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + VerifyUpdateDate(db, id: 2); + } + + [Test] + public void Can_filter_updateOnly_method1_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.UpdateOnly(() => new DefaultValues {DefaultInt = 345}, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + + [Test] + public void Can_filter_updateOnly_method2_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.UpdateOnly(() => new DefaultValues { DefaultInt = 345 }, db.From().Where(p => p.Id == 1), + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + + [Test] + public void Can_filter_updateOnly_method3_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultDouble = 978.423; + db.UpdateOnlyFields(row, db.From().Update(p => p.DefaultDouble), + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + + [Test] + public void Can_filter_updateOnly_method4_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultDouble = 978.423; + db.UpdateOnlyFields(row, p => p.DefaultDouble, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateOnly_method5_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultDouble = 978.423; + db.UpdateOnlyFields(row, new[] { nameof(DefaultValues.DefaultDouble) }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateAdd_expression_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + + var count = db.UpdateAdd(() => new DefaultValues { DefaultInt = 5, DefaultDouble = 7.2 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + + Assert.That(count, Is.EqualTo(1)); + var row = db.SingleById(1); + Assert.That(row.DefaultInt, Is.EqualTo(6)); + Assert.That(row.DefaultDouble, Is.EqualTo(8.3).Within(0.1)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateAdd_SqlExpression_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + + var where = db.From().Where(p => p.Id == 1); + var count = db.UpdateAdd(() => new DefaultValues { DefaultInt = 5, DefaultDouble = 7.2 }, where, + cmd => cmd.SetUpdateDate(nameof(DefaultValues.UpdatedDateUtc), DialectProvider)); + + Assert.That(count, Is.EqualTo(1)); + var row = db.SingleById(1); + Assert.That(row.DefaultInt, Is.EqualTo(6)); + Assert.That(row.DefaultDouble, Is.EqualTo(8.3).Within(0.1)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Does_use_defaults_for_missing_values() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithDefaults { DefaultInt = 10 }); + + var row = db.Select().FirstOrDefault(); + + Assert.That(row.Id, Is.GreaterThan(0)); + Assert.That(row.DefaultInt, Is.EqualTo(10)); + Assert.That(row.DefaultString, Is.EqualTo("String")); + } + } + + [Test] + public void Does_only_use_defaults_for_all_default_properties() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertUsingDefaults( + new ModelWithDefaults { Name = "foo", DefaultInt = 10 }, + new ModelWithDefaults { Name = "bar", DefaultString = "qux" }); + + var rows = db.Select(); + rows.PrintDump(); + + Assert.That(rows.All(x => x.Id > 0)); + Assert.That(rows.All(x => x.DefaultInt == 1)); + Assert.That(rows.All(x => x.DefaultString == "String")); + } + } + } + + /// + /// MySql 5.5 only allows a single timestamp default column + /// + [TestFixtureOrmLiteDialects(Dialect.MySql, MySqlDb.V5_5)] + public class MySqlDefaultValueTests : OrmLiteProvidersTestBase + { + public MySqlDefaultValueTests(DialectContext context) : base(context) {} + + [Test] + public void Can_create_table_with_DefaultValues() + { + using (var db = OpenDbConnection()) + { + var row = CreateAndInitialize(db); + + var expectedDate = DateTime.Now.Date; //MySql CURRENT_TIMESTAMP == LOCAL_TIME + + Assert.That(row.UpdatedDateUtc, Is.GreaterThan(expectedDate)); + } + } + + private MySqlDefaultValues CreateAndInitialize(IDbConnection db, int count = 1) + { + db.DropAndCreateTable(); + db.GetLastSql().Print(); + + MySqlDefaultValues firstRow = null; + for (var i = 1; i <= count; i++) + { + var defaultValues = new MySqlDefaultValues { Id = i }; + db.Insert(defaultValues); + + var row = db.SingleById(1); + row.PrintDump(); + Assert.That(row.DefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultIntNoDefault, Is.EqualTo(0)); + Assert.That(row.NDefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.NDefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.DefaultString, Is.EqualTo("String")); + + if (firstRow == null) + firstRow = row; + } + + return firstRow; + } + + [Test] + public void Can_use_ToUpdateStatement_to_generate_inline_SQL() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + var row = db.SingleById(1); + row.DefaultIntNoDefault = 42; + + var sql = db.ToUpdateStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + row = db.SingleById(1); + + Assert.That(row.DefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultIntNoDefault, Is.EqualTo(42)); + Assert.That(row.NDefaultInt, Is.EqualTo(1)); + Assert.That(row.DefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.NDefaultDouble, Is.EqualTo(1.1).Within(.1d)); + Assert.That(row.DefaultString, Is.EqualTo("String")); + } + } + + [Test] + public void Can_filter_update_method1_to_insert_date() + { + using var db = OpenDbConnection(); + CreateAndInitialize(db, 2); + + ResetUpdateDate(db); + db.Update(cmd => + cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider), + new MySqlDefaultValues { Id = 1, DefaultInt = 45 }, + new MySqlDefaultValues { Id = 2, DefaultInt = 72 }); + VerifyUpdateDate(db); + VerifyUpdateDate(db, id: 2); + } + + private static void ResetUpdateDate(IDbConnection db) + { + var updateTime = new DateTime(2011, 1, 1, 1, 1, 1, DateTimeKind.Utc); + db.Update(new { UpdatedDateUtc = updateTime }, p => p.Id == 1); + } + + private void VerifyUpdateDate(IDbConnection db, int id = 1) + { + var row = db.SingleById(id); + row.PrintDump(); + + if (!Dialect.HasFlag(Dialect.AnyMySql)) //not returning UTC + Assert.That(row.UpdatedDateUtc, Is.GreaterThan(DateTime.UtcNow - TimeSpan.FromMinutes(5))); + } + + [Test] + public void Can_filter_update_method2_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.Update(new MySqlDefaultValues { Id = 1, DefaultInt = 2342 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_update_method3_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultInt = 3245; + row.DefaultDouble = 978.423; + db.Update(row, cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_update_method4_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.Update(new { DefaultInt = 765 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateAll_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db, 2); + + ResetUpdateDate(db); + db.UpdateAll(new [] { new MySqlDefaultValues { Id = 1, DefaultInt = 45 }, + new MySqlDefaultValues { Id = 2, DefaultInt = 72 } }, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + VerifyUpdateDate(db, id: 2); + } + } + + [Test] + public void Can_filter_updateOnly_method1_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.UpdateOnly(() => new MySqlDefaultValues {DefaultInt = 345}, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateOnly_method2_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + db.UpdateOnly(() => new MySqlDefaultValues { DefaultInt = 345 }, db.From().Where(p => p.Id == 1), + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateOnly_method3_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultDouble = 978.423; + db.UpdateOnlyFields(row, db.From().Update(p => p.DefaultDouble), + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateOnly_method4_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultDouble = 978.423; + db.UpdateOnlyFields(row, p => p.DefaultDouble, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateOnly_method5_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + var row = db.SingleById(1); + row.DefaultDouble = 978.423; + db.UpdateOnlyFields(row, new[] { nameof(MySqlDefaultValues.DefaultDouble) }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateAdd_expression_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + + var count = db.UpdateAdd(() => new MySqlDefaultValues { DefaultInt = 5, DefaultDouble = 7.2 }, p => p.Id == 1, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + + Assert.That(count, Is.EqualTo(1)); + var row = db.SingleById(1); + Assert.That(row.DefaultInt, Is.EqualTo(6)); + Assert.That(row.DefaultDouble, Is.EqualTo(8.3).Within(0.1)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Can_filter_updateAdd_SqlExpression_to_insert_date() + { + using (var db = OpenDbConnection()) + { + CreateAndInitialize(db); + + ResetUpdateDate(db); + + var where = db.From().Where(p => p.Id == 1); + var count = db.UpdateAdd(() => new MySqlDefaultValues { DefaultInt = 5, DefaultDouble = 7.2 }, where, + cmd => cmd.SetUpdateDate(nameof(MySqlDefaultValues.UpdatedDateUtc), DialectProvider)); + + Assert.That(count, Is.EqualTo(1)); + var row = db.SingleById(1); + Assert.That(row.DefaultInt, Is.EqualTo(6)); + Assert.That(row.DefaultDouble, Is.EqualTo(8.3).Within(0.1)); + VerifyUpdateDate(db); + } + } + + [Test] + public void Does_use_defaults_for_missing_values() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithDefaults { DefaultInt = 10 }); + + var row = db.Select().FirstOrDefault(); + + Assert.That(row.Id, Is.GreaterThan(0)); + Assert.That(row.DefaultInt, Is.EqualTo(10)); + Assert.That(row.DefaultString, Is.EqualTo("String")); + } + } + + [Test] + public void Does_only_use_defaults_for_all_default_properties() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertUsingDefaults( + new ModelWithDefaults { Name = "foo", DefaultInt = 10 }, + new ModelWithDefaults { Name = "bar", DefaultString = "qux" }); + + var rows = db.Select(); + rows.PrintDump(); + + Assert.That(rows.All(x => x.Id > 0)); + Assert.That(rows.All(x => x.DefaultInt == 1)); + Assert.That(rows.All(x => x.DefaultString == "String")); + } + } + + private class MySqlDefaultValues + { + public int Id { get; set; } + + [Default(1)] + public int DefaultInt { get; set; } + + public int DefaultIntNoDefault { get; set; } + + [Default(1)] + public int? NDefaultInt { get; set; } + + [Default(1.1)] + public double DefaultDouble { get; set; } + + [Default(1.1)] + public double? NDefaultDouble { get; set; } + + [Default("'String'")] + public string DefaultString { get; set; } + + [Default(OrmLiteVariables.SystemUtc)] + public DateTime UpdatedDateUtc { get; set; } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/EnsureTests.cs b/tests/ServiceStack.OrmLite.Tests/EnsureTests.cs new file mode 100644 index 000000000..322311edd --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/EnsureTests.cs @@ -0,0 +1,217 @@ +using System.Data; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Async; + +namespace ServiceStack.OrmLite.Tests +{ + public class EnsureTests : OrmLiteTestBase + { + void InitRockstars(IDbConnection db) + { + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedRockstars); + // OrmLiteUtils.PrintSql(); + } + + [Test] + public void Can_pre_Ensure_sql_filter() + { + using var db = OpenDbConnection(); + InitRockstars(db); + + void assertEnsure(SqlExpression q) + { + var rows = db.Select(q); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(1)); + } + + var q = db.From(); + q.Ensure("Id = {0}", 1); + + assertEnsure(q); + + q.Where(x => x.Age == 27); + + assertEnsure(q); + + q.Or(x => x.LivingStatus == LivingStatus.Dead); + + assertEnsure(q); + } + + [Test] + public void Can_pre_Ensure_typed_filter() + { + using var db = OpenDbConnection(); + InitRockstars(db); + + void assertEnsure(SqlExpression q) + { + var rows = db.Select(q); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(1)); + } + + var q = db.From(); + q.Ensure(x => x.Id == 1); + + assertEnsure(q); + + q.Where(x => x.Age == 27); + + assertEnsure(q); + + q.Or(x => x.LivingStatus == LivingStatus.Dead); + + assertEnsure(q); + } + + [Test] + public void Can_post_Ensure() + { + using var db = OpenDbConnection(); + InitRockstars(db); + + void assertEnsure(SqlExpression q) + { + var rows = db.Select(q); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(1)); + } + + var q = db.From(); + + q.Where(x => x.Age == 27) + .Or(x => x.LivingStatus == LivingStatus.Dead); + + q.Ensure(x => x.Id == 1); + assertEnsure(q); + } + + [Test] + public void Can_post_Ensure_joined_table() + { + using var db = OpenDbConnection(); + InitRockstars(db); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedAlbums); + + void assertEnsure(SqlExpression q) + { + var rows = db.Select(q); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(3)); + } + + var q = db + .From() + .Join((r,a) => r.Id == a.RockstarId); + + q.Where(x => x.Age == 27) + .Or(x => x.LivingStatus == LivingStatus.Dead); + + q.Ensure(x => x.Name == "Nevermind"); + assertEnsure(q); + } + + [Test] + public void Can_post_Ensure_multi_tables() + { + using var db = OpenDbConnection(); + InitRockstars(db); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedAlbums); + + void assertEnsure(SqlExpression q) + { + var rows = db.Select(q); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(3)); + } + + var q = db + .From() + .Join((r,a) => r.Id == a.RockstarId); + + q.Where(x => x.Age == 27) + .Or(x => x.LivingStatus == LivingStatus.Dead); + + q.Ensure((r,a) => a.Name == "Nevermind" && r.Id == a.RockstarId); + assertEnsure(q); + } + + [Test] + public void Can_pre_Ensure_multi_tables() + { + using var db = OpenDbConnection(); + InitRockstars(db); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedAlbums); + + void assertEnsure(SqlExpression q) + { + var rows = db.Select(q); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(3)); + } + + var q = db + .From() + .Join((r,a) => r.Id == a.RockstarId); + + q.Ensure((r,a) => a.Name == "Nevermind" && r.Id == a.RockstarId); + + q.Where(x => x.Age == 27) + .Or(x => x.LivingStatus == LivingStatus.Dead); + + assertEnsure(q); + } + + [Test] + public void Can_pre_multi_Ensure_and_tables() + { + using var db = OpenDbConnection(); + InitRockstars(db); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedAlbums); + + void assertEnsure(SqlExpression q) + { + var rows = db.Select(q); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(3)); + } + + var q = db + .From() + .Join((r,a) => r.Id == a.RockstarId); + + q.Ensure((r,a) => a.Name == "Nevermind" && r.Id == a.RockstarId); + + q.Where(x => x.Age == 27) + .Or(x => x.LivingStatus == LivingStatus.Dead); + + q.Ensure(x => x.Id == 3); + + assertEnsure(q); + } + + [Test] + public void Ensure_does_use_aliases() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new ModelWithAlias { + IntField = 1, + }); + + var q = db.From() + .Ensure(x => x.IntField > 0); + + var results = db.Select(q); + Assert.That(results.Count, Is.EqualTo(1)); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/EntityBaseTests.cs b/tests/ServiceStack.OrmLite.Tests/EntityBaseTests.cs new file mode 100644 index 000000000..0e8f2843a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/EntityBaseTests.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests +{ + public class EntityBase + { + public int TenantId { get; set; } + public bool Deleted { get; set; } + } + + public class CustomerEntity : EntityBase + { + [AutoIncrement] + public int Id { get; set; } + + public string CustomerName { get; set; } + } + + public class EmployeeEntity : EntityBase + { + [AutoIncrement] + public int Id { get; set; } + + public string EmployeeType { get; set; } + } + + class TenantRepo + { + public int tenantId; + public TenantRepo(int tenantId) => this.tenantId = tenantId; + + public List All(IDbConnection db) + { + return db.Where(new { TenantId = tenantId }); + } + + public List AllUntyped(IDbConnection db) + { + return db.Where(nameof(EntityBase.TenantId), tenantId); + } + + private SqlExpression CreateQuery(IDbConnection db) + { + return db.From().Where(x => (x as EntityBase).TenantId == tenantId); + } + + public List AllTyped(IDbConnection db) + { + return db.Select(CreateQuery(db)); + } + + public List Where(IDbConnection db, Expression> expr) + { + return db.Select(CreateQuery(db).And(expr)); + } + } + + abstract class EntityRepoBase where T : EntityBase, new() + { + public int tenantId; + public EntityRepoBase(int tenantId) => this.tenantId = tenantId; + + public List All(IDbConnection db) => + db.Select(db.From().Where(x => x.TenantId == tenantId)); + + public List Where(IDbConnection db, Expression> expr) => + db.Select(db.From().Where(x => x.TenantId == tenantId).And(expr)); + } + + class CustomerTenantRepo : EntityRepoBase + { + public CustomerTenantRepo(int tenantId) : base(tenantId) { } + } + + [TestFixture] + public class EntityBaseTests : OrmLiteTestBase + { + public void SeedData(IDbConnection db) + { + OrmLiteUtils.PrintSql(); + db.DropAndCreateTable(); + db.Insert(new CustomerEntity {TenantId = 1, CustomerName = "Kurt" }); + db.Insert(new CustomerEntity {TenantId = 1, CustomerName = "Dave" }); + db.Insert(new CustomerEntity {TenantId = 2, CustomerName = "Kurt" }); + db.Insert(new CustomerEntity {TenantId = 2, CustomerName = "Dave" }); + } + + [Test] + public void Can_generically_query_base_class() + { + var repo = new TenantRepo(2); + + using var db = OpenDbConnection(); + SeedData(db); + + var rows = repo.All(db); + Assert.That(rows.Count, Is.EqualTo(2)); + Assert.That(rows.All(x => x.TenantId == 2)); + + rows = repo.AllTyped(db); + Assert.That(rows.Count, Is.EqualTo(2)); + Assert.That(rows.All(x => x.TenantId == 2)); + + rows = repo.AllUntyped(db); + Assert.That(rows.Count, Is.EqualTo(2)); + Assert.That(rows.All(x => x.TenantId == 2)); + + rows = repo.Where(db, x => x.CustomerName == "Kurt"); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].TenantId, Is.EqualTo(2)); + } + + [Test] + public void Can_generically_query_base_class_with_constrained_repo() + { + var repo = new CustomerTenantRepo(2); + + using var db = OpenDbConnection(); + SeedData(db); + + var rows = repo.All(db); + Assert.That(rows.Count, Is.EqualTo(2)); + Assert.That(rows.All(x => x.TenantId == 2)); + + rows = repo.Where(db, x => x.CustomerName == "Kurt"); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].TenantId, Is.EqualTo(2)); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/EnumTests.cs b/tests/ServiceStack.OrmLite.Tests/EnumTests.cs index fc7a76510..e0ed2acf3 100644 --- a/tests/ServiceStack.OrmLite.Tests/EnumTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/EnumTests.cs @@ -1,14 +1,45 @@ using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Logging; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { using System; - public class EnumTests : OrmLiteTestBase + public class TypeWithEnumAsStringAsPk { + [PrimaryKey] + public SomeEnum Id { get; set; } + +// [Default(typeof(bool), "0")] + public bool IsDeleted { get; set; } + + [RowVersion] + public byte[] RowVersion { get; set; } + + } + + [TestFixtureOrmLite] + public class EnumTests : OrmLiteProvidersTestBase + { + public EnumTests(DialectContext context) : base(context) {} + + [Test] + [IgnoreDialect(Dialect.AnyMySql, "Blob columns can't have a default value. https://stackoverflow.com/a/4553664/85785")] + public void Can_use_RowVersion_on_EnumAsString_PrimaryKey() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new TypeWithEnumAsStringAsPk { Id = SomeEnum.Value1 }); + + db.Save(new TypeWithEnumAsStringAsPk { Id = SomeEnum.Value2 }); + } + [Test] public void CanCreateTable() { @@ -18,238 +49,450 @@ public void CanCreateTable() [Test] public void CanStoreEnumValue() { - using (var con = OpenDbConnection()) - { - con.CreateTable(true); - con.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - } + using var con = OpenDbConnection(); + con.CreateTable(true); + con.Insert(new TypeWithEnum { Id = 1 }); } [Test] public void CanGetEnumValue() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; - db.Save(obj); - var target = db.SingleById(obj.Id); - Assert.AreEqual(obj.Id, target.Id); - Assert.AreEqual(obj.EnumValue, target.EnumValue); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var obj = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }; + db.Save(obj); + var target = db.SingleById(obj.Id); + Assert.AreEqual(obj.Id, target.Id); + Assert.AreEqual(obj.EnumValue, target.EnumValue); } [Test] public void CanQueryByEnumValue_using_select_with_expression() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - db.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - db.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - - var results = db.Select(q => q.EnumValue == SomeEnum.Value1); - Assert.That(results.Count, Is.EqualTo(2)); - results = db.Select(q => q.EnumValue == SomeEnum.Value2); - Assert.That(results.Count, Is.EqualTo(1)); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + db.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + db.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + + var results = db.Select(q => q.EnumValue == SomeEnum.Value1); + Assert.That(results.Count, Is.EqualTo(2)); + results = db.Select(q => q.EnumValue == SomeEnum.Value2); + Assert.That(results.Count, Is.EqualTo(1)); } [Test] public void CanQueryByEnumValue_using_select_with_string() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - db.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - db.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + db.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + db.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - var target = db.SelectFmt( - "EnumValue".SqlColumn() + " = {0}", SomeEnum.Value1); + var target = db.Select( + "EnumValue".SqlColumn(DialectProvider) + " = @value".PreNormalizeSql(db), new { value = SomeEnum.Value1 }); - Assert.AreEqual(2, target.Count()); - } + Assert.AreEqual(2, target.Count()); } [Test] public void CanQueryByEnumValue_using_where_with_AnonType() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - db.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); - db.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + db.Save(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + db.Save(new TypeWithEnum { Id = 3, EnumValue = SomeEnum.Value2 }); - var target = db.Where(new { EnumValue = SomeEnum.Value1 }); + var target = db.Where(new { EnumValue = SomeEnum.Value1 }); - Assert.AreEqual(2, target.Count()); - } + Assert.AreEqual(2, target.Count()); } [Test] public void can_select_enum_equals_other_enum() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Insert(new DoubleState { Id = "1", State1 = DoubleState.State.OK, State2 = DoubleState.State.KO }); - db.Insert(new DoubleState { Id = "2", State1 = DoubleState.State.OK, State2 = DoubleState.State.OK }); - IEnumerable doubleStates = db.Select(x => x.State1 != x.State2); - Assert.AreEqual(1, doubleStates.Count()); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Insert(new DoubleState { Id = "1", State1 = DoubleState.State.OK, State2 = DoubleState.State.KO }); + db.Insert(new DoubleState { Id = "2", State1 = DoubleState.State.OK, State2 = DoubleState.State.OK }); + IEnumerable doubleStates = db.Select(x => x.State1 != x.State2); + Assert.AreEqual(1, doubleStates.Count()); } [Test] public void StoresFlagEnumsAsNumericValues() { - using (var db = OpenDbConnection()) + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Insert( + new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne | FlagsEnum.FlagTwo | FlagsEnum.FlagThree }); + + try { - db.DropAndCreateTable(); - db.Insert( - new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne | FlagsEnum.FlagTwo | FlagsEnum.FlagThree }); - - try - { - var expectedFlags = (int)(FlagsEnum.FlagOne | FlagsEnum.FlagTwo | FlagsEnum.FlagThree); - Assert.AreEqual(db.Scalar("SELECT Flags FROM {0} WHERE Id = 1" - .Fmt("TypeWithFlagsEnum".SqlColumn())), expectedFlags); - } - catch (FormatException) - { - // Probably a string then - var value = db.Scalar("SELECT Flags FROM TypeWithFlagsEnum WHERE Id = 1"); - throw new Exception(string.Format("Expected integer value but got string value {0}", value)); - } + var expectedFlags = (int)(FlagsEnum.FlagOne | FlagsEnum.FlagTwo | FlagsEnum.FlagThree); + Assert.That(db.Scalar("SELECT Flags FROM {0} WHERE Id = 1" + .Fmt("TypeWithFlagsEnum".SqlTable(DialectProvider))), Is.EqualTo(expectedFlags)); + } + catch (FormatException) + { + // Probably a string then + var value = db.Scalar("SELECT Flags FROM TypeWithFlagsEnum WHERE Id = 1"); + throw new Exception($"Expected integer value but got string value {value}"); } } [Test] public void Creates_int_field_for_enum_flags() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - var createTableSql = db.GetLastSql().NormalizeSql(); - createTableSql.Print(); + var createTableSql = db.GetLastSql().NormalizeSql(); + createTableSql.Print(); - Assert.That(createTableSql, Is.StringContaining("flags int")); - } + Assert.That(createTableSql, Does.Contain("flags int")); + } + + [Test] + public void Creates_int_field_for_EnumAsInt() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var createTableSql = db.GetLastSql().NormalizeSql(); + createTableSql.Print(); + + Assert.That(createTableSql, Does.Contain("enumvalue int")); } [Test] public void Updates_enum_flags_with_int_value() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - db.Insert(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); - db.Insert(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagTwo }); - db.Insert(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagOne | FlagsEnum.FlagTwo }); + db.Insert(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); + db.Insert(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagTwo }); + db.Insert(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagOne | FlagsEnum.FlagTwo }); - db.Update(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagThree }); - Assert.That(db.GetLastSql(), Is.StringContaining("=@Flags").Or.StringContaining("=:Flags")); - db.GetLastSql().Print(); + db.Update(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagThree }); + Assert.That(db.GetLastSql(), Does.Contain("=@Flags").Or.Contain("=:Flags")); + db.GetLastSql().Print(); - db.UpdateOnly(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagThree }, q => q.Flags); - Assert.That(db.GetLastSql(), Is.StringContaining("=" + (int)FlagsEnum.FlagThree)); - db.GetLastSql().Print(); - } + db.UpdateOnlyFields(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagThree }, onlyFields: q => q.Flags); + Assert.That(db.GetLastSql().NormalizeSql(), Does.Contain("=@flags")); + + var row = db.SingleById(1); + Assert.That(row.Flags, Is.EqualTo(FlagsEnum.FlagThree)); + } + + [Test] + public void Updates_EnumAsInt_with_int_value() + { + OrmLiteUtils.PrintSql(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value1 }); + db.Insert(new TypeWithEnumAsInt { Id = 2, EnumValue = SomeEnumAsInt.Value2 }); + db.Insert(new TypeWithEnumAsInt { Id = 3, EnumValue = SomeEnumAsInt.Value3 }); + + db.Update(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value1 }); + Assert.That(db.GetLastSql(), Does.Contain("=@EnumValue").Or.Contain("=:EnumValue")); + db.GetLastSql().Print(); + + db.UpdateOnlyFields(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value3 }, + onlyFields: q => q.EnumValue); + Assert.That(db.GetLastSql().NormalizeSql(), Does.Contain("=@enumvalue")); + + var row = db.SingleById(1); + Assert.That(row.EnumValue, Is.EqualTo(SomeEnumAsInt.Value3)); + } + + [Test] + public void Updates_EnumAsChar_with_char_value() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + Assert.That(db.GetLastSql().ToUpper().IndexOf("CHAR(1)", StringComparison.Ordinal) >= 0); + + db.Insert(new TypeWithEnumAsChar { Id = 1, EnumValue = CharEnum.Value1 }); + db.Insert(new TypeWithEnumAsChar { Id = 2, EnumValue = CharEnum.Value2 }); + db.Insert(new TypeWithEnumAsChar { Id = 3, EnumValue = CharEnum.Value3 }); + + var row = db.SingleById(1); + Assert.That(row.EnumValue, Is.EqualTo(CharEnum.Value1)); + + db.Update(new TypeWithEnumAsChar { Id = 1, EnumValue = CharEnum.Value1 }); + Assert.That(db.GetLastSql(), Does.Contain("=@EnumValue").Or.Contain("=:EnumValue")); + db.GetLastSql().Print(); + + db.UpdateOnlyFields(new TypeWithEnumAsChar { Id = 1, EnumValue = CharEnum.Value3 }, + onlyFields: q => q.EnumValue); + Assert.That(db.GetLastSql().NormalizeSql(), Does.Contain("=@enumvalue")); + + row = db.SingleById(1); + Assert.That(row.EnumValue, Is.EqualTo(CharEnum.Value3)); } [Test] public void CanQueryByEnumValue_using_select_with_expression_enum_flags() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Save(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); - db.Save(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagOne }); - db.Save(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagTwo }); - - var results = db.Select(q => q.Flags == FlagsEnum.FlagOne); - db.GetLastSql().Print(); - Assert.That(results.Count, Is.EqualTo(2)); - results = db.Select(q => q.Flags == FlagsEnum.FlagTwo); - db.GetLastSql().Print(); - Assert.That(results.Count, Is.EqualTo(1)); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); + db.Save(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagOne }); + db.Save(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagTwo }); + + var results = db.Select(q => q.Flags == FlagsEnum.FlagOne); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2)); + results = db.Select(q => q.Flags == FlagsEnum.FlagTwo); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(1)); + } + + [Test] + public void CanQueryByEnumValue_using_select_with_expression_EnumAsInt() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value1 }); + db.Save(new TypeWithEnumAsInt { Id = 2, EnumValue = SomeEnumAsInt.Value1 }); + db.Save(new TypeWithEnumAsInt { Id = 3, EnumValue = SomeEnumAsInt.Value2 }); + + var results = db.Select(q => q.EnumValue == SomeEnumAsInt.Value1); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2)); + results = db.Select(q => q.EnumValue == SomeEnumAsInt.Value2); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(1)); } [Test] public void CanQueryByEnumValue_using_select_with_string_enum_flags() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Save(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); - db.Save(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagOne }); - db.Save(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagTwo }); - - var target = db.SelectFmt( - "Flags".SqlColumn() + " = {0}", FlagsEnum.FlagOne); - db.GetLastSql().Print(); - Assert.AreEqual(2, target.Count()); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); + db.Save(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagOne }); + db.Save(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagTwo }); + + var target = db.Select( + "Flags".SqlColumn(DialectProvider) + " = @value".PreNormalizeSql(db), new { value = FlagsEnum.FlagOne }); + db.GetLastSql().Print(); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void CanQueryByEnumValue_using_select_with_string_EnumAsInt() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value1 }); + db.Save(new TypeWithEnumAsInt { Id = 2, EnumValue = SomeEnumAsInt.Value1 }); + db.Save(new TypeWithEnumAsInt { Id = 3, EnumValue = SomeEnumAsInt.Value2 }); + + var target = db.Select( + "EnumValue".SqlColumn(DialectProvider) + " = @value".PreNormalizeSql(db), new { value = SomeEnumAsInt.Value1 }); + db.GetLastSql().Print(); + Assert.That(target.Count, Is.EqualTo(2)); } [Test] public void CanQueryByEnumValue_using_where_with_AnonType_enum_flags() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Save(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); - db.Save(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagOne }); - db.Save(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagTwo }); - - var target = db.Where(new { Flags = FlagsEnum.FlagOne }); - db.GetLastSql().Print(); - Assert.AreEqual(2, target.Count()); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagOne }); + db.Save(new TypeWithFlagsEnum { Id = 2, Flags = FlagsEnum.FlagOne }); + db.Save(new TypeWithFlagsEnum { Id = 3, Flags = FlagsEnum.FlagTwo }); + + var target = db.Where(new { Flags = FlagsEnum.FlagOne }); + db.GetLastSql().Print(); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void CanQueryByEnumValue_using_where_with_AnonType_EnumAsInt() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value1 }); + db.Save(new TypeWithEnumAsInt { Id = 2, EnumValue = SomeEnumAsInt.Value1 }); + db.Save(new TypeWithEnumAsInt { Id = 3, EnumValue = SomeEnumAsInt.Value2 }); + + var target = db.Where(new { EnumValue = SomeEnumAsInt.Value1 }); + db.GetLastSql().Print(); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_use_Equals_in_SqlExpression_with_EnumAsInt() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.Save(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value1 }); + db.Save(new TypeWithEnumAsInt { Id = 2, EnumValue = SomeEnumAsInt.Value2 }); + db.Save(new TypeWithEnumAsInt { Id = 3, EnumValue = SomeEnumAsInt.Value3 }); + + var row = db.Single(x => x.EnumValue == SomeEnumAsInt.Value2); + Assert.That(row.Id, Is.EqualTo(2)); + + row = db.Single(x => x.EnumValue.Equals(SomeEnumAsInt.Value2)); + Assert.That(row.Id, Is.EqualTo(2)); } [Test] public void Does_save_Enum_with_label_by_default() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - db.Insert(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); - db.Insert(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value2 }); + db.Insert(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value1 }); + db.Insert(new TypeWithEnum { Id = 2, EnumValue = SomeEnum.Value2 }); - var row = db.SingleFmt( - "EnumValue".SqlColumn() + " = {0}", "Value2"); + var row = db.Single( + "EnumValue".SqlColumn(DialectProvider) + " = @value", new { value = "Value2" }); - Assert.That(row.Id, Is.EqualTo(2)); - } + Assert.That(row.Id, Is.EqualTo(2)); } [Test] public void Can_save_Enum_as_Integers() { - using (JsConfig.With(treatEnumAsInteger: true)) + using (JsConfig.With(new Config { TreatEnumAsInteger = true })) using (var db = OpenDbConnection()) { - db.DropAndCreateTable(); + db.DropAndCreateTable(); - db.Insert(new TypeWithEnumAsInt { Id = 1, EnumValue = SomeEnumAsInt.Value1 }); - db.Insert(new TypeWithEnumAsInt { Id = 2, EnumValue = SomeEnumAsInt.Value2 }); + db.Insert(new TypeWithTreatEnumAsInt { Id = 1, EnumValue = SomeEnumTreatAsInt.Value1 }); + db.Insert(new TypeWithTreatEnumAsInt { Id = 2, EnumValue = SomeEnumTreatAsInt.Value2 }); - var row = db.SingleFmt( - "EnumValue".SqlColumn() + " = {0}", "2"); + var row = db.Single( + "EnumValue".SqlColumn(DialectProvider) + " = @value".PreNormalizeSql(db), new { value = "2" }); Assert.That(row.Id, Is.EqualTo(2)); } } + + [Test] + public void Can_Select_Type_with_Nullable_Enum() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new TypeWithNullableEnum { Id = 1, EnumValue = SomeEnum.Value1, NullableEnumValue = SomeEnum.Value2 }); + db.Insert(new TypeWithNullableEnum { Id = 2, EnumValue = SomeEnum.Value1 }); + + var rows = db.Select(); + Assert.That(rows.Count, Is.EqualTo(2)); + + var row = rows.First(x => x.NullableEnumValue == null); + Assert.That(row.Id, Is.EqualTo(2)); + + rows = db.SqlList("SELECT * FROM {0}" + .Fmt(nameof(TypeWithNullableEnum).SqlTable(DialectProvider))); + + row = rows.First(x => x.NullableEnumValue == null); + Assert.That(row.Id, Is.EqualTo(2)); + + rows = db.SqlList("SELECT * FROM {0}" + .Fmt(nameof(TypeWithNullableEnum).SqlTable(DialectProvider)), new { Id = 2 }); + + row = rows.First(x => x.NullableEnumValue == null); + Assert.That(row.Id, Is.EqualTo(2)); + } + + [Test] + public void Can_get_Scalar_Enum() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var row = new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value2 }; + db.Insert(row); + + var someEnum = db.Scalar(db.From() + .Where(o => o.Id == row.Id) + .Select(o => o.EnumValue)); + + Assert.That(someEnum, Is.EqualTo(SomeEnum.Value2)); + } + + [Test] + public void Can_get_Scalar_Enum_Flag() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var row = new TypeWithFlagsEnum { Id = 1, Flags = FlagsEnum.FlagTwo }; + db.Insert(row); + + row.PrintDump(); + + var flagsEnum = db.Scalar(db.From() + .Where(o => o.Id == row.Id) + .Select(o => o.Flags)); + + Assert.That(flagsEnum, Is.EqualTo(FlagsEnum.FlagTwo)); + } + + [Test] + public void Can_select_enum_using_tuple() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new TypeWithEnum { Id = 1, EnumValue = SomeEnum.Value2 }); + + var q = db.From().Select(x => new { x.EnumValue, x.Id }); + var rows = db.Select<(SomeEnum someEnum, int id)>(q); + + Assert.That(rows[0].someEnum, Is.EqualTo(SomeEnum.Value2)); + } + + [Test] + public void Does_insert_types_with_EnumMembers() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new TypeWithEnumMember {Id = 1, WorkflowType = WorkflowType.SalesInvoice}); + db.Insert(new TypeWithEnumMember {Id = 2, WorkflowType = WorkflowType.PurchaseInvoice}); + + var results = db.Select().ToDictionary(x => x.Id); + Assert.That(results[1].WorkflowType, Is.EqualTo(WorkflowType.SalesInvoice)); + Assert.That(results[2].WorkflowType, Is.EqualTo(WorkflowType.PurchaseInvoice)); + } + + [Test] + public void Can_query_EnumMembers_with_SqlFmt() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var id = 1; + db.Insert(new TypeWithEnumMember {Id = id, WorkflowType = WorkflowType.PurchaseInvoice}); + var q = db.From(); + var result = db.Single( + ("select * from " + q.Table() + " as db where db.Id = {0} and db." + + q.Column(x => x.WorkflowType) + " = {1}").SqlFmt(id, WorkflowType.PurchaseInvoice)); + Assert.That(result.WorkflowType, Is.EqualTo(WorkflowType.PurchaseInvoice)); + } } + [EnumAsChar] + public enum CharEnum : int + { + Value1 = 'A', + Value2 = 'B', + Value3 = 'C', + Value4 = 'D' + } public class DoubleState { @@ -266,9 +509,9 @@ public enum State public enum SomeEnum { - Value1 = 1, - Value2 = 2, - Value3 = 3 + Value1, + Value2, + Value3 } public class TypeWithEnum @@ -277,17 +520,17 @@ public class TypeWithEnum public SomeEnum EnumValue { get; set; } } - public enum SomeEnumAsInt + public enum SomeEnumTreatAsInt { Value1 = 1, Value2 = 2, Value3 = 3 } - public class TypeWithEnumAsInt + public class TypeWithTreatEnumAsInt { public int Id { get; set; } - public SomeEnumAsInt EnumValue { get; set; } + public SomeEnumTreatAsInt EnumValue { get; set; } } [Flags] @@ -303,4 +546,50 @@ public class TypeWithFlagsEnum public int Id { get; set; } public FlagsEnum Flags { get; set; } } + + [EnumAsInt] + public enum SomeEnumAsInt + { + Value1 = 1, + Value2 = 2, + Value3 = 3, + } + + public class TypeWithEnumAsChar + { + public int Id { get; set; } + + public CharEnum EnumValue { get; set; } + } + + public class TypeWithEnumAsInt + { + public int Id { get; set; } + + public SomeEnumAsInt EnumValue { get; set; } + } + + public class TypeWithNullableEnum + { + public int Id { get; set; } + public SomeEnum EnumValue { get; set; } + public SomeEnum? NullableEnumValue { get; set; } + } + + public enum WorkflowType + { + Unknown, + [EnumMember(Value = "Sales Invoices")] + SalesInvoice, + [EnumMember(Value = "Purchase Invoices")] + PurchaseInvoice, + [EnumMember(Value = "Supplier Statement")] + SupplierStatement + } + + public class TypeWithEnumMember + { + public int Id { get; set; } + public WorkflowType WorkflowType { get; set; } + } } diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/AdditiveExpressionsTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/AdditiveExpressionsTest.cs index 01d608b32..58b380ea4 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/AdditiveExpressionsTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/AdditiveExpressionsTest.cs @@ -2,68 +2,80 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class AdditiveExpressionsTest : ExpressionsTestBase { + public AdditiveExpressionsTest(DialectContext context) : base(context) {} + [Test] public void Can_select_constant_add_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 4 + 3); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 4 + 3); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_constant_subtract_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 10 - 3); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 10 - 3); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_variable_add_expression() { -// ReSharper disable ConvertToConstant.Local + // ReSharper disable ConvertToConstant.Local var a = 4; var b = 3; -// ReSharper restore ConvertToConstant.Local + // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == a + b); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == a + b); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -74,58 +86,68 @@ public void Can_select_variable_subtract_expression() var b = 3; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == a - b); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == a - b); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_method_add_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(4) + GetValue(3)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == GetValue(4) + GetValue(3)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_method_subtract_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); + + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == GetValue(10) - GetValue(3)); - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(10) - GetValue(3)); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + } } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/ComplexJoinTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/ComplexJoinTests.cs index 67280b72e..83c931b02 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/ComplexJoinTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/ComplexJoinTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using System.Linq; using NUnit.Framework; @@ -125,9 +126,11 @@ public class ProductWithManufacturer public string ManufacturerName { get; set; } } - [TestFixture] - public class ComplexJoinTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class ComplexJoinTests : OrmLiteProvidersTestBase { + public ComplexJoinTests(DialectContext context) : base(context) {} + private static int _baz1Id; private static int _baz2Id; private static int _fooBar1Id; @@ -154,13 +157,13 @@ private static void InitTables(IDbConnection db) db.Insert(new BarJoin { Id = bar1Id, Name = "Banana", }); db.Insert(new BarJoin { Id = bar2Id, Name = "Orange", }); - _baz1Id = (int) db.Insert(new Baz {Name = "Large"}, true); - _baz2Id = (int) db.Insert(new Baz {Name = "Huge"}, true); + _baz1Id = (int)db.Insert(new Baz { Name = "Large" }, true); + _baz2Id = (int)db.Insert(new Baz { Name = "Huge" }, true); - _fooBar1Id = (int) db.Insert(new FooBar { BarId = bar1Id, }, true); - _fooBar2Id = (int) db.Insert(new FooBar { BarId = bar2Id, }, true); + _fooBar1Id = (int)db.Insert(new FooBar { BarId = bar1Id, }, true); + _fooBar2Id = (int)db.Insert(new FooBar { BarId = bar2Id, }, true); - _fooBarBaz1Id = (int) db.Insert(new FooBarBaz { Amount = 42, FooBarId = _fooBar1Id, BazId = _baz2Id }, true); + _fooBarBaz1Id = (int)db.Insert(new FooBarBaz { Amount = 42, FooBarId = _fooBar1Id, BazId = _baz2Id }, true); _fooBarBaz2Id = (int)db.Insert(new FooBarBaz { Amount = 50, FooBarId = _fooBar1Id, BazId = _baz1Id }, true); _fooBarBaz3Id = (int)db.Insert(new FooBarBaz { Amount = 2, FooBarId = _fooBar2Id, BazId = _baz1Id }, true); } @@ -181,13 +184,14 @@ public void Can_query_contains_on_joined_table_column() q = db.From() .Join((dp, p) => dp.BarId == p.Id) - .Where((f,x) => x.Name.Contains("an")); + .Where((f, x) => x.Name.Contains("an")); results = db.Select(q); Assert.That(results.Count, Is.EqualTo(2)); } } +#pragma warning disable 618 [Test] public void ComplexJoin_with_JoinSqlBuilder() { @@ -196,7 +200,7 @@ public void ComplexJoin_with_JoinSqlBuilder() InitTables(db); /* This gives the expected values for BazId */ - var jn = new JoinSqlBuilder() + var jn = new JoinSqlBuilder(DialectProvider) .Join( sourceColumn: dp => dp.BarId, destinationColumn: p => p.Id, @@ -224,6 +228,7 @@ public void ComplexJoin_with_JoinSqlBuilder() Assert.That(fooBarBaz.BazId, Is.EqualTo(_baz1Id)); } } +#pragma warning restore 618 [Test] public void ComplexJoin_with_SqlExpression() @@ -247,8 +252,31 @@ public void ComplexJoin_with_SqlExpression() Assert.That(fooBarBaz.BazId, Is.EqualTo(_baz2Id)); fooBarBaz = results.First(x => x.FooBarBazId == _fooBarBaz2Id); Assert.That(fooBarBaz.BazId, Is.EqualTo(_baz1Id)); - fooBarBaz = results.First(x => x.FooBarBazId == _fooBarBaz2Id); - Assert.That(fooBarBaz.BazId, Is.EqualTo(_baz1Id)); + } + } + + [Test] + public void Can_select_dictionary_from_multiple_tables() + { + using (var db = OpenDbConnection()) + { + InitTables(db); + + var q = db.From() + .Join() + .Select((f, b) => new { f.Id, b.Name }); + + var results = db.Dictionary(q); + + var sql = db.GetLastSql(); + sql.Print(); + + results.PrintDump(); + + Assert.That(results, Is.EquivalentTo(new Dictionary { + {_fooBar1Id,"Banana"}, + {_fooBar2Id,"Orange"}, + })); } } diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/ConditionalExpressionTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/ConditionalExpressionTest.cs index 9bc4e68ac..7aef70961 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/ConditionalExpressionTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/ConditionalExpressionTest.cs @@ -1,45 +1,56 @@ -using NUnit.Framework; +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class ConditionalExpressionTest : ExpressionsTestBase { + public ConditionalExpressionTest(DialectContext context) : base(context) {} + [Test] public void Can_select_conditional_and_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn > 2 && q.IntColumn < 4); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn > 2 && q.IntColumn < 4); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_conditional_or_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 3 || q.IntColumn < 0); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 3 || q.IntColumn < 0); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -50,20 +61,23 @@ public void Can_select_evaluated_conditional_and_expression() var b = 5; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a >= b && a > 0)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == (a >= b && a > 0)); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -74,20 +88,23 @@ public void Can_select_evaluated_conditional_or_expression() var b = 5; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 3 || a > b); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 3 || a > b); - Assert.IsNotNull(actual); - Assert.AreEqual(11, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(11, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -97,43 +114,84 @@ public void Can_select_evaluated_invalid_conditional_or_valid_expression() var a = true; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => !q.BoolColumn || a); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => !q.BoolColumn || a); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } + [Test] public void Can_select_evaluated_conditional_and_valid_expression() { var model = new - { - StringValue = "4" - }; + { + StringValue = "4" + }; - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn && q.StringColumn == model.StringValue); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn && q.StringColumn == model.StringValue); + + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_use_bitwise_operations_in_typed_query() + { + OrmLiteConfig.BeforeExecFilter = dbCmd => dbCmd.GetDebugString().Print(); + + Init(5); + + List results; + + using (var db = OpenDbConnection()) + { + results = db.Select(x => (x.Id | 2) == 3); + Assert.That(results.Map(x => x.Id), Is.EquivalentTo(new[]{ 1, 3 })); + + results = db.Select(x => (x.Id & 2) == 2); + Assert.That(results.Map(x => x.Id), Is.EquivalentTo(new[]{ 2, 3 })); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + if (!Dialect.AnySqlServer.HasFlag(Dialect)) + { + results = db.Select(x => (x.Id << 1) == 4); + Assert.That(results.Map(x => x.Id), Is.EquivalentTo(new[]{ 2 })); + + results = db.Select(x => (x.Id >> 1) == 1); + Assert.That(results.Map(x => x.Id), Is.EquivalentTo(new[]{ 2, 3 })); + } + + if ((Dialect.AnySqlServer | Dialect.AnyMySql).HasFlag(Dialect)) + { + results = db.Select(x => (x.Id ^ 2) == 3); + Assert.That(results.Map(x => x.Id), Is.EquivalentTo(new[]{ 1 })); + } + } } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/EqualityExpressionsTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/EqualityExpressionsTest.cs index e47885d6c..c03c5b0cc 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/EqualityExpressionsTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/EqualityExpressionsTest.cs @@ -2,88 +2,101 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class EqualityExpressionsTest : ExpressionsTestBase { - #region int tests + public EqualityExpressionsTest(DialectContext context) : base(context) {} [Test] public void Can_select_equals_constant_int_expression() { - var expected = new TestType() - { - IntColumn = 3, - BoolColumn = true, - StringColumn = "4" - }; + var expected = new TestType + { + IntColumn = 3, + BoolColumn = true, + StringColumn = "4" + }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 3); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 3); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_equals_variable_int_expression() { -// ReSharper disable ConvertToConstant.Local + // ReSharper disable ConvertToConstant.Local var columnValue = 3; -// ReSharper restore ConvertToConstant.Local + // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = columnValue, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == columnValue); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == columnValue); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_equals_int_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(3)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == GetValue(3)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_not_equals_constant_int_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn != 3); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn != 3); - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } } [Test] @@ -93,85 +106,89 @@ public void Can_select_not_equals_variable_int_expression() var columnValue = 3; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = columnValue, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn != columnValue); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn != columnValue); - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } } [Test] public void Can_select_not_equals_int_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn != GetValue(3)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn != GetValue(3)); - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } } - #endregion - - #region bool test - [Test] public void Can_select_equals_constant_bool_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); -// ReSharper disable RedundantBoolCompare - var actual = OpenDbConnection().Select(q => q.BoolColumn == true); -// ReSharper restore RedundantBoolCompare + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == true); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_equals_constant_bool_expression2() { - var expected = new TestType() + var expected = new TestType { IntColumn = 3, BoolColumn = true, StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - // ReSharper disable RedundantBoolCompare - var actual = OpenDbConnection().Select(q => q.BoolColumn); - // ReSharper restore RedundantBoolCompare + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -188,13 +205,16 @@ public void Can_select_equals_variable_bool_expression() StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == columnValue); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == columnValue); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -207,13 +227,16 @@ public void Can_select_equals_bool_method_expression() StringColumn = "4" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == GetValue(true)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == GetValue(true)); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -227,13 +250,16 @@ public void Can_select_equals_null_espression() NullableCol = new TestType { StringColumn = "sometext" } }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.NullableCol == null); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.NullableCol == null); - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 10); - CollectionAssert.DoesNotContain(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 10); + CollectionAssert.DoesNotContain(actual, expected); + } } [Test] @@ -247,16 +273,39 @@ public void Can_select_not_equals_null_espression() NullableCol = new TestType { StringColumn = "sometext" } }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.NullableCol != null); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.NullableCol != null); - Assert.IsNotNull(actual); - Assert.AreEqual(actual.Count, 1); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } } // Assume not equal works ;-) - #endregion + [Test] + public void Can_select_equals_variable_null_expression() + { + object columnValue = null; + + var expected = new TestType() + { + IntColumn = 12, + BoolColumn = false, + StringColumn = "test", + NullableCol = new TestType { StringColumn = "sometext" } + }; + + Init(10, expected); + + var actual = OpenDbConnection().Select(q => q.NullableCol == columnValue); + + Assert.IsNotNull(actual); + Assert.AreEqual(actual.Count, 10); + CollectionAssert.DoesNotContain(actual, expected); + } } } diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionChainingUseCase.cs b/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionChainingUseCase.cs index daece8204..da478067e 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionChainingUseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionChainingUseCase.cs @@ -6,10 +6,10 @@ namespace ServiceStack.OrmLite.Tests.Expression { - [TestFixture] - public class ExpressionChainingUseCase: OrmLiteTestBase + [TestFixtureOrmLite] + public class ExpressionChainingUseCase: OrmLiteProvidersTestBase { - #region Setup/Teardown + public ExpressionChainingUseCase(DialectContext context) : base(context) {} [SetUp] public void SetUp() @@ -26,8 +26,6 @@ public void TearDown() db.Dispose(); } - #endregion - public class Person { public Person() @@ -49,38 +47,39 @@ public Person(int id, string firstName, string lastName, int age) public override string ToString() { - return string.Format("Id: {0}, FirstName: {1}, LastName: {2}, Age: {3}", Id, FirstName, LastName, Age); + return $"Id: {Id}, FirstName: {FirstName}, LastName: {LastName}, Age: {Age}"; } } private IDbConnection db; public Person[] People = new[] - { - new Person(1, "Jimi", "Hendrix", 27), - new Person(2, "Janis", "Joplin", 27), - new Person(3, "Jim", "Morrisson", 27), - new Person(4, "Kurt", "Cobain", 27), - new Person(5, "Elvis", "Presley", 42), - new Person(6, "Michael", "Jackson", 50) - }; + { + new Person(1, "Jimi", "Hendrix", 27), + new Person(2, "Janis", "Joplin", 27), + new Person(3, "Jim", "Morrisson", 27), + new Person(4, "Kurt", "Cobain", 27), + new Person(5, "Elvis", "Presley", 42), + new Person(6, "Michael", "Jackson", 50) + }; [Test] public void Can_Chain_Expressions_Using_And() { db.Insert(People); - var visitor = db.From(); + var q = db.From(); - visitor.Where(x => x.FirstName.StartsWith("Jim")).And(x => x.LastName.StartsWith("Hen")); - var results = db.Select(visitor); + q.Where(x => x.FirstName.StartsWith("Jim")) + .And(x => x.LastName.StartsWith("Hen")); + var results = db.Select(q); Assert.AreEqual(1,results.Count); - visitor.Where(); //clears underlying expression + q.Where(); //clears underlying expression - visitor.Where(x => x.LastName.StartsWith("J")).And(x => x.Age > 40); - results = db.Select(visitor); + q.Where(x => x.LastName.StartsWith("J")).And(x => x.Age > 40); + results = db.Select(q); Assert.AreEqual(results[0].FirstName,"Michael"); } @@ -218,7 +217,7 @@ public void Can_OrderBy_string() var ages = db.Select(query).ConvertAll(x => x.Age.Value); db.GetLastSql().Print(); - Assert.That(db.GetLastSql(), Is.StringContaining("ORDER BY Age DESC")); + Assert.That(db.GetLastSql(), Does.Contain("ORDER BY Age DESC")); ages.PrintDump(); diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionUsingCustomSerializedEnumTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionUsingCustomSerializedEnumTests.cs index db7228362..031152585 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionUsingCustomSerializedEnumTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionUsingCustomSerializedEnumTests.cs @@ -31,15 +31,17 @@ public class NullableActivity public string Comment { get; set; } } + [TestFixtureOrmLite] public class ExpressionUsingCustomSerializedEnumTests : ExpressionsTestBase { + public ExpressionUsingCustomSerializedEnumTests(DialectContext context) : base(context) {} + [TestCase(0)] [TestCase(1)] [TestCase(2)] + [IgnoreDialect(Tests.Dialect.AnyOracle, "Can't work on Oracle because Oracle does not allow empty strings in a varchar column")] public void Can_select_on_custom_default_null_serialized_enum(int index) { - if (Dialect == Dialect.Oracle) Assert.Ignore("Can't work on Oracle because Oracle does not allow empty strings in a varchar column"); - EnumSerializerWithNullDefaults.Configure(); using (var db = OpenDbConnection()) @@ -59,11 +61,11 @@ private static Activity Init(IDbConnection db, int index) db.DropAndCreateTable(); var activities = new [] - { - new Activity {ActivityType = ActivityType.Unknown, Comment = "know nothing about this"}, - new Activity {ActivityType = ActivityType.Unspecified, Comment = "know we don't know about this"}, - new Activity {ActivityType = ActivityType.HavingFun, Comment = "want to be doing this"} - }; + { + new Activity { ActivityType = ActivityType.Unknown, Comment = "know nothing about this" }, + new Activity { ActivityType = ActivityType.Unspecified, Comment = "know we don't know about this" }, + new Activity { ActivityType = ActivityType.HavingFun, Comment = "want to be doing this" } + }; db.InsertAll(activities); return activities[index]; } @@ -71,10 +73,9 @@ private static Activity Init(IDbConnection db, int index) [TestCase(0)] [TestCase(1)] [TestCase(2)] + [IgnoreDialect(Tests.Dialect.AnyOracle, "Can't work on Oracle because Oracle does not allow empty strings in a varchar column")] public void Can_select_on_custom_default_empty_serialized_enum(int index) { - if (Dialect == Dialect.Oracle) Assert.Ignore("Can't work on Oracle because Oracle does not allow empty strings in a varchar column"); - EnumSerializerWithEmptyDefaults.Configure(); using (var db = OpenDbConnection()) diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionsTestBase.cs b/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionsTestBase.cs index 25c81fc27..198bb9b0f 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionsTestBase.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/ExpressionsTestBase.cs @@ -1,36 +1,41 @@ using System; using System.Data; -using System.IO; using System.Linq; using NUnit.Framework; namespace ServiceStack.OrmLite.Tests.Expression { - public class ExpressionsTestBase : OrmLiteTestBase + [NonParallelizable] + public abstract class ExpressionsTestBase : OrmLiteProvidersTestBase { + public ExpressionsTestBase(DialectContext context) : base(context) {} + [SetUp] public void Setup() { - OpenDbConnection().CreateTable(true); + using (var db = OpenDbConnection()) + db.CreateTable(true); + + db = OpenDbConnection(); } //Avoid painful refactor to change all tests to use a using pattern private IDbConnection db; - public override IDbConnection OpenDbConnection() - { - try - { - if (db != null && db.State != ConnectionState.Open) - db = null; - } - catch (ObjectDisposedException) //PostgreSQL throws when trying to inspect db.State on a disposed connection. WHY??? - { - db = null; - } - - return db ?? (db = base.OpenDbConnection()); - } +// public override IDbConnection OpenDbConnection() +// { +// try +// { +// if (db != null && db.State != ConnectionState.Open) +// db = null; +// } +// catch (ObjectDisposedException) //PostgreSQL throws when trying to inspect db.State on a disposed connection. WHY??? +// { +// db = null; +// } +// +// return db ?? (db = base.OpenDbConnection()); +// } [TearDown] public void TearDown() @@ -46,46 +51,52 @@ public T GetValue(T item) return item; } - protected void EstablishContext(int numberOfRandomObjects) + protected void Init(int numberOfRandomObjects) + { + Init(numberOfRandomObjects, null); + } + + protected void Init(int numberOfRandomObjects, params TestType[] obj) { - EstablishContext(numberOfRandomObjects, null); + Init(null, numberOfRandomObjects, obj); } - protected void EstablishContext(int numberOfRandomObjects, params TestType[] obj) + protected void Init(IDbConnection db, int numberOfRandomObjects, params TestType[] obj) { if (obj == null) obj = new TestType[0]; - using (var con = OpenDbConnection()) + var con = db ?? OpenDbConnection(); + foreach (var t in obj) { - foreach (var t in obj) - { - con.Insert(t); - } + con.Insert(t); + } + + var random = new Random((int)(DateTime.UtcNow.Ticks ^ (DateTime.UtcNow.Ticks >> 4))); + for (var i = 0; i < numberOfRandomObjects; i++) + { + TestType o = null; - var random = new Random((int)(DateTime.UtcNow.Ticks ^ (DateTime.UtcNow.Ticks >> 4))); - for (var i = 0; i < numberOfRandomObjects; i++) + while (o == null) { - TestType o = null; + int intVal = random.Next(); - while (o == null) + o = new TestType { - int intVal = random.Next(); + BoolColumn = random.Next() % 2 == 0, + IntColumn = intVal, + StringColumn = Guid.NewGuid().ToString() + }; - o = new TestType - { - BoolColumn = random.Next() % 2 == 0, - IntColumn = intVal, - StringColumn = Guid.NewGuid().ToString() - }; - - if (obj.Any(x => x.IntColumn == intVal)) - o = null; - } - - con.Insert(o); + if (obj.Any(x => x.IntColumn == intVal)) + o = null; } + + con.Insert(o); } + + if (db == null) + con.Dispose(); } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/FromExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/FromExpressionTests.cs index 508576476..b68b52902 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/FromExpressionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/FromExpressionTests.cs @@ -10,8 +10,11 @@ public class Band public int PersonId { get; set; } } + [TestFixtureOrmLite] public class FromExpressionTests : ExpressionsTestBase { + public FromExpressionTests(DialectContext context) : base(context) {} + public void Init(IDbConnection db) { db.DropAndCreateTable(); @@ -30,7 +33,7 @@ public void Can_select_from_custom_FROM_expression() { Init(db); - var results = db.Select(db.From("Person INNER JOIN Band ON Person.Id = Band.{0}".Fmt("PersonId".SqlColumn()))); + var results = db.Select(db.From("Person INNER JOIN Band ON Person.Id = Band.{0}".Fmt("PersonId".SqlColumn(DialectProvider)))); Assert.That(results.Count, Is.EqualTo(2)); Assert.That(results.ConvertAll(x => x.FirstName), Is.EquivalentTo(new[] { "Kurt", "Jim" })); diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/GenericTableExpressions.cs b/tests/ServiceStack.OrmLite.Tests/Expression/GenericTableExpressions.cs index 12c599298..d408db8d8 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/GenericTableExpressions.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/GenericTableExpressions.cs @@ -4,7 +4,6 @@ using System.Linq.Expressions; using NUnit.Framework; using ServiceStack.DataAnnotations; -using ServiceStack.Logging; namespace ServiceStack.OrmLite.Tests.Expression { @@ -16,14 +15,14 @@ public class GenericEntity public string ColumnA { get; set; } } - [TestFixture] - public class GenericTableExpressions : OrmLiteTestBase + [TestFixtureOrmLite] + public class GenericTableExpressions : OrmLiteProvidersTestBase { + public GenericTableExpressions(DialectContext context) : base(context) {} + [Test] public void Can_change_table_at_runtime() { - LogManager.LogFactory = new ConsoleLogFactory(); - const string tableName = "Entity1"; using (var db = OpenDbConnection()) { @@ -31,16 +30,16 @@ public void Can_change_table_at_runtime() db.Insert(tableName, new GenericEntity { Id = 1, ColumnA = "A" }); - var rows = db.Select(tableName, q => - q.Where(x => x.ColumnA == "A")); + var rows = db.Select(tableName, db.From() + .Where(x => x.ColumnA == "A")); Assert.That(rows.Count, Is.EqualTo(1)); db.Update(tableName, new GenericEntity { ColumnA = "B" }, where: q => q.ColumnA == "A"); - rows = db.Select(tableName, q => - q.Where(x => x.ColumnA == "B")); + rows = db.Select(tableName, db.From() + .Where(x => x.ColumnA == "B")); Assert.That(rows.Count, Is.EqualTo(1)); } @@ -80,7 +79,7 @@ public static long Insert(this IDbConnection db, string table, T obj, bool se return (long)ExecWithAlias(table, () => db.Insert(obj, selectIdentity)); } - public static List Select(this IDbConnection db, string table, Func, SqlExpression> expression) + public static List Select(this IDbConnection db, string table, SqlExpression expression) { return (List)ExecWithAlias(table, () => db.Select(expression)); } diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/JoinAliasTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/JoinAliasTests.cs new file mode 100644 index 000000000..0b2e0fa3b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/JoinAliasTests.cs @@ -0,0 +1,144 @@ +using System; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + public class Tasked + { + [AutoIncrement] + public long Id { get; set; } + + public long? ParentId { get; set; } + + public DateTime Created { get; set; } + } + + public class AliasedTable + { + [AutoIncrement] + [PrimaryKey] + [Alias("MAINID")] + public int Id { get; set; } + + [Alias("DESCRIPTION")] + public string Description { get; set; } + } + + public class AliasedTableAlt + { + [AutoIncrement] + [PrimaryKey] + [Alias("ALTID")] + public int Id { get; set; } + + [Alias("DESCRIPTION")] + public string Description { get; set; } + } + + [TestFixtureOrmLite] + public class JoinAliasTests : OrmLiteProvidersTestBase + { + public JoinAliasTests(DialectContext context) : base(context) {} + + [Test] + [IgnoreDialect(Tests.Dialect.AnyPostgreSql | Tests.Dialect.AnyMySql, "Invalid Custom SQL for provider naming convention")] + public void Can_use_JoinAlias_in_condition() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var parentId = db.Insert(new Tasked { Created = new DateTime(2000, 01, 01) }, selectIdentity: true); + var childId = db.Insert(new Tasked { ParentId = parentId, Created = new DateTime(2001, 01, 01) }, selectIdentity:true); + + var fromDateTime = new DateTime(2000, 02, 02); + + var q = db.From() + .CustomJoin("LEFT JOIN Tasked history ON (Tasked.Id = history.ParentId)") + .Where("history.\"Created\" >= {0} OR Tasked.\"Created\" >= {0}", fromDateTime); + + //doesn't work with Self Joins + //var q = db.From() + // .LeftJoin((parent, history) => (parent.Id == history.ParentId) + // && (history.CreatedAt >= fromDateTime || parent.CreatedAt >= fromDateTime) + // ,db.JoinAlias("history")); + + var results = db.Select(q); + + db.GetLastSql().Print(); + + results.PrintDump(); + } + } + + [Test] + public void Can_use_Column_to_resolve_properties() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var parentId = db.Insert(new Tasked { Created = new DateTime(2000, 01, 01) }, selectIdentity: true); + var childId = db.Insert(new Tasked { ParentId = parentId, Created = new DateTime(2001, 01, 01) }, selectIdentity: true); + + var q = db.From(); + + var leftJoin = + $"LEFT JOIN Tasked history ON ({q.Column(t => t.Id, prefixTable:true)} = history.{q.Column(t => t.ParentId)})"; + Assert.That(leftJoin, Is.EqualTo( + $"LEFT JOIN Tasked history ON ({q.Table()}.{q.Column(t => t.Id)} = history.{q.Column(t => t.ParentId)})")); + Assert.That(leftJoin, Is.EqualTo( + $"LEFT JOIN Tasked history ON ({q.Table()}.{q.Column(nameof(Tasked.Id))} = history.{q.Column(nameof(Tasked.ParentId))})")); + + q.CustomJoin(leftJoin); + + var results = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(2)); + } + } + + [Test] + public async Task Can_get_RowCount_of_duplicate_aliases_in_AliasedTable() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var q = db.From() + .Join((mainTable, altTable) => mainTable.Id == altTable.Id) + .Where(x => x.Id == 1); + + var result = await db.RowCountAsync(q); + } + } + + [Test] + public void Can_use_JoinAlias_on_source_table() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var parentId = db.Insert(new Tasked { Created = new DateTime(2000, 01, 01) }, selectIdentity: true); + var childId = db.Insert(new Tasked { ParentId = parentId, Created = new DateTime(2001, 01, 01) }, selectIdentity: true); + + var q = db.From(db.TableAlias("s")) + .Join((t1, t2) => t1.ParentId == t2.Id, db.TableAlias("t")); + + var rows = db.Select(q); + rows.PrintDump(); + + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(2)); + Assert.That(rows[0].ParentId, Is.EqualTo(1)); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/LimitExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/LimitExpressionTests.cs new file mode 100644 index 000000000..873afb7d8 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/LimitExpressionTests.cs @@ -0,0 +1,56 @@ +using System; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + [TestFixtureOrmLite] + public class LimitExpressionTests : OrmLiteProvidersTestBase + { + public LimitExpressionTests(DialectContext context) : base(context) {} + + [Test] + public void Can_Skip_and_Take_UserAuth_Join() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var now = DateTime.UtcNow; + 5.Times(i => + { + var id = (int)db.Insert(new UserAuth + { + DisplayName = "Name" + i, + CreatedDate = now, + ModifiedDate = now, + }, selectIdentity: true); + + db.Insert(new UserAuthRole + { + UserAuthId = id, + Role = "role", + CreatedDate = now, + ModifiedDate = now, + }); + }); + + var query = db.From() + .LeftJoin((a, b) => a.Id == b.UserAuthId) + .Where(r => "role" == r.Role) + .Skip(2) + .Take(2) + .OrderBy("displayName".SqlColumn(DialectProvider)) + .SelectDistinct(); + + var results = db.Select(query); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(results.Map(x => x.DisplayName), Is.EqualTo(new[] { "Name2", "Name3" })); + + db.GetLastSql().Print(); + results.PrintDump(); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/LogicalExpressionsTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/LogicalExpressionsTest.cs index dd4c101e2..0d64f0704 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/LogicalExpressionsTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/LogicalExpressionsTest.cs @@ -2,16 +2,10 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class LogicalExpressionsTest : ExpressionsTestBase { - #region constants - - // Unlikely - // OpenDbConnection().Select(q => q.BoolColumn == (true & false)); - - #endregion - - #region variables + public LogicalExpressionsTest(DialectContext context) : base(context) {} [Test] public void Can_select_logical_and_variable_expression() @@ -21,20 +15,23 @@ public void Can_select_logical_and_variable_expression() var b = false; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a & b)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == (a & b)); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -45,20 +42,23 @@ public void Can_select_logical_or_variable_expression() var b = false; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a | b)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == (a | b)); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -69,43 +69,45 @@ public void Can_select_logical_xor_variable_expression() var b = false; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == (a ^ b)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == (a ^ b)); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } - #endregion - - #region method - [Test] public void Can_select_logical_and_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == (GetValue(true) & GetValue(false))); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == (GetValue(true) & GetValue(false))); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -118,34 +120,38 @@ public void Can_select_logical_or_method_expression() StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == (GetValue(true) | GetValue(false))); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == (GetValue(true) | GetValue(false))); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_logical_xor_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == (GetValue(true) ^ GetValue(false))); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == (GetValue(true) ^ GetValue(false))); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } - - #endregion - } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/MethodExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/MethodExpressionTests.cs index 8bc66425c..4f7128982 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/MethodExpressionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/MethodExpressionTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Service Stack LLC. All Rights Reserved. +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt @@ -7,31 +7,58 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class MethodExpressionTests : ExpressionsTestBase { + public MethodExpressionTests(DialectContext context) : base(context) {} + [Test] public void Can_select_ints_using_array_contains() { - var ints = new[] { 1, 2, 3 }; + var ints = new[] { 1, 20, 30 }; + var nullableInts = new int?[] { 5, 30, null, 20 }; using (var db = OpenDbConnection()) { - db.Select(x => ints.Contains(x.Id)); + var int10 = new TestType { IntColumn = 10 }; + var int20 = new TestType { IntColumn = 20 }; + var int30 = new TestType { IntColumn = 30 }; + + Init(db, 0, int10, int20, int30); + + var results = db.Select(x => ints.Contains(x.IntColumn)); + var resultsNullable = db.Select(x => nullableInts.Contains(x.IntColumn)); - Assert.That(db.GetLastSql(), Is.StringContaining("(1,2,3)")); + CollectionAssert.AreEquivalent(new[] { int20, int30 }, results); + CollectionAssert.AreEquivalent(new[] { int20, int30 }, resultsNullable); + + Assert.That(db.GetLastSql(), Does.Contain("(@0,@1,@2)"). + Or.Contain("(:0,:1,:2)")); } } [Test] public void Can_select_ints_using_list_contains() { - var ints = new[] { 1, 2, 3 }.ToList(); + var ints = new[] { 1, 20, 30 }.ToList(); + var nullableInts = new int?[] { 5, 30, null, 20 }.ToList(); using (var db = OpenDbConnection()) { - db.Select(x => ints.Contains(x.Id)); + var int10 = new TestType { IntColumn = 10 }; + var int20 = new TestType { IntColumn = 20 }; + var int30 = new TestType { IntColumn = 30 }; + + Init(db, 0, int10, int20, int30); - Assert.That(db.GetLastSql(), Is.StringContaining("(1,2,3)")); + var results = db.Select(x => ints.Contains(x.IntColumn)); + var resultsNullable = db.Select(x => nullableInts.Contains(x.IntColumn)); + + CollectionAssert.AreEquivalent(new[] { int20, int30 }, results); + CollectionAssert.AreEquivalent(new[] { int20, int30 }, resultsNullable); + + Assert.That(db.GetLastSql(), Does.Contain("(@0,@1,@2)"). + Or.Contain("(:0,:1,:2)")); } } @@ -42,9 +69,12 @@ public void Can_select_ints_using_empty_array_contains() using (var db = OpenDbConnection()) { - db.Select(x => ints.Contains(x.Id)); - - Assert.That(db.GetLastSql(), Is.StringContaining("(NULL)")); + Init(db, 5); + + var results = db.Select(x => ints.Contains(x.Id)); + + CollectionAssert.IsEmpty(results); + Assert.That(db.GetLastSql(), Does.Contain("(NULL)")); } } diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/MultiplicativeExpressionsTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/MultiplicativeExpressionsTest.cs index e34f16dfe..92b044ed9 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/MultiplicativeExpressionsTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/MultiplicativeExpressionsTest.cs @@ -2,63 +2,75 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class MultiplicativeExpressionsTest : ExpressionsTestBase { + public MultiplicativeExpressionsTest(DialectContext context) : base(context) {} + [Test] public void Can_select_constant_multiply_expression() { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; + var expected = new TestType + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 4 * 3); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 4 * 3); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_constant_divide_expression() { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; + var expected = new TestType + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 36 / 3); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 36 / 3); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_constant_modulo_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == 37 % 10); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == 37 % 10); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -69,20 +81,23 @@ public void Can_select_variable_multiply_expression() var b = 3; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; + var expected = new TestType + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == a * b); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == a * b); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -93,20 +108,23 @@ public void Can_select_variable_divide_expression() var b = 3; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; + var expected = new TestType + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == a / b); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == a / b); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -117,77 +135,89 @@ public void Can_select_variablemodulo_expression() var b = 10; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == a % b); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == a % b); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_method_multiply_expression() { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; + var expected = new TestType + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(4) * GetValue(3)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == GetValue(4) * GetValue(3)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_method_divide_expression() { - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; + var expected = new TestType + { + IntColumn = 12, + BoolColumn = true, + StringColumn = "test" + }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(36) / GetValue(3)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == GetValue(36) / GetValue(3)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_method_modulo_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 7, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == GetValue(37) % GetValue(10)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == GetValue(37) % GetValue(10)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/OrmLiteCountTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/OrmLiteCountTests.cs index bf1f66c53..504f632a1 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/OrmLiteCountTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/OrmLiteCountTests.cs @@ -8,9 +8,11 @@ namespace ServiceStack.OrmLite.Tests.Expression { - [TestFixture] - public class OrmLiteCountTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteCountTests : OrmLiteProvidersTestBase { + public OrmLiteCountTests(DialectContext context) : base(context) {} + [Test] public void CanDoCountWithInterface() { @@ -32,7 +34,6 @@ public void CanDoCountWithInterface() count = CountByColumn(db); Assert.That(count, Is.EqualTo(0)); - } } @@ -70,14 +71,12 @@ public void CanDoCountWithInterfaceAndPredicate() return db.Scalar(e => Sql.Count(request.Id)); } - long CountByColumn(IDbConnection db) where T : IHasCountColumn, new() { T request = new T(); return db.Scalar(e => Sql.Count(request.CountColumn)).Value; } - int Count(IDbConnection db, Expression> predicate) where T : IHasId, new() { return db.Scalar(e => Sql.Count(e.Id), predicate); diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/PrimaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/PrimaryExpressionsTest.cs index b299af953..857a74982 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/PrimaryExpressionsTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/PrimaryExpressionsTest.cs @@ -2,12 +2,15 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class PrimaryExpressionsTest : ExpressionsTestBase { + public PrimaryExpressionsTest(DialectContext context) : base(context) {} + private static class TestClass { - public static int StaticProperty { get { return 12; } } - public static int _staticField = 12; + public static int StaticProperty => 12; + public static int staticField = 12; } private class TestClass @@ -19,58 +22,59 @@ public static T StaticMethod(T value) public T Property { get; set; } - public T _field; + public readonly T field; - public T Mehtod() + public T Method() { - return _field; + return field; } public TestClass(T value) { Property = value; - _field = value; + field = value; } } private struct TestStruct { - public T Property { get { return _field; } } + public T Property => field; - public T _field; + public readonly T field; - public T Mehtod() + public T Method() { - return _field; + return field; } public TestStruct(T value) { - _field = value; + field = value; } } - #region int - [Test] public void Can_select_int_property_expression() { var tmp = new TestClass(12); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Property); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == tmp.Property); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -78,20 +82,23 @@ public void Can_select_int_field_expression() { var tmp = new TestClass(12); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp._field); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == tmp.field); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -99,96 +106,111 @@ public void Can_select_int_method_expression() { var tmp = new TestClass(12); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Mehtod()); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == tmp.Method()); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_static_int_property_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass.StaticProperty); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == TestClass.StaticProperty); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_static_int_field_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass._staticField); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == TestClass.staticField); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_static_int_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == TestClass.StaticMethod(12)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == TestClass.StaticMethod(12)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_int_new_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == new TestClass(12).Property); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == new TestClass(12).Property); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -196,20 +218,23 @@ public void Can_select_struct_int_field_expression() { var tmp = new TestStruct(12); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp._field); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == tmp.field); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -217,20 +242,23 @@ public void Can_select_struct_int_property_expression() { var tmp = new TestStruct(12); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Property); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == tmp.Property); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -238,46 +266,47 @@ public void Can_select_struct_int_method_expression() { var tmp = new TestStruct(12); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == tmp.Mehtod()); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == tmp.Method()); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } - #endregion int - - - #region bool - [Test] public void Can_select_bool_property_expression() { var tmp = new TestClass(false); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == tmp.Property); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == tmp.Property); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -285,20 +314,23 @@ public void Can_select_bool_field_expression() { var tmp = new TestClass(false); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == tmp._field); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == tmp.field); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -306,60 +338,67 @@ public void Can_select_bool_method_expression() { var tmp = new TestClass(false); - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == tmp.Mehtod()); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == tmp.Method()); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_static_bool_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == TestClass.StaticMethod(false)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == TestClass.StaticMethod(false)); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_bool_new_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == new TestClass(false).Property); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == new TestClass(false).Property); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 1); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 1); + CollectionAssert.Contains(actual, expected); + } } - - #endregion bool } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/RelationalExpressionsTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/RelationalExpressionsTest.cs index ece3eca86..19b92d2b9 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/RelationalExpressionsTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/RelationalExpressionsTest.cs @@ -2,81 +2,97 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] + public class RelationalExpressionsTest : ExpressionsTestBase { + public RelationalExpressionsTest(DialectContext context) : base(context) {} + [Test] public void Can_select_greater_than_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 1, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn > 1); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn > 1); - Assert.IsNotNull(actual); - Assert.AreEqual(10, actual.Count); - CollectionAssert.DoesNotContain(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(10, actual.Count); + CollectionAssert.DoesNotContain(actual, expected); + } } [Test] public void Can_select_greater_or_equal_than_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 1, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn >= 1); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn >= 1); - Assert.IsNotNull(actual); - Assert.AreEqual(11, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(11, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_smaller_than_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 1, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn < 1); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn < 1); - Assert.IsNotNull(actual); - Assert.AreEqual(0, actual.Count); + Assert.IsNotNull(actual); + Assert.AreEqual(0, actual.Count); + } } [Test] public void Can_select_smaller_or_equal_than_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 1, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn <= 1); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn <= 1); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/RestrictionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/RestrictionTests.cs new file mode 100644 index 000000000..206d83b2c --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/RestrictionTests.cs @@ -0,0 +1,80 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + [TestFixtureOrmLite] + public class ExpressionTests : OrmLiteProvidersTestBase + { + public ExpressionTests(DialectContext context) : base(context) {} + + public class Person + { + public Person() {} + + public Person(int id, string firstName, string lastName, int age) + { + Id = id; + FirstName = firstName; + LastName = lastName; + Age = age; + } + + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public int? Age { get; set; } + } + + public Person[] People = { + new Person(1, "Jimi", "Hendrix", 27), + new Person(2, "Janis", "Joplin", 27), + new Person(3, "Jim", "Morrisson", 27), + new Person(4, "Kurt", "Cobain", 27), + new Person(5, "Elvis", "Presley", 42), + new Person(6, "Michael", "Jackson", 50), + }; + + [Test] + public void Can_Chain_Expressions_Using_Or_and_And() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(People); + + var q = db.From(); + + q.Where(x => x.FirstName.StartsWith("Jim")).Or(x => x.LastName.StartsWith("Cob")); + + var results = db.Select(q); + Assert.AreEqual(3, results.Count); + + q.Where(); //clear where expression + + q.Where(x => x.FirstName.StartsWith("Jim")).And(x => x.LastName.StartsWith("Hen")); + results = db.Select(q); + + Assert.AreEqual(1, results.Count); + } + } + + [Test] + public void Can_get_rowcount_from_expression_visitor() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(People); + + var q = db.From(); + + q.Where(x => x.FirstName.StartsWith("Jim")).Or(x => x.LastName.StartsWith("Cob")); + + var count = db.Count(q); + + var results = db.Select(q); + Assert.AreEqual(count, results.Count); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SelectExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SelectExpressionTests.cs index 6db4a20af..ed919cee9 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/SelectExpressionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SelectExpressionTests.cs @@ -1,23 +1,26 @@ using System; using System.Linq; using NUnit.Framework; -using ServiceStack.Common.Tests.Models; using ServiceStack.DataAnnotations; using ServiceStack.OrmLite.Tests.Shared; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests.Expression { + + [TestFixtureOrmLite] public class SelectExpressionTests : ExpressionsTestBase { + public SelectExpressionTests(DialectContext context) : base(context) {} + [Test] public void Can_select_where_and_limit_expression() { - EstablishContext(20); + Init(20); using (var db = OpenDbConnection()) { - var rows = db.Select(q => q.Where(x => x.BoolColumn).Limit(5)); + var rows = db.Select(db.From().Where(x => x.BoolColumn).Limit(5)); db.GetLastSql().Print(); Assert.That(rows.Count, Is.EqualTo(5)); @@ -120,9 +123,9 @@ public void Can_select_Partial_SQL_Statements() Is.EquivalentTo(new[] { "Planes R Us", "We do everything!" })); - var partialDto = db.Select(q => - q.Select(x => new { x.Phone, x.CompanyName }) - .Where(x => x.ShipperTypeId == 2)); + var partialDto = db.Select(db.From() + .Select(x => new { x.Phone, x.CompanyName }) + .Where(x => x.ShipperTypeId == 2)); Assert.That(partialDto.Map(x => x.Phone), Is.EquivalentTo(new[] { "555-UNICORNS", "555-PLANES" })); @@ -130,9 +133,9 @@ public void Can_select_Partial_SQL_Statements() Is.EquivalentTo(new[] { "Planes R Us", "We do everything!" })); - partialDto = db.Select(q => - q.Select("Phone, " + "CompanyName".SqlColumn()) - .Where(x => x.ShipperTypeId == 2)); + partialDto = db.Select(db.From() + .Select("Phone, " + "CompanyName".SqlColumn(DialectProvider)) + .Where(x => x.ShipperTypeId == 2)); Assert.That(partialDto.Map(x => x.Phone), Is.EquivalentTo(new[] { "555-UNICORNS", "555-PLANES" })); @@ -141,38 +144,42 @@ public void Can_select_Partial_SQL_Statements() } } + public class Text + { + public string Name { get; set; } + } + [Test] public void Can_escape_wildcards() { using (var db = OpenDbConnection()) { - db.DropAndCreateTable(); - - db.Insert(new Poco { Name = "a" }); - db.Insert(new Poco { Name = "ab" }); - db.Insert(new Poco { Name = "a_c" }); - db.Insert(new Poco { Name = "a_cd" }); - db.Insert(new Poco { Name = "abcd" }); - db.Insert(new Poco { Name = "a%" }); - db.Insert(new Poco { Name = "a%b" }); - db.Insert(new Poco { Name = "a%bc" }); - db.Insert(new Poco { Name = "a\\" }); - db.Insert(new Poco { Name = "a\\b" }); - db.Insert(new Poco { Name = "a\\bc" }); - db.Insert(new Poco { Name = "a^" }); - db.Insert(new Poco { Name = "a^b" }); - db.Insert(new Poco { Name = "a^bc" }); - - Assert.That(db.Count(q => q.Name == "a_"), Is.EqualTo(0)); - Assert.That(db.Count(q => q.Name.StartsWith("a_")), Is.EqualTo(2)); - Assert.That(db.Count(q => q.Name.StartsWith("a%")), Is.EqualTo(3)); - Assert.That(db.Count(q => q.Name.StartsWith("a_c")), Is.EqualTo(2)); - Assert.That(db.Count(q => q.Name.StartsWith(@"a\")), Is.EqualTo(3)); - Assert.That(db.Count(q => q.Name.StartsWith(@"a\b")), Is.EqualTo(2)); - Assert.That(db.Count(q => q.Name.StartsWith(@"a^")), Is.EqualTo(3)); - Assert.That(db.Count(q => q.Name.StartsWith(@"a^b")), Is.EqualTo(2)); - Assert.That(db.Count(q => q.Name.EndsWith(@"_cd")), Is.EqualTo(1)); - Assert.That(db.Count(q => q.Name.Contains(@"abc")), Is.EqualTo(1)); + db.DropAndCreateTable(); + + db.Insert(new Text { Name = "a" }); + db.Insert(new Text { Name = "ab" }); + db.Insert(new Text { Name = "a_c" }); + db.Insert(new Text { Name = "a_cd" }); + db.Insert(new Text { Name = "abcd" }); + db.Insert(new Text { Name = "a%" }); + db.Insert(new Text { Name = "a%b" }); + db.Insert(new Text { Name = "a%bc" }); + db.Insert(new Text { Name = "a\\" }); + db.Insert(new Text { Name = "a\\b" }); + db.Insert(new Text { Name = "a\\bc" }); + db.Insert(new Text { Name = "a^" }); + db.Insert(new Text { Name = "a^b" }); + db.Insert(new Text { Name = "a^bc" }); + + Assert.That(db.Count(q => q.Name == "a_"), Is.EqualTo(0)); + Assert.That(db.Count(q => q.Name.StartsWith("a_")), Is.EqualTo(2)); + Assert.That(db.Count(q => q.Name.StartsWith("a%")), Is.EqualTo(3)); + Assert.That(db.Count(q => q.Name.StartsWith("a_c")), Is.EqualTo(2)); + Assert.That(db.Count(q => q.Name.StartsWith(@"a\")), Is.EqualTo(3)); + Assert.That(db.Count(q => q.Name.StartsWith(@"a\b")), Is.EqualTo(2)); + Assert.That(db.Count(q => q.Name.StartsWith(@"a^b")), Is.EqualTo(2)); + Assert.That(db.Count(q => q.Name.EndsWith(@"_cd")), Is.EqualTo(1)); + Assert.That(db.Count(q => q.Name.Contains(@"abc")), Is.EqualTo(1)); } } @@ -206,44 +213,96 @@ public void Can_perform_case_sensitive_likes() { using (var db = OpenDbConnection()) { - db.DropAndCreateTable(); + db.DropAndCreateTable(); - db.Insert(new Poco { Name = "Apple" }); - db.Insert(new Poco { Name = "ABCDE" }); - db.Insert(new Poco { Name = "abc" }); + db.Insert(new Text { Name = "Apple" }); + db.Insert(new Text { Name = "ABCDE" }); + db.Insert(new Text { Name = "abc" }); Func normalizedSql = () => - db.GetLastSql().Replace("\"", "").Replace("`", "").Replace("Name", "name"); + db.GetLastSql().Replace("\"", "").Replace("`", "").Replace("Name", "name").Replace("NAME", "name").Replace(":","@"); - db.Count(q => q.Name.StartsWith("A")); + var hold = OrmLiteConfig.StripUpperInLike; //.NET Core defaults to `true` + OrmLiteConfig.StripUpperInLike = false; + + db.Count(q => q.Name.StartsWith("A")); Assert.That(normalizedSql(), - Is.StringContaining("WHERE upper(name) like 'A%'")); + Does.Contain("upper(name) like @0".NormalizeSql())); - db.Count(q => q.Name.EndsWith("e")); + db.Count(q => q.Name.EndsWith("e")); Assert.That(normalizedSql(), - Is.StringContaining("WHERE upper(name) like '%E'")); + Does.Contain("upper(name) like @0".NormalizeSql())); - db.Count(q => q.Name.Contains("b")); + db.Count(q => q.Name.Contains("b")); Assert.That(normalizedSql(), - Is.StringContaining("WHERE upper(name) like '%B%'")); + Does.Contain("upper(name) like @0".NormalizeSql())); OrmLiteConfig.StripUpperInLike = true; - db.Count(q => q.Name.StartsWith("A")); + db.Count(q => q.Name.StartsWith("A")); Assert.That(normalizedSql(), - Is.StringContaining("WHERE name like 'A%'")); + Does.Contain("name like @0".NormalizeSql())); - db.Count(q => q.Name.EndsWith("e")); + db.Count(q => q.Name.EndsWith("e")); Assert.That(normalizedSql(), - Is.StringContaining("WHERE name like '%e'")); + Does.Contain("name like @0".NormalizeSql())); - db.Count(q => q.Name.Contains("b")); + db.Count(q => q.Name.Contains("b")); Assert.That(normalizedSql(), - Is.StringContaining("WHERE name like '%b%'")); + Does.Contain("name like @0".NormalizeSql())); - OrmLiteConfig.StripUpperInLike = false; + OrmLiteConfig.StripUpperInLike = hold; } } + + class Record + { + public int Id { get; set; } + + public string Name { get; set; } + } + + class Output + { + public int Id { get; set; } + + public string Name { get; set; } + } + + [Test] + public void Can_Select_Single_from_just_FROM_Expression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertAll(new Record[] { + new Record { Id = 1, Name = "Record 1" }, + }); + + var q = db.From(); + var results = db.Select(q); + Assert.That(results.Count, Is.EqualTo(1)); + + var result = db.Single(q); + Assert.That(result, Is.Not.Null); + } + } + + [Test] + public void Can_Select_Filed_Alias_Expression() + { + using var db = OpenDbConnection(); + var sql = db.From() + .Join((e, c) => e.CompanyId == c.Id) + .Select((e, c) => new { + Id = e.Id, + Name = e.Name, // test this property use alias + CompanyName = c.Name + }); + Assert.That(sql.SelectExpression.NormalizeSql(), Is.EqualTo( + "select employee.id, employee.employeename as name, company.companyname as companyname")); + } } public class Submission @@ -254,4 +313,19 @@ public class Submission public string Body { get; set; } } + public class Company + { + public int Id { get; set; } + [Alias("CompanyName")] + public string Name { get; set; } + } + + public class Employee + { + public int Id { get; set; } + public int CompanyId { get; set; } + [Alias("EmployeeName")] + public string Name { get; set; } + } + } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SelectFieldExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SelectFieldExpressionTests.cs new file mode 100644 index 000000000..ddf787a99 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SelectFieldExpressionTests.cs @@ -0,0 +1,176 @@ +using System.Linq; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + [TestFixtureOrmLite] + public class SelectFieldExpressionTests : OrmLiteProvidersTestBase + { + public SelectFieldExpressionTests(DialectContext context) : base(context) {} + + [Test] + public void Can_Select_Substring() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var results = db.Select(x => x.FirstName.Substring(1, 2) == "im"); + + results.PrintDump(); + + var expected = Person.Rockstars.Where(x => x.FirstName.Substring(1, 2) == "im").ToList(); + + Assert.That(results.Count, Is.EqualTo(expected.Count)); + Assert.That(results, Is.EquivalentTo(expected)); + + results = db.Select(x => x.FirstName.Substring(1) == "im"); + results.PrintDump(); + + expected = Person.Rockstars.Where(x => x.FirstName.Substring(1) == "im").ToList(); + Assert.That(results.Count, Is.EqualTo(expected.Count)); + Assert.That(results, Is.EquivalentTo(expected)); + } + } + + [Test] + public void Can_select_value_as_null() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var firstName = "Kurt"; + string lastName = null; + + var results = db.Select(db.From() + .Where(x => firstName == null || x.FirstName == firstName) + .And(x => lastName == null || x.LastName == lastName)); + + db.GetLastSql().Print(); + + results.PrintDump(); + + Assert.That(results[0].LastName, Is.EqualTo("Cobain")); + } + } + + [Test] + public void Can_select_partial_list_of_fields() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var results = db.Select(db.From().Select(new[] { "Id", "FirstName", "Age" })); + + db.GetLastSql().Print(); + + Assert.That(results.All(x => x.Id > 0)); + Assert.That(results.All(x => x.FirstName != null)); + Assert.That(results.All(x => x.LastName == null)); + Assert.That(results.Any(x => x.Age > 0)); + } + } + + [Test] + public void Can_select_partial_list_of_fields_case_insensitive() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var results = db.Select(db.From().Select(new[] { "id", "firstname", "age" })); + + db.GetLastSql().Print(); + + Assert.That(results.All(x => x.Id > 0)); + Assert.That(results.All(x => x.FirstName != null)); + Assert.That(results.All(x => x.LastName == null)); + Assert.That(results.Any(x => x.Age > 0)); + } + } + + [Test] + public void Does_ignore_invalid_fields() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var results = db.Select(db.From().Select(new[] { null, "Id", "unknown", "FirstName", "Age" })); + + db.GetLastSql().Print(); + + Assert.That(results.All(x => x.Id > 0)); + Assert.That(results.All(x => x.FirstName != null)); + Assert.That(results.All(x => x.LastName == null)); + Assert.That(results.Any(x => x.Age > 0)); + } + } + + [Test] + public void Can_select_fields_from_joined_table() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedAlbums); + + var q = db.From() + .Join((p, a) => p.Id == a.RockstarId) + .Select(new[] { "Id", "FirstName", "Age", "RockstarAlbumName" }); + + var results = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(results.All(x => x.Id > 0)); + Assert.That(results.All(x => x.FirstName != null)); + Assert.That(results.All(x => x.LastName == null)); + Assert.That(results.All(x => x.Age > 0)); + Assert.That(results.All(x => x.RockstarId == 0)); + Assert.That(results.All(x => x.RockstarAlbumName != null)); + } + } + + [Test] + public void Can_select_fields_from_joined_table_case_insensitive() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedRockstars); + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedAlbums); + + var q = db.From() + .Join() + .Select(new[] { "id", "firstname", "age", "rockstaralbumname", "rockstaralbumid" }); + + var results = db.Select(q); + + results.PrintDump(); + + db.GetLastSql().Print(); + + Assert.That(results.All(x => x.Id > 0)); + Assert.That(results.All(x => x.FirstName != null)); + Assert.That(results.All(x => x.LastName == null)); + Assert.That(results.All(x => x.Age > 0)); + Assert.That(results.All(x => x.RockstarId == 0)); + Assert.That(results.All(x => x.RockstarAlbumName != null)); + Assert.That(results.All(x => x.RockstarAlbumId >= 10)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SqlCustomTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SqlCustomTests.cs new file mode 100644 index 000000000..d7b5b6890 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SqlCustomTests.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + public class Custom1 + { + public int Id { get; set; } + public string Field1 { get; set; } + public string Field2 { get; set; } + + [CustomSelect(@"(CASE Custom1Id + WHEN 1 THEN 'On Hold' + WHEN 3 THEN 'In Treatment' + WHEN 7 THEN 'Awaiting First Appointment' + WHEN 8 THEN 'Discharged' + WHEN 12 THEN 'Closed - Awaiting Review' + ELSE 'Closed and Reviewed' + END)")] + public string StatusText { get; set; } + } + + public class Custom2 + { + public int Id { get; set; } + public int Custom1Id { get; set; } + public string Field3 { get; set; } + public string Field4 { get; set; } + } + + [TestFixtureOrmLite] + public class SqlCustomTests : OrmLiteProvidersTestBase + { + public SqlCustomTests(DialectContext context) : base(context) {} + + [Test] + [IgnoreDialect(Dialect.AnyPostgreSql, "Not supported")] + public void Can_use_CustomSelect_field_in_Typed_Query() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new Custom1 { Id = 1, Field1 = "f1", Field2 = "f2" }); + db.Insert(new Custom2 { Id = 2, Field3 = "f3", Field4 = "f4", Custom1Id = 1 }); + + var q = db.From() + .LeftJoin() + .Where(x => x.StatusText == "On Hold") + .Select((t1, t2) => new + { + t1, + t2, + }); + + var results = db.Select>(q); + + Assert.That(results[0]["StatusText"], Is.EqualTo("On Hold")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionDeleteTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionDeleteTests.cs new file mode 100644 index 000000000..aa981ba7e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionDeleteTests.cs @@ -0,0 +1,43 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + class PersonJoin + { + public int Id { get; set; } + public int PersonId { get; set; } + } + + [TestFixtureOrmLite] + public class SqlExpressionDeleteTests : OrmLiteProvidersTestBase + { + public SqlExpressionDeleteTests(DialectContext context) : base(context) {} + + [Test] + public void Can_delete_entity_with_join_expression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new Person { Id = 1, FirstName = "Foo" }); + db.Insert(new PersonJoin { Id = 1, PersonId = 1 }); + db.Insert(new PersonJoin { Id = 2, PersonId = 1 }); + + var q = db.From() + .Join((x, y) => x.Id == y.PersonId) + .Where(x => x.Id == 2); + + var record = db.Single(q); + + Assert.That(record.Id, Is.EqualTo(1)); + + db.Delete(q); + + Assert.That(db.Select().Count, Is.EqualTo(0)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionFilterTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionFilterTests.cs new file mode 100644 index 000000000..fa1f66a05 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionFilterTests.cs @@ -0,0 +1,33 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + [TestFixtureOrmLite] + public class SqlExpressionFilterTests : OrmLiteProvidersTestBase + { + public SqlExpressionFilterTests(DialectContext context) : base(context) {} + + [Test] + public void Can_enhance_SqlExpression_with_Custom_SqlFilter() + { + if (Dialect != Dialect.SqlServer) return; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertAll(Person.Rockstars); + + var q = db.From() + .Where(x => x.Age == 27) + .WithSqlFilter(sql => sql + "\noption (recompile)"); + + var rockstars = db.Select(q); + Assert.That(rockstars.Count, Is.EqualTo(4)); + + Assert.That(db.GetLastSql(), Does.Contain("option (recompile)")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionJoinTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionJoinTests.cs new file mode 100644 index 000000000..0d31d2b9f --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionJoinTests.cs @@ -0,0 +1,499 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + [TestFixtureOrmLite] + public class SqlExpressionJoinTests : ExpressionsTestBase + { + public SqlExpressionJoinTests(DialectContext context) : base(context) {} + + public class TableA + { + public int Id { get; set; } + public bool Bool { get; set; } + public string Name { get; set; } + } + + public class TableB + { + public int Id { get; set; } + public int TableAId { get; set; } + public string Name { get; set; } + } + + [Test] + public void Can_query_bools() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new TableA { Id = 1, Bool = false }); + db.Insert(new TableA { Id = 2, Bool = true }); + db.Insert(new TableB { Id = 1, TableAId = 1 }); + db.Insert(new TableB { Id = 2, TableAId = 2 }); + + var q = db.From() + .LeftJoin((a, b) => a.Id == b.Id) + .Where(a => !a.Bool); + + var result = db.Single(q); + var lastSql = db.GetLastSql(); + lastSql.Print(); + Assert.That(result.Id, Is.EqualTo(1)); + Assert.That(lastSql, Is.Not.Contains("NOT")); + + q = db.From() + .Where(a => !a.Bool) + .LeftJoin((a, b) => a.Id == b.Id); + + result = db.Single(q); + lastSql = db.GetLastSql(); + lastSql.Print(); + Assert.That(result.Id, Is.EqualTo(1)); + Assert.That(lastSql, Is.Not.Contains("NOT")); + + + q = db.From() + .Where(a => !a.Bool); + + result = db.Single(q); + lastSql = db.GetLastSql(); + lastSql.Print(); + Assert.That(result.Id, Is.EqualTo(1)); + Assert.That(lastSql, Is.Not.Contains("NOT")); + + q = db.From() + .LeftJoin((a, b) => a.Id == b.Id) + .Where(a => a.Bool); + + result = db.Single(q); + db.GetLastSql().Print(); + Assert.That(result.Id, Is.EqualTo(2)); + + q = db.From() + .Where(a => a.Bool) + .LeftJoin((a, b) => a.Id == b.Id); + + result = db.Single(q); + db.GetLastSql().Print(); + Assert.That(result.Id, Is.EqualTo(2)); + + + q = db.From() + .Where(a => a.Bool); + + result = db.Single(q); + db.GetLastSql().Print(); + Assert.That(result.Id, Is.EqualTo(2)); + } + } + + [Test] + public void Can_order_by_Joined_table() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new TableA { Id = 1, Bool = false }); + db.Insert(new TableA { Id = 2, Bool = true }); + db.Insert(new TableB { Id = 1, TableAId = 1, Name = "Z" }); + db.Insert(new TableB { Id = 2, TableAId = 2, Name = "A" }); + + var q = db.From() + .Join() + .OrderBy(x => x.Id); + + var rows = db.Select(q); + db.GetLastSql().Print(); + Assert.That(rows.Map(x => x.Id), Is.EqualTo(new[] { 1, 2 })); + + + q = db.From() + .Join() + .OrderBy(x => x.Name); + + rows = db.Select(q); + db.GetLastSql().Print(); + Assert.That(rows.Map(x => x.Id), Is.EqualTo(new[] { 2, 1 })); + } + } + + [Test] + public void Can_find_missing_rows_from_Left_Join_on_int_primary_key() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new TableA { Id = 1, Bool = true, Name = "A" }); + db.Insert(new TableA { Id = 2, Bool = true, Name = "B" }); + db.Insert(new TableA { Id = 3, Bool = true, Name = "C" }); + db.Insert(new TableB { Id = 1, TableAId = 1, Name = "Z" }); + +#pragma warning disable 472 + var missingNames = db.Column( + db.From() + .LeftJoin((a, b) => a.Id == b.Id) + .Where(b => b.Id == null) + .Select(a => a.Name)); +#pragma warning restore 472 + + Assert.That(missingNames, Is.EquivalentTo(new[] { "B", "C" })); + } + } + + public class CrossJoinTableA + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class CrossJoinTableB + { + public int Id { get; set; } + public int Value { get; set; } + } + + public class CrossJoinResult + { + public int CrossJoinTableAId { get; set; } + public string Name { get; set; } + public int CrossJoinTableBId { get; set; } + public int Value { get; set; } + + public override bool Equals(object obj) + { + var other = obj as CrossJoinResult; + if (other == null) + return false; + + return CrossJoinTableAId == other.CrossJoinTableAId && string.Equals(Name, other.Name) && CrossJoinTableBId == other.CrossJoinTableBId && Value == other.Value; + } + + public override int GetHashCode() => + (((23*37 + CrossJoinTableAId) * 37 + CrossJoinTableBId) * 37 + Value) + ^ Name.GetHashCode(); + } + + [Test] + public void Can_perform_a_crossjoin_without_a_join_expression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new CrossJoinTableA { Id = 1, Name = "Foo" }); + db.Insert(new CrossJoinTableA { Id = 2, Name = "Bar" }); + db.Insert(new CrossJoinTableB { Id = 5, Value = 3 }); + db.Insert(new CrossJoinTableB { Id = 6, Value = 42 }); + + var q = db.From() + .CrossJoin() + .OrderBy(x => x.Id) + .ThenBy(x => x.Id); + var result = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(result.Count, Is.EqualTo(4)); + var expected = new List + { + new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 5, Value = 3 }, + new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 6, Value = 42 }, + new CrossJoinResult { CrossJoinTableAId = 2, Name = "Bar", CrossJoinTableBId = 5, Value = 3}, + new CrossJoinResult { CrossJoinTableAId = 2, Name = "Bar", CrossJoinTableBId = 6, Value = 42}, + }; + Assert.That(result, Is.EquivalentTo(expected)); + } + } + + [Test] + public void Can_perform_a_crossjoin_with_a_join_expression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new CrossJoinTableA { Id = 1, Name = "Foo" }); + db.Insert(new CrossJoinTableA { Id = 2, Name = "Bar" }); + db.Insert(new CrossJoinTableB { Id = 5, Value = 3 }); + db.Insert(new CrossJoinTableB { Id = 6, Value = 42 }); + db.Insert(new CrossJoinTableB { Id = 7, Value = 56 }); + + var q = db.From().CrossJoin((a, b) => b.Id > 5 && a.Id < 2).OrderBy(x => x.Id).ThenBy(x => x.Id); + var result = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(result.Count, Is.EqualTo(2)); + var expected = new List + { + new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 6, Value = 42 }, + new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 7, Value = 56 }, + }; + Assert.That(result, Is.EquivalentTo(expected)); + } + } + + class JoinTest + { + public int Id { get; set; } + } + + class JoinTestChild + { + public int Id { get; set; } + + public int ParentId { get; set; } + + public bool IsActive { get; set; } + } + + [Test] + public void Issue_Bool_JoinTable_Expression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.InsertAll(new[] { + new JoinTest { Id = 1, }, + new JoinTest { Id = 2, } + }); + + db.InsertAll(new[] { + new JoinTestChild + { + Id = 1, + ParentId = 1, + IsActive = true + }, + new JoinTestChild + { + Id = 2, + ParentId = 2, + IsActive = false + } + }); + + var q = db.From(); + q.Where(x => !x.IsActive); + Assert.That(db.Select(q).Count, Is.EqualTo(1)); + + var qSub = db.From(); + qSub.Join((x, y) => x.Id == y.ParentId); + qSub.Where(x => !x.IsActive); // This line is a bug! + Assert.That(db.Select(qSub).Count, Is.EqualTo(1)); + } + } + + public class Invoice + { + public int Id { get; set; } + + public int WorkflowId { get; set; } + + public int DocumentId { get; set; } + + public int PageCount { get; set; } + + public string DocumentStatus { get; set; } + + public string Extra { get; set; } + } + + public class UsagePageInvoice + { + public int Id { get; set; } + public int InvoiceId { get; set; } + } + + [Test] + public void Can_select_individual_columns() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new Invoice + { + Id = 1, + WorkflowId = 2, + DocumentId = 3, + PageCount = 4, + DocumentStatus = "a", + Extra = "EXTRA" + }); + +#pragma warning disable 472 + var q = db.From() + .LeftJoin((i, upi) => i.Id == upi.InvoiceId) + .Where(i => (i.DocumentStatus == "a" || i.DocumentStatus == "b")) + .And(upi => upi.Id == null) + .Select(c => new { c.Id, c.WorkflowId, c.DocumentId, c.DocumentStatus, c.PageCount }); +#pragma warning restore 472 + + var result = db.Select(q).First(); + + Assert.That(result.Id, Is.EqualTo(1)); + Assert.That(result.WorkflowId, Is.EqualTo(2)); + Assert.That(result.DocumentId, Is.EqualTo(3)); + Assert.That(result.PageCount, Is.EqualTo(4)); + Assert.That(result.DocumentStatus, Is.EqualTo("a")); + Assert.That(result.Extra, Is.Null); + } + } + + private class JoinSelectResults1 + { + // From TableA + public int Id { get; set; } + public bool Bool { get; set; } + public string Name { get; set; } + + // From TableB + public int TableAId { get; set; } + + public override bool Equals(object obj) + { + var other = (JoinSelectResults1)obj; + return Id == other.Id && Bool == other.Bool && Name == other.Name && TableAId == other.TableAId; + } + + public override int GetHashCode() => + ((23*37 + Id) * 37 + Name.GetHashCode()) + ^ (Bool ? 65535 : 0); + } + + private class JoinSelectResults2 + { + // From TableA + public int Id { get; set; } + public bool Bool { get; set; } + public string Name { get; set; } + + // From TableB + public int TableBId { get; set; } + public string TableBName { get; set; } + + public override bool Equals(object obj) + { + var other = (JoinSelectResults2)obj; + return Id == other.Id && Bool == other.Bool && Name == other.Name && TableBId == other.TableBId && TableBName == other.TableBName; + } + + public override int GetHashCode() => + ((23*37 + Id) * 37 + TableBId) + ^ Name.GetHashCode() + ^ TableBName.GetHashCode() + ^ (Bool ? 65535 : 0); + + } + + private class JoinSelectResults3 + { + // From TableA + public int TableA_Id { get; set; } + public bool TableA_Bool { get; set; } + public string TableA_Name { get; set; } + + // From TableB + public int Id { get; set; } + public string TableBName { get; set; } + + public override bool Equals(object obj) + { + var other = (JoinSelectResults3)obj; + return TableA_Id == other.TableA_Id && TableA_Bool == other.TableA_Bool && TableA_Name == other.TableA_Name + && Id == other.Id && TableBName == other.TableBName; + } + + public override int GetHashCode() => + ((23*37 + TableA_Id) * 37 + Id) + ^ TableA_Name.GetHashCode() + ^ TableBName.GetHashCode() + ^ (TableA_Bool ? 65535 : 0); + } + + [Test] + public void Can_select_entire_tables() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new TableA { Id = 1, Bool = false, Name = "NameA1" }); + db.Insert(new TableA { Id = 2, Bool = true, Name = "NameA2" }); + db.Insert(new TableB { Id = 1, TableAId = 1, Name = "NameB1" }); + db.Insert(new TableB { Id = 2, TableAId = 2, Name = "NameB2" }); + db.Insert(new TableB { Id = 3, TableAId = 2, Name = "NameB3" }); + + try + { + // Select all columns from TableA + + var q1 = db.From() + .Join() + .Select((a, b) => new { a, b.TableAId }) + .OrderBy(x => x.Id); + + var rows1 = db.Select(q1); + var expected1 = new[] + { + new JoinSelectResults1 { Id = 1, Bool = false, Name = "NameA1", TableAId = 1 }, + new JoinSelectResults1 { Id = 2, Bool = true, Name = "NameA2", TableAId = 2 }, + new JoinSelectResults1 { Id = 2, Bool = true, Name = "NameA2", TableAId = 2 }, + }; + Assert.That(rows1, Is.EqualTo(expected1)); + + // Same, but use column aliases for some columns from TableB whose names would conflict otherwise + + var q2 = db.From() + .Join() + .Select((a, b) => new { a, TableBId = b.Id, TableBName = b.Name }); + + var rows2 = db.Select(q2).OrderBy(r => r.Id).ThenBy(r => r.TableBId); + var expected2 = new[] + { + new JoinSelectResults2 { Id = 1, Bool = false, Name = "NameA1", TableBId = 1, TableBName = "NameB1" }, + new JoinSelectResults2 { Id = 2, Bool = true, Name = "NameA2", TableBId = 2, TableBName = "NameB2" }, + new JoinSelectResults2 { Id = 2, Bool = true, Name = "NameA2", TableBId = 3, TableBName = "NameB3" }, + }; + Assert.That(rows2, Is.EqualTo(expected2)); + + // Use column alias prefixes for all columns in TableA + + var q3 = db.From() + .Join() + .Select((a, b) => new { TableA_ = a, b.Id, TableBName = b.Name }); + + var rows3 = db.Select(q3).OrderBy(r => r.TableA_Id).ThenBy(r => r.Id).ToList(); + var expected3 = new[] + { + new JoinSelectResults3 { TableA_Id = 1, TableA_Bool = false, TableA_Name = "NameA1", Id = 1, TableBName = "NameB1" }, + new JoinSelectResults3 { TableA_Id = 2, TableA_Bool = true, TableA_Name = "NameA2", Id = 2, TableBName = "NameB2" }, + new JoinSelectResults3 { TableA_Id = 2, TableA_Bool = true, TableA_Name = "NameA2", Id = 3, TableBName = "NameB3" }, + }; + Assert.That(rows3, Is.EqualTo(expected3)); + } + finally + { + db.GetLastSql().Print(); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionParamTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionParamTests.cs new file mode 100644 index 000000000..f78745f0e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionParamTests.cs @@ -0,0 +1,31 @@ +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + [TestFixtureOrmLite] + public class SqlExpressionParamTests : OrmLiteProvidersTestBase + { + public SqlExpressionParamTests(DialectContext context) : base(context) {} + + [Test] + public void Can_add_DbParam_to_SqlExpression() + { + using (var db = OpenDbConnection()) + { + SqlExpressionTests.InitLetters(db); + + var q = db.From() + .UnsafeWhere("Letter = {0}".Fmt(DialectProvider.GetParam("p1"))); + + q.Params.Add(q.CreateParam("p1", "B")); + + var results = db.Select(q); + + results.PrintDump(); + + Assert.That(results.Count, Is.EqualTo(2)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionTests.cs index 443f8f582..c8736f877 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; -using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.DataAnnotations; using ServiceStack.OrmLite.Tests.UseCase; @@ -16,6 +15,9 @@ public class LetterFrequency public int Id { get; set; } public string Letter { get; set; } + + [Alias("AliasValue")] + public int Value { get; set; } } public class LetterWeighting @@ -33,13 +35,27 @@ public class LetterStat public int Weighting { get; set; } } + [TestFixtureOrmLite] public class SqlExpressionTests : ExpressionsTestBase { - private static void InitLetters(IDbConnection db) + public SqlExpressionTests(DialectContext context) : base(context) {} + + private int letterFrequencyMaxId; + private int letterFrequencyMinId; + private int letterFrequencySumId; + + private void GetIdStats(IDbConnection db) + { + letterFrequencyMaxId = db.Scalar(db.From().Select(Sql.Max("Id"))); + letterFrequencyMinId = db.Scalar(db.From().Select(Sql.Min("Id"))); + letterFrequencySumId = db.Scalar(db.From().Select(Sql.Sum("Id"))); + } + + public static int InitLetters(IDbConnection db) { db.DropAndCreateTable(); - db.Insert(new LetterFrequency { Letter = "A" }); + var firstId = db.Insert(new LetterFrequency { Letter = "A" }, selectIdentity: true); db.Insert(new LetterFrequency { Letter = "B" }); db.Insert(new LetterFrequency { Letter = "B" }); db.Insert(new LetterFrequency { Letter = "C" }); @@ -49,6 +65,7 @@ private static void InitLetters(IDbConnection db) db.Insert(new LetterFrequency { Letter = "D" }); db.Insert(new LetterFrequency { Letter = "D" }); db.Insert(new LetterFrequency { Letter = "D" }); + return (int)firstId; } [Test] @@ -56,7 +73,10 @@ public void Can_select_Dictionary_with_SqlExpression() { using (var db = OpenDbConnection()) { - InitLetters(db); + var firstId = InitLetters(db); + var expected = new Dictionary { + { "A", 1 }, { "B", 2 }, { "C", 3 }, + }; var query = db.From() .Select(x => new { x.Letter, count = Sql.Count("*") }) @@ -65,10 +85,28 @@ public void Can_select_Dictionary_with_SqlExpression() query.ToSelectStatement().Print(); - var map = new SortedDictionary(db.Dictionary(query)); - Assert.That(map.EquivalentTo(new Dictionary { - { "A", 1 }, { "B", 2 }, { "C", 3 }, - })); + var map = db.Dictionary(query); + Assert.That(map.EquivalentTo(expected)); + + // Same, but group by an anonymous type using an alias - this should not translate to "GROUP BY TheLetter AS Letter", which is invalid SQL + + query = db.From() + .Select(x => new { x.Letter, count = Sql.Count("*") }) + .Where(q => q.Letter != "D") + .GroupBy(x => new { TheLetter = x.Letter }); + + map = db.Dictionary(query); + Assert.That(map.EquivalentTo(expected)); + + // Now group by all columns without listing them - effectively "SELECT DISTINCT *" + + query = db.From() + .Where(q => q.Letter != "D") + .GroupBy(x => new { x }) + .Select(x => new { x.Id }); + + var list = db.SqlList(query); + Assert.That(list, Is.EquivalentTo(new[] { 0, 1, 2, 3, 4, 5 }.AdjustIds(firstId))); } } @@ -90,6 +128,186 @@ public void Can_select_ColumnDistinct_with_SqlExpression() } } + [Test] + public void Can_Select_as_List_Object() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + GetIdStats(db); + + var query = db.From() + .Select("COUNT(*), MAX(Id), MIN(Id), Sum(Id)"); + + query.ToSelectStatement().Print(); + + var results = db.Select>(query); + + Assert.That(results.Count, Is.EqualTo(1)); + + var result = results[0]; + CheckDbTypeInsensitiveEquivalency(result); + + var single = db.Single>(query); + CheckDbTypeInsensitiveEquivalency(single); + + result.PrintDump(); + } + } + + [Test] + public void Can_Select_as_List_ValueTuple() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + GetIdStats(db); + + //var a = new ValueTuple(); + //a.Item1 = 1; + + var query = db.From() + .Select("COUNT(*), MIN(Letter), MAX(Letter), Sum(Id)"); + + var results = db.Select<(int count, string min, string max, int sum)>(query); + + Assert.That(results.Count, Is.EqualTo(1)); + + var result = results[0]; + Assert.That(result.count, Is.EqualTo(10)); + Assert.That(result.min, Is.EqualTo("A")); + Assert.That(result.max, Is.EqualTo("D")); + Assert.That(result.sum, Is.EqualTo(letterFrequencySumId)); + + var single = db.Single<(int count, string min, string max, int sum)>(query); + Assert.That(single.count, Is.EqualTo(10)); + Assert.That(single.min, Is.EqualTo("A")); + Assert.That(single.max, Is.EqualTo("D")); + Assert.That(single.sum, Is.EqualTo(letterFrequencySumId)); + + single = db.Single<(int count, string min, string max, int sum)>( + db.From() + .Select(x => new + { + Count = Sql.Count("*"), + Min = Sql.Min(x.Letter), + Max = Sql.Max(x.Letter), + Sum = Sql.Sum(x.Id) + })); + + Assert.That(single.count, Is.EqualTo(10)); + Assert.That(single.min, Is.EqualTo("A")); + Assert.That(single.max, Is.EqualTo("D")); + Assert.That(single.sum, Is.EqualTo(letterFrequencySumId)); + } + } + + [Test] + public async System.Threading.Tasks.Task Can_Select_as_List_ValueTuple_Async() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + GetIdStats(db); + + //var a = new ValueTuple(); + //a.Item1 = 1; + + var query = db.From() + .Select("COUNT(*), MIN(Letter), MAX(Letter), Sum(Id)"); + + var results = await db.SelectAsync<(int count, string min, string max, int sum)>(query); + + Assert.That(results.Count, Is.EqualTo(1)); + + var result = results[0]; + Assert.That(result.count, Is.EqualTo(10)); + Assert.That(result.min, Is.EqualTo("A")); + Assert.That(result.max, Is.EqualTo("D")); + Assert.That(result.sum, Is.EqualTo(letterFrequencySumId)); + + var single = await db.SingleAsync<(int count, string min, string max, int sum)>(query); + Assert.That(single.count, Is.EqualTo(10)); + Assert.That(single.min, Is.EqualTo("A")); + Assert.That(single.max, Is.EqualTo("D")); + Assert.That(single.sum, Is.EqualTo(letterFrequencySumId)); + + single = await db.SingleAsync<(int count, string min, string max, int sum)>( + db.From() + .Select(x => new + { + Count = Sql.Count("*"), + Min = Sql.Min(x.Letter), + Max = Sql.Max(x.Letter), + Sum = Sql.Sum(x.Id) + })); + + Assert.That(single.count, Is.EqualTo(10)); + Assert.That(single.min, Is.EqualTo("A")); + Assert.That(single.max, Is.EqualTo("D")); + Assert.That(single.sum, Is.EqualTo(letterFrequencySumId)); + } + } + + private void CheckDbTypeInsensitiveEquivalency(List result) + { + Assert.That(Convert.ToInt64(result[0]), Is.EqualTo(10)); + Assert.That(Convert.ToInt64(result[1]), Is.EqualTo(letterFrequencyMaxId)); + Assert.That(Convert.ToInt64(result[2]), Is.EqualTo(letterFrequencyMinId)); + Assert.That(Convert.ToInt64(result[3]), Is.EqualTo(letterFrequencySumId)); + } + + [Test] + public void Can_Select_as_Dictionary_Object() + { + using (var db = OpenDbConnection()) + { + InitLetters(db); + GetIdStats(db); + + var query = db.From() + .Select("COUNT(*) \"Count\", MAX(Id) \"Max\", MIN(Id) \"Min\", Sum(Id) \"Sum\""); + + query.ToSelectStatement().Print(); + + var results = db.Select>(query); + + Assert.That(results.Count, Is.EqualTo(1)); + + var result = results[0]; + CheckDbTypeInsensitiveEquivalency(result); + + var single = db.Single>(query); + CheckDbTypeInsensitiveEquivalency(single); + + results.PrintDump(); + } + } + + private void CheckDbTypeInsensitiveEquivalency(Dictionary result) + { + Assert.That(Convert.ToInt64(result["Count"]), Is.EqualTo(10)); + Assert.That(Convert.ToInt64(result["Max"]), Is.EqualTo(letterFrequencyMaxId)); + Assert.That(Convert.ToInt64(result["Min"]), Is.EqualTo(letterFrequencyMinId)); + Assert.That(Convert.ToInt64(result["Sum"]), Is.EqualTo(letterFrequencySumId)); + } + + [Test] + public void Can_select_Object() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var id = db.Insert(new LetterFrequency { Id = 1, Letter = "A" }, selectIdentity: true); + + var result = db.Scalar(db.From().Select(x => x.Letter)); + Assert.That(result, Is.EqualTo("A")); + + result = db.Scalar(db.From().Select(x => x.Id)); + Assert.That(Convert.ToInt64(result), Is.EqualTo(id)); + } + } + [Test] public void Can_select_limit_with_SqlExpression() { @@ -142,10 +360,12 @@ public void Can_select_limit_with_JoinSqlBuilder() db.Insert(new LetterWeighting { LetterFrequencyId = id, Weighting = ++i * 10 }); }); +#pragma warning disable 618 var joinFn = new Func>(() => - new JoinSqlBuilder() + new JoinSqlBuilder(DialectProvider) .Join(x => x.Id, x => x.LetterFrequencyId) ); +#pragma warning restore 618 var results = db.Select(joinFn()); Assert.That(results.Count, Is.EqualTo(5)); @@ -207,11 +427,6 @@ public void Can_add_basic_joins_with_SqlExpression() .Join((x, y) => x.Id == y.LetterFrequencyId)); db.GetLastSql().Print(); Assert.That(results.Count, Is.EqualTo(5)); - - results = db.Select(q => - q.Join((x, y) => x.Id == y.LetterFrequencyId)); - db.GetLastSql().Print(); - Assert.That(results.Count, Is.EqualTo(5)); } } @@ -232,16 +447,16 @@ public void Can_do_ToCountStatement_with_SqlExpression_if_where_expression_refer .Join() .Where(x => x.Id > 0); - var count = db.SqlScalar(expr.ToCountStatement()); + var count = db.SqlScalar(expr.ToCountStatement(), expr.Params.ToDictionary(param => param.ParameterName, param => param.Value)); Assert.That(count, Is.GreaterThan(0)); - count = db.Count(q => q.Join().Where(x => x.Id > 0)); + count = db.Count(db.From().Join().Where(x => x.Id > 0)); Assert.That(count, Is.GreaterThan(0)); Assert.That( - db.Exists(q => q.Join().Where(x => x.Id > 0))); + db.Exists(db.From().Join().Where(x => x.Id > 0))); } } @@ -278,6 +493,63 @@ public void Can_do_ToCountStatement_with_SqlExpression_if_expression_has_groupby } } + [Test] + public void Can_select_RowCount_with_db_params() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new LetterFrequency { Letter = "A" }); + db.Insert(new LetterFrequency { Letter = "A" }); + db.Insert(new LetterFrequency { Letter = "A" }); + db.Insert(new LetterFrequency { Letter = "B" }); + db.Insert(new LetterFrequency { Letter = "B" }); + db.Insert(new LetterFrequency { Letter = "B" }); + db.Insert(new LetterFrequency { Letter = "B" }); + + var query = db.From() + .Where(x => x.Letter == "B") + .Select(x => x.Letter); + + var rowCount = db.RowCount(query); + db.GetLastSql().Print(); + Assert.That(rowCount, Is.EqualTo(4)); + + var table = nameof(LetterFrequency).SqlTable(DialectProvider); + + rowCount = db.RowCount("SELECT * FROM {0} WHERE Letter = @p1".PreNormalizeSql(db).Fmt(table), new { p1 = "B" }); + Assert.That(rowCount, Is.EqualTo(4)); + + rowCount = db.RowCount("SELECT * FROM {0} WHERE Letter = @p1".PreNormalizeSql(db).Fmt(table), + new[] { db.CreateParam("p1", "B") }); + Assert.That(rowCount, Is.EqualTo(4)); + } + } + + [Test] + public void Can_get_RowCount_if_expression_has_OrderBy() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new LetterFrequency { Letter = "A" }); + db.Insert(new LetterFrequency { Letter = "B" }); + db.Insert(new LetterFrequency { Letter = "B" }); + + var query = db.From() + .Select(x => x.Letter) + .OrderBy(x => x.Id); + + var rowCount = db.RowCount(query); + Assert.That(rowCount, Is.EqualTo(3)); + + rowCount = db.Select(query).Count; + Assert.That(rowCount, Is.EqualTo(3)); + } + } + [Test] public void Can_OrderBy_Fields_with_different_sort_directions() { @@ -292,25 +564,58 @@ public void Can_OrderBy_Fields_with_different_sort_directions() insertedIds.Add(db.Insert(new LetterFrequency { Letter = letter }, selectIdentity: true)); }); - var rows = db.Select(q => q.OrderByFields("Letter", "Id")); + var rows = db.Select(db.From().OrderByFields("Letter", "Id")); Assert.That(rows.Map(x => x.Letter), Is.EquivalentTo("A,B,B,C,C,C,D,D,E".Split(','))); Assert.That(rows.Map(x => x.Id), Is.EquivalentTo(insertedIds)); - rows = db.Select(q => q.OrderByFields("Letter", "-Id")); + rows = db.Select(db.From().OrderByFields("Letter", "-Id")); Assert.That(rows.Map(x => x.Letter), Is.EquivalentTo("A,B,B,C,C,C,D,D,E".Split(','))); Assert.That(rows.Map(x => x.Id), Is.EquivalentTo(insertedIds)); - rows = db.Select(q => q.OrderByFieldsDescending("Letter", "-Id")); + rows = db.Select(db.From().OrderByFieldsDescending("Letter", "-Id")); Assert.That(rows.Map(x => x.Letter), Is.EquivalentTo("E,D,D,C,C,C,B,B,A".Split(','))); Assert.That(rows.Map(x => x.Id), Is.EquivalentTo(Enumerable.Reverse(insertedIds))); } } + [Test] + public void Can_Select_with_List_Contains() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var insertedIds = "A,B,B,C,C,C,D,D,E".Split(',').Map(letter => + db.Insert(new LetterFrequency { Letter = letter }, selectIdentity: true)); + + var first3Ids = insertedIds.Take(3).ToList(); + var letters = db.Column(db.From() + .Where(x => first3Ids.Contains(x.Id)) + .OrderBy(x => x.Id) + .Select(x => x.Letter)); + + Assert.That(letters.Join(","), Is.EqualTo("A,B,B")); + + letters = db.Column(db.From() + .Where(x => !first3Ids.Contains(x.Id)) + .OrderBy(x => x.Id) + .Select(x => x.Letter)); + + db.GetLastSql().Print(); + + Assert.That(letters.Join(","), Is.EqualTo("C,C,C,D,D,E")); + } + } + [Test] public void Can_select_limit_on_Table_with_References() { //This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' - if (Dialect == Dialect.MySql) return; + if (Dialect == Dialect.AnyMySql) return; + + //Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. + if ((Dialect & Dialect.AnySqlServer) == Dialect) + return; using (var db = OpenDbConnection()) { @@ -325,7 +630,7 @@ public void Can_select_limit_on_Table_with_References() var customer2 = LoadReferencesTests.GetCustomerWithOrders("2"); db.Save(customer2, references: true); - var results = db.LoadSelect(q => q + var results = db.LoadSelect(db.From() .OrderBy(x => x.Id) .Limit(1, 1)); @@ -336,7 +641,7 @@ public void Can_select_limit_on_Table_with_References() Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street")); Assert.That(results[0].Orders.Count, Is.EqualTo(2)); - results = db.LoadSelect(q => q + results = db.LoadSelect(db.From() .Join() .OrderBy(x => x.Id) .Limit(1, 1)); @@ -350,200 +655,30 @@ public void Can_select_limit_on_Table_with_References() } } - public class TableA - { - public int Id { get; set; } - public bool Bool { get; set; } - public string Name { get; set; } - } - - public class TableB - { - public int Id { get; set; } - public int TableAId { get; set; } - public string Name { get; set; } - } - [Test] - public void Can_query_bools() + public void Can_select_subselect() { using (var db = OpenDbConnection()) { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - db.Insert(new TableA { Id = 1, Bool = false }); - db.Insert(new TableB { Id = 1, TableAId = 1 }); - - var q = db.From() - .LeftJoin((a, b) => a.Id == b.Id) - .Where(a => !a.Bool); - - var result = db.Single(q); - db.GetLastSql().Print(); - Assert.That(result.Id, Is.EqualTo(1)); - - q = db.From() - .Where(a => !a.Bool) - .LeftJoin((a, b) => a.Id == b.Id); - - result = db.Single(q); - db.GetLastSql().Print(); - Assert.That(result.Id, Is.EqualTo(1)); - - - q = db.From() - .Where(a => !a.Bool); - - result = db.Single(q); - db.GetLastSql().Print(); - Assert.That(result.Id, Is.EqualTo(1)); - } - } - - [Test] - public void Can_order_by_Joined_table() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - db.Insert(new TableA { Id = 1, Bool = false }); - db.Insert(new TableA { Id = 2, Bool = true }); - db.Insert(new TableB { Id = 1, TableAId = 1, Name = "Z" }); - db.Insert(new TableB { Id = 2, TableAId = 2, Name = "A" }); - - var q = db.From() - .Join() - .OrderBy(x => x.Id); - - var rows = db.Select(q); - db.GetLastSql().Print(); - Assert.That(rows.Map(x => x.Id), Is.EqualTo(new[] { 1, 2 })); - - - q = db.From() - .Join() - .OrderBy(x => x.Name); - - rows = db.Select(q); - db.GetLastSql().Print(); - Assert.That(rows.Map(x => x.Id), Is.EqualTo(new[] { 2, 1 })); - } - } - - [Test] - public void Can_find_missing_rows_from_Left_Join_on_int_primary_key() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - db.Insert(new TableA { Id = 1, Bool = true, Name = "A" }); - db.Insert(new TableA { Id = 2, Bool = true, Name = "B" }); - db.Insert(new TableA { Id = 3, Bool = true, Name = "C" }); - db.Insert(new TableB { Id = 1, TableAId = 1, Name = "Z" }); - - var missingNames = db.Column( - db.From() - .LeftJoin((a, b) => a.Id == b.Id) - .Where(b => b.Id == null) - .Select(a => a.Name)); - - Assert.That(missingNames, Is.EquivalentTo(new[] { "B", "C" })); - } - } - - public class CrossJoinTableA - { - public int Id { get; set; } - public string Name { get; set; } - } - - public class CrossJoinTableB - { - public int Id { get; set; } - public int Value { get; set; } - } - - public class CrossJoinResult - { - public int CrossJoinTableAId { get; set; } - public string Name { get; set; } - public int CrossJoinTableBId { get; set; } - public int Value { get; set; } - - public override bool Equals(object obj) - { - var other = obj as CrossJoinResult; - if(other == null) - return false; - - return CrossJoinTableAId == other.CrossJoinTableAId && string.Equals(Name, other.Name) && CrossJoinTableBId == other.CrossJoinTableBId && Value == other.Value; - } - } - - [Test] - public void Can_perform_a_crossjoin_without_a_join_expression() - { - using(var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - db.Insert(new CrossJoinTableA {Id = 1, Name = "Foo"}); - db.Insert(new CrossJoinTableA {Id = 2, Name = "Bar"}); - db.Insert(new CrossJoinTableB {Id = 5, Value = 3}); - db.Insert(new CrossJoinTableB {Id = 6, Value = 42}); - - var q = db.From() - .CrossJoin() - .OrderBy(x => x.Id) - .ThenBy(x => x.Id); - var result = db.Select(q); - - db.GetLastSql().Print(); - - Assert.That(result.Count, Is.EqualTo(4)); - var expected = new List - { - new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 5, Value = 3 }, - new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 6, Value = 42 }, - new CrossJoinResult { CrossJoinTableAId = 2, Name = "Bar", CrossJoinTableBId = 5, Value = 3}, - new CrossJoinResult { CrossJoinTableAId = 2, Name = "Bar", CrossJoinTableBId = 6, Value = 42}, - }; - Assert.That(result, Is.EquivalentTo(expected)); - } - } - - [Test] - public void Can_perform_a_crossjoin_with_a_join_expression() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - db.Insert(new CrossJoinTableA { Id = 1, Name = "Foo" }); - db.Insert(new CrossJoinTableA { Id = 2, Name = "Bar" }); - db.Insert(new CrossJoinTableB { Id = 5, Value = 3 }); - db.Insert(new CrossJoinTableB { Id = 6, Value = 42 }); - db.Insert(new CrossJoinTableB { Id = 7, Value = 56 }); - - var q = db.From().CrossJoin((a, b) => b.Id > 5 && a.Id < 2).OrderBy(x => x.Id).ThenBy(x => x.Id); - var result = db.Select(q); - - db.GetLastSql().Print(); + db.DropAndCreateTable(); - Assert.That(result.Count, Is.EqualTo(2)); - var expected = new List - { - new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 6, Value = 42 }, - new CrossJoinResult { CrossJoinTableAId = 1, Name = "Foo", CrossJoinTableBId = 7, Value = 56 }, - }; - Assert.That(result, Is.EquivalentTo(expected)); + var insertedIds = "A,B,B,C,C,C,D,D,E".Split(',').Map(letter => + db.Insert(new LetterFrequency { Letter = letter }, selectIdentity: true)); + + var q = db.From(db.TableAlias("x")); + q.Where(x => x.Letter == Sql.TableAlias(x.Letter, "obj")); + var subSql = q.Select(Sql.Count("*")).ToSelectStatement(); + + var rows = db.Select>(db.From(db.TableAlias("obj")) + .Where(x => x.Letter == "C") + .Select(x => new { + x, + count = Sql.Custom($"({subSql})"), + })); + + rows.PrintDump(); + Assert.That(rows.Count, Is.EqualTo(3)); + Assert.That(rows.All(x => x["count"].ConvertTo() == 3)); } } } diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionWhereTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionWhereTests.cs new file mode 100644 index 000000000..b8d2d5960 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionWhereTests.cs @@ -0,0 +1,154 @@ +using System.Data; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Expression +{ + [TestFixtureOrmLite] + public class SqlExpressionWhereTests : OrmLiteProvidersTestBase + { + public SqlExpressionWhereTests(DialectContext context) : base(context) {} + + private static void Init(IDbConnection db) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new Table1 {Id = 1, String = "A"}); + db.Insert(new Table2 {Id = 1, String = "A"}); + db.Insert(new Table3 {Id = 1, String = "A"}); + db.Insert(new Table4 {Id = 1, String = "A"}); + db.Insert(new Table5 {Id = 1, String = "A"}); + } + + [Test] + public void Can_use_Where_on_multiple_tables() + { + using (var db = OpenDbConnection()) + { + Init(db); + + var q = db.From() + .Join((t1, t2) => t1.Id == t2.Id) + .Join((t1, t3) => t1.Id == t3.Id) + .Join((t1, t4) => t1.Id == t4.Id) + .Join((t1, t5) => t1.Id == t5.Id) + .Where((t1, t2, t3, t4, t5) => + t1.String == t2.String + && t2.String == t3.String + && t4.String == t5.String); + + var results = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].String, Is.EqualTo("A")); + } + } + + [Test] + public void Can_add_join_condition_to_join_multiple_tables_using_typed_api() + { + using (var db = OpenDbConnection()) + { + Init(db); + + var q = db.From() + .Join((t1, t2) => t1.Id == t2.Id) + .LeftJoin((t1, t3, t2) => + t1.Id == t3.Id && t3.Id == t2.Id); + + var results = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].String, Is.EqualTo("A")); + + q = db.From() + .Join((t1, t2) => t1.Id == t2.Id) + .Join((t1, t3) => t1.Id == t3.Id) + .LeftJoin((t1, t4, t2, t3) => + t1.Id == t4.Id && t4.Id == t2.Id && t4.Id == t3.Id); + + results = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].String, Is.EqualTo("A")); + } + } + + [Test] + public void Can_add_join_condition_to_join_multiple_tables_using_custom_join_format() + { + using (var db = OpenDbConnection()) + { + Init(db); + + var q = db.From() + .Join((t1, t2) => t1.Id == t2.Id) + .LeftJoin((t1, t3) => t1.Id == t3.Id, + (dialect, modelDef, joinExpr) => + { + var injectJoin = " AND Table3.Id = Table2.Id)"; + return dialect.GetQuotedTableName(modelDef.ModelName) + + " " + joinExpr.Replace(")", injectJoin); + }); + + var results = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(db.GetLastSql(), Does.Contain("AND Table3.Id = Table2.Id")); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].String, Is.EqualTo("A")); + } + } + + [Test] + public void Can_add_join_condition_to_join_multiple_tables_using_custom_join_sql() + { + using (var db = OpenDbConnection()) + { + Init(db); + + var q = db.From() + .Join((t1, t2) => t1.Id == t2.Id) + .CustomJoin("LEFT JOIN Table3 ON (Table1.Id = Table3.Id AND Table3.Id = Table2.Id)"); + + var results = db.Select(q); + + db.GetLastSql().Print(); + + Assert.That(db.GetLastSql(), Does.Contain("Table1.Id = Table3.Id AND Table3.Id = Table2.Id")); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].String, Is.EqualTo("A")); + } + } + + [Test] + public void Can_join_multiple_tables_using_custom_sql() + { + using (var db = OpenDbConnection()) + { + Init(db); + + var results = db.SqlList(@"SELECT Table1.* + FROM Table1 INNER JOIN Table2 ON(Table1.Id = Table2.Id) LEFT JOIN Table3 ON(Table1.Id = Table3.Id AND Table3.Id = Table2.Id)"); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].String, Is.EqualTo("A")); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/StringFunctionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expression/StringFunctionTests.cs index 68a55a373..a52a2dc21 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/StringFunctionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/StringFunctionTests.cs @@ -2,8 +2,11 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class StringFunctionTests : ExpressionsTestBase { + public StringFunctionTests(DialectContext context) : base(context) {} + [Test] public void Can_select_using_contains() { @@ -16,13 +19,16 @@ public void Can_select_using_contains() StringColumn = stringVal }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.Contains(stringVal)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -37,13 +43,16 @@ public void Can_select_using_contains_with_quote_in_string() StringColumn = stringVal }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.Contains(stringVal)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -58,13 +67,16 @@ public void Can_select_using_contains_with_double_quote_in_string() StringColumn = stringVal }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.Contains(stringVal)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -79,13 +91,16 @@ public void Can_select_using_contains_with_backtick_in_string() StringColumn = stringVal }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.Contains(stringVal)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.Contains(stringVal)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -100,13 +115,16 @@ public void Can_select_using_startsWith() StringColumn = prefix + "asdfasdfasdf" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.StartsWith(prefix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -121,13 +139,16 @@ public void Can_select_using_startsWith_with_quote_in_string() StringColumn = prefix + "'asdfasdfasdf" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.StartsWith(prefix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -142,13 +163,16 @@ public void Can_select_using_startsWith_with_double_quote_in_string() StringColumn = prefix + "\"asdfasdfasdf" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.StartsWith(prefix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -163,13 +187,39 @@ public void Can_select_using_startsWith_with_backtick_in_string() StringColumn = prefix + "`asdfasdfasdf" }; - EstablishContext(10, expected); + Init(10, expected); + + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.StartsWith(prefix)); + + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } + } + + [Test] + public void Can_select_using_Equals() + { + var postfix = "postfix"; + + var expected = new TestType { + IntColumn = 7, + BoolColumn = true, + StringColumn = postfix + }; + + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.StartsWith(prefix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.Equals(postfix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.That(actual, Is.Not.Null); + Assert.That(actual.Count, Is.EqualTo(1)); + Assert.That(actual, Is.EquivalentTo(new[]{ expected })); + } } [Test] @@ -184,13 +234,16 @@ public void Can_select_using_endsWith() StringColumn = "asdfasdfasdf" + postfix }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.EndsWith(postfix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -205,13 +258,16 @@ public void Can_select_using_endsWith_with_quote_in_string() StringColumn = "asdfasd'fasdf" + postfix }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.EndsWith(postfix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -226,13 +282,16 @@ public void Can_select_using_endsWith_with_double_quote_in_string() StringColumn = "asdfasd\"fasdf" + postfix }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.EndsWith(postfix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -247,13 +306,16 @@ public void Can_select_using_endsWith_with_backtick_in_string() StringColumn = "asdfasd`fasdf" + postfix }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.StringColumn.EndsWith(postfix)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.StringColumn.EndsWith(postfix)); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } } } diff --git a/tests/ServiceStack.OrmLite.Tests/Expression/UnaryExpressionsTest.cs b/tests/ServiceStack.OrmLite.Tests/Expression/UnaryExpressionsTest.cs index cc2913c74..8f0052a20 100644 --- a/tests/ServiceStack.OrmLite.Tests/Expression/UnaryExpressionsTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/Expression/UnaryExpressionsTest.cs @@ -2,90 +2,99 @@ namespace ServiceStack.OrmLite.Tests.Expression { + [TestFixtureOrmLite] public class UnaryExpressionsTest : ExpressionsTestBase { - #region constants + public UnaryExpressionsTest(DialectContext context) : base(context) {} [Test] public void Can_select_unary_plus_constant_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == +12); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == +12); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_unary_minus_constant_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = -12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == -12); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == -12); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_unary_not_constant_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == !true); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == !true); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_unary_not_constant_expression2() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => !q.BoolColumn); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => !q.BoolColumn); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } - #endregion - - #region variables - [Test] public void Can_select_unary_plus_variable_expression() { @@ -93,20 +102,23 @@ public void Can_select_unary_plus_variable_expression() var intVal = +12; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == intVal); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == intVal); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -116,20 +128,23 @@ public void Can_select_unary_minus_variable_expression() var intVal = -12; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = -12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == intVal); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == intVal); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -139,20 +154,23 @@ public void Can_select_unary_not_variable_expression() var boolVal = true; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == !boolVal); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == !boolVal); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] @@ -162,135 +180,68 @@ public void Can_select_unary_cast_variable_expression() object intVal = 12; // ReSharper restore ConvertToConstant.Local - var expected = new TestType() - { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var actual = OpenDbConnection().Select(q => q.IntColumn == (int)intVal); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_cast_variable_with_explicit_userdefined_type_conversion_expression() - { - // ReSharper disable ConvertToConstant.Local - var intVal = 12; - // ReSharper restore ConvertToConstant.Local - - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); - - var value = new IntWrapper(intVal); - - var actual = OpenDbConnection().Select(q => q.IntColumn == (int)value); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - [Test] - public void Can_select_unary_cast_variable_with_implicit_userdefined_type_conversion_expression() - { - // ReSharper disable ConvertToConstant.Local - var intVal = 12; - // ReSharper restore ConvertToConstant.Local + Init(10, expected); - var expected = new TestType() + using (var db = OpenDbConnection()) { - IntColumn = 12, - BoolColumn = true, - StringColumn = "test" - }; - - EstablishContext(10, expected); - - var value = new IntWrapper(intVal); - - var actual = OpenDbConnection().Select(q => q.IntColumn == value); + var actual = db.Select(q => q.IntColumn == (int)intVal); - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } - #endregion - - #region method - [Test] public void Can_select_unary_not_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = false, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.BoolColumn == !GetValue(true)); + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.BoolColumn == !GetValue(true)); - Assert.IsNotNull(actual); - Assert.Greater(actual.Count, 0); - CollectionAssert.Contains(actual, expected); + Assert.IsNotNull(actual); + Assert.Greater(actual.Count, 0); + CollectionAssert.Contains(actual, expected); + } } [Test] public void Can_select_unary_cast_method_expression() { - var expected = new TestType() + var expected = new TestType { IntColumn = 12, BoolColumn = true, StringColumn = "test" }; - EstablishContext(10, expected); + Init(10, expected); - var actual = OpenDbConnection().Select(q => q.IntColumn == (int)GetValue((object)12)); - - Assert.IsNotNull(actual); - Assert.AreEqual(1, actual.Count); - CollectionAssert.Contains(actual, expected); - } - - #endregion - } - - public struct IntWrapper - { - private readonly int _id; - - public IntWrapper(int projectId) - { - _id = projectId; - } + using (var db = OpenDbConnection()) + { + var actual = db.Select(q => q.IntColumn == (int)GetValue((object)12)); - public static explicit operator IntWrapper(int value) - { - return new IntWrapper(value); + Assert.IsNotNull(actual); + Assert.AreEqual(1, actual.Count); + CollectionAssert.Contains(actual, expected); + } } - public static implicit operator int(IntWrapper value) - { - return value._id; - } } - } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ExpressionTests.cs b/tests/ServiceStack.OrmLite.Tests/ExpressionTests.cs index d89e0e693..438c1ae5a 100644 --- a/tests/ServiceStack.OrmLite.Tests/ExpressionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ExpressionTests.cs @@ -2,22 +2,23 @@ using NUnit.Framework; using ServiceStack.OrmLite.Sqlite; using ServiceStack.OrmLite.Tests.Shared; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { [TestFixture] public class ExpressionTests { - [TestFixtureSetUp] + private SqliteOrmLiteDialectProvider _dialectProvider; + + [OneTimeSetUp] public void TestFixtureSetUp() { - OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider(); + _dialectProvider = new SqliteOrmLiteDialectProvider(); } - public static SqliteExpression expr() + public SqlExpression expr() { - return (SqliteExpression) OrmLiteConfig.DialectProvider.SqlExpression(); + return _dialectProvider.SqlExpression(); } [Test] @@ -26,16 +27,16 @@ public void Does_support_Sql_In_on_int_collections() var ids = new[] { 1, 2, 3 }; Assert.That(expr().Where(q => Sql.In(q.Id, 1, 2, 3)).WhereExpression, - Is.EqualTo("WHERE \"Id\" In (1,2,3)")); + Is.EqualTo("WHERE \"Id\" IN (@0,@1,@2)")); Assert.That(expr().Where(q => Sql.In(q.Id, ids)).WhereExpression, - Is.EqualTo("WHERE \"Id\" In (1,2,3)")); + Is.EqualTo("WHERE \"Id\" IN (@0,@1,@2)")); Assert.That(expr().Where(q => Sql.In(q.Id, ids.ToList())).WhereExpression, - Is.EqualTo("WHERE \"Id\" In (1,2,3)")); + Is.EqualTo("WHERE \"Id\" IN (@0,@1,@2)")); Assert.That(expr().Where(q => Sql.In(q.Id, ids.ToList().Cast())).WhereExpression, - Is.EqualTo("WHERE \"Id\" In (1,2,3)")); + Is.EqualTo("WHERE \"Id\" IN (@0,@1,@2)")); } [Test] @@ -44,16 +45,16 @@ public void Does_support_Sql_In_on_string_collections() var ids = new[] { "A", "B", "C" }; Assert.That(expr().Where(q => Sql.In(q.FirstName, "A", "B", "C")).WhereExpression, - Is.EqualTo("WHERE \"FirstName\" In ('A','B','C')")); + Is.EqualTo("WHERE \"FirstName\" IN (@0,@1,@2)")); Assert.That(expr().Where(q => Sql.In(q.FirstName, ids)).WhereExpression, - Is.EqualTo("WHERE \"FirstName\" In ('A','B','C')")); + Is.EqualTo("WHERE \"FirstName\" IN (@0,@1,@2)")); Assert.That(expr().Where(q => Sql.In(q.FirstName, ids.ToList())).WhereExpression, - Is.EqualTo("WHERE \"FirstName\" In ('A','B','C')")); + Is.EqualTo("WHERE \"FirstName\" IN (@0,@1,@2)")); Assert.That(expr().Where(q => Sql.In(q.FirstName, ids.ToList().Cast())).WhereExpression, - Is.EqualTo("WHERE \"FirstName\" In ('A','B','C')")); + Is.EqualTo("WHERE \"FirstName\" IN (@0,@1,@2)")); } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ExpressionVisitorTests.cs b/tests/ServiceStack.OrmLite.Tests/ExpressionVisitorTests.cs index e488baa36..3ee8a4de8 100644 --- a/tests/ServiceStack.OrmLite.Tests/ExpressionVisitorTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ExpressionVisitorTests.cs @@ -1,57 +1,87 @@ using System; +using System.Collections.Generic; +using System.Data; using System.Linq; using NUnit.Framework; +using ServiceStack.DataAnnotations; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class ExpressionVisitorTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class ExpressionVisitorTests : OrmLiteProvidersTestBase { + public ExpressionVisitorTests(DialectContext context) : base(context) {} + + private IDbConnection Db; + [SetUp] public void Setup() { - using (var con = OpenDbConnection()) + using (var db = OpenDbConnection()) { - con.DropAndCreateTable(); - con.Insert(new TestType { Id = 1, BoolCol = true, DateCol = new DateTime(2012, 1, 1), TextCol = "asdf", EnumCol = TestEnum.Val0 }); - con.Insert(new TestType { Id = 2, BoolCol = true, DateCol = new DateTime(2012, 2, 1), TextCol = "asdf123", EnumCol = TestEnum.Val1 }); - con.Insert(new TestType { Id = 3, BoolCol = false, DateCol = new DateTime(2012, 3, 1), TextCol = "qwer", EnumCol = TestEnum.Val2 }); - con.Insert(new TestType { Id = 4, BoolCol = false, DateCol = new DateTime(2012, 4, 1), TextCol = "qwer123", EnumCol = TestEnum.Val3 }); + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.Insert(new TestType3 { Id = 1, BoolCol = true, DateCol = new DateTime(2012, 4, 1), TextCol = "111", EnumCol = TestEnum.Val3, NullableIntCol = 10, TestType3Name = "3.1", CustomInt = 100 }); + db.Insert(new TestType3 { Id = 2, BoolCol = false, DateCol = new DateTime(2012, 4, 1), TextCol = "222", EnumCol = TestEnum.Val3, NullableIntCol = 20, TestType3Name = "3.2", CustomInt = 200 }); + db.Insert(new TestType3 { Id = 3, BoolCol = false, DateCol = new DateTime(2012, 4, 1), TextCol = "222", EnumCol = TestEnum.Val3, NullableIntCol = 30, TestType3Name = "3.3", CustomInt = 300 }); + db.Insert(new TestType3 { Id = 4, BoolCol = false, DateCol = new DateTime(2012, 4, 1), TextCol = "222", EnumCol = TestEnum.Val3, NullableIntCol = 40, TestType3Name = "3.4", CustomInt = 400 }); + + db.CreateTable(); + db.Insert(new TestType2 { Id = 1, BoolCol = true, DateCol = new DateTime(2012, 4, 1), TextCol = "111", EnumCol = TestEnum.Val3, NullableIntCol = 10, TestType2Name = "2.1", TestType3ObjColId = 1 }); + db.Insert(new TestType2 { Id = 2, BoolCol = false, DateCol = new DateTime(2012, 4, 1), TextCol = "222", EnumCol = TestEnum.Val3, NullableIntCol = 20, TestType2Name = "2.2", TestType3ObjColId = 2 }); + db.Insert(new TestType2 { Id = 3, BoolCol = true, DateCol = new DateTime(2012, 4, 1), TextCol = "333", EnumCol = TestEnum.Val3, NullableIntCol = 30, TestType2Name = "2.3", TestType3ObjColId = 3 }); + db.Insert(new TestType2 { Id = 4, BoolCol = false, DateCol = new DateTime(2012, 4, 1), TextCol = "444", EnumCol = TestEnum.Val3, NullableIntCol = 40, TestType2Name = "2.4", TestType3ObjColId = 4 }); + + db.CreateTable(); + db.Insert(new TestType { Id = 1, BoolCol = true, DateCol = new DateTime(2012, 1, 1), TextCol = "asdf", EnumCol = TestEnum.Val0, NullableIntCol = 10, TestType2ObjColId = 1 }); + db.Insert(new TestType { Id = 2, BoolCol = true, DateCol = new DateTime(2012, 2, 1), TextCol = "asdf123", EnumCol = TestEnum.Val1, NullableIntCol = null, TestType2ObjColId = 2 }); + db.Insert(new TestType { Id = 3, BoolCol = false, DateCol = new DateTime(2012, 3, 1), TextCol = "qwer", EnumCol = TestEnum.Val2, NullableIntCol = 30, TestType2ObjColId = 3 }); + db.Insert(new TestType { Id = 4, BoolCol = false, DateCol = new DateTime(2012, 4, 1), TextCol = "qwer123", EnumCol = TestEnum.Val3, NullableIntCol = 40, TestType2ObjColId = 4 }); } + Db = OpenDbConnection(); + } + + [TearDown] + public void TearDown() + { + Db.Dispose(); } [Test] public void Can_Select_by_const_int() { - var target = OpenDbConnection().Select(q => q.Id == 1); + var target = Db.Select(q => q.Id == 1); Assert.AreEqual(1, target.Count); } [Test] public void Can_Select_by_value_returned_by_method_without_params() { - var target = OpenDbConnection().Select(q => q.Id == MethodReturningInt()); + var target = Db.Select(q => q.Id == MethodReturningInt()); Assert.AreEqual(1, target.Count); } [Test] public void Can_Select_by_value_returned_by_method_with_param() { - var target = OpenDbConnection().Select(q => q.Id == MethodReturningInt(1)); + var target = Db.Select(q => q.Id == MethodReturningInt(1)); Assert.AreEqual(1, target.Count); } [Test] public void Can_Select_by_const_enum() { - var target = OpenDbConnection().Select(q => q.EnumCol == TestEnum.Val0); + var target = Db.Select(q => q.EnumCol == TestEnum.Val0); Assert.AreEqual(1, target.Count); } [Test] public void Can_Select_by_enum_returned_by_method() { - var target = OpenDbConnection().Select(q => q.EnumCol == MethodReturningEnum()); + var target = Db.Select(q => q.EnumCol == MethodReturningEnum()); Assert.AreEqual(1, target.Count); } @@ -59,7 +89,7 @@ public void Can_Select_by_enum_returned_by_method() public void Can_Select_using_ToUpper_on_string_property_of_T() { var target = - OpenDbConnection().Select(q => q.TextCol.ToUpper() == "ASDF"); + Db.Select(q => q.TextCol.ToUpper() == "ASDF"); Assert.AreEqual(1, target.Count); } @@ -69,7 +99,7 @@ public void Can_Select_using_ToLower_on_string_property_of_field() var obj = new TestType {TextCol = "ASDF"}; var target = - OpenDbConnection().Select(q => q.TextCol == obj.TextCol.ToLower()); + Db.Select(q => q.TextCol == obj.TextCol.ToLower()); Assert.AreEqual(1, target.Count); } @@ -77,85 +107,146 @@ public void Can_Select_using_ToLower_on_string_property_of_field() public void Can_Select_using_Constant_Bool_Value() { var target = - OpenDbConnection().Select(q => q.BoolCol == true); + Db.Select(q => q.BoolCol == true); Assert.AreEqual(2, target.Count); } [Test] - public void Can_Select_using_new() + public void Can_Select_using_new_ComplexType() { - using (var con = OpenDbConnection()) + Db.Insert(new TestType { - con.Insert(new TestType - { - Id = 5, - BoolCol = false, - DateCol = new DateTime(2012, 5, 1), - TextCol = "uiop", - EnumCol = TestEnum.Val3, - ComplexObjCol = new TestType { TextCol = "poiu" } - }); - - var target = OpenDbConnection().Select( - q => q.ComplexObjCol == new TestType { TextCol = "poiu"}); - Assert.AreEqual(1, target.Count); - } + Id = 5, + BoolCol = false, + DateCol = new DateTime(2012, 5, 1), + TextCol = "uiop", + EnumCol = TestEnum.Val3, + ComplexObjCol = new TestType { TextCol = "poiu" }, + TestType2ObjColId = 1 + }); + + var target = Db.Select( + q => q.ComplexObjCol == new TestType { TextCol = "poiu" }); + Assert.AreEqual(1, target.Count); } [Test] public void Can_Select_using_IN() { - var visitor = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor.Where(q => Sql.In(q.TextCol, "asdf", "qwer")); - var target = OpenDbConnection().Select(visitor); + var q = Db.From(); + q.Where(x => Sql.In(x.TextCol, "asdf", "qwer")); + var target = Db.Select(q); Assert.AreEqual(2, target.Count); } [Test] public void Can_Select_using_IN_using_params() { - var visitor = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor.Where(q => Sql.In(q.Id, 1, 2, 3)); - var target = OpenDbConnection().Select(visitor); + var q = Db.From(); + q.Where(x => Sql.In(x.Id, 1, 2, 3)); + var target = Db.Select(q); Assert.AreEqual(3, target.Count); } [Test] public void Can_Select_using_IN_using_int_array() { - var visitor = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor.Where(q => Sql.In(q.Id, new[] {1, 2, 3})); - var target = OpenDbConnection().Select(visitor); + var q = Db.From(); + q.Where(x => Sql.In(x.Id, new[] {1, 2, 3})); + var target = Db.Select(q); Assert.AreEqual(3, target.Count); } [Test] public void Can_Select_using_IN_using_object_array() { - var visitor = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor.Where(q => Sql.In(q.Id, new object[] { 1, 2, 3 })); - var target = OpenDbConnection().Select(visitor); + var q = Db.From(); + q.Where(x => Sql.In(x.Id, new object[] { 1, 2, 3 })); + var target = Db.Select(q); Assert.AreEqual(3, target.Count); } + [Test] + public void Can_Select_using_int_array_Contains() + { + var ids = new[] { 1, 2 }; + var q = Db.From().Where(x => ids.Contains(x.Id)); + var target = Db.Select(q); + CollectionAssert.AreEquivalent(ids, target.Select(t => t.Id).ToArray()); + } + + [Test] + public void Can_Select_using_int_list_Contains() + { + var ids = new List { 1, 2 }; + var q = Db.From().Where(x => ids.Contains(x.Id)); + var target = Db.Select(q); + CollectionAssert.AreEquivalent(ids, target.Select(t => t.Id).ToArray()); + } + + [Test] + public void Can_Select_using_int_array_Contains_Value() + { + var ints = new[] { 10, 40 }; + var q = Db.From().Where(x => ints.Contains(x.NullableIntCol.Value)); // Doesn't compile without ".Value" here - "ints" is not nullable + var target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 4 }, target.Select(t => t.Id).ToArray()); + } + + [Test] + public void Can_Select_using_Nullable_HasValue() + { + var q = Db.From().Where(x => x.NullableIntCol.HasValue); // WHERE NullableIntCol IS NOT NULL + var target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3, 4 }, target.Select(t => t.Id).ToArray()); + + q = Db.From().Where(x => !x.NullableIntCol.HasValue); // WHERE NOT (NullableIntCol IS NOT NULL) + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 2 }, target.Select(t => t.Id).ToArray()); + } + + [Test] + public void Can_Select_using_constant_Yoda_condition() + { + var q = Db.From().Where(x => null != x.NullableIntCol); // "null != x.NullableIntCol" should be the same as "x.NullableIntCol != null" + var target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3, 4 }, target.Select(t => t.Id).ToArray()); + } + + [Test] + public void Can_Select_using_int_array_constructed_inside_Contains() + { + var q = Db.From().Where(x => new int?[] { 10, 30 }.Contains(x.NullableIntCol)); + var target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3 }, target.Select(t => t.Id).ToArray()); + } + + [Test] + public void Can_Select_using_int_list_constructed_inside_Contains() + { + var q = Db.From().Where(x => new List { 10, 30 }.Contains(x.NullableIntCol)); + var target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3 }, target.Select(t => t.Id).ToArray()); + } + [Test] public void Can_Select_using_Startswith() { - var target = OpenDbConnection().Select(q => q.TextCol.StartsWith("asdf")); + var target = Db.Select(q => q.TextCol.StartsWith("asdf")); Assert.AreEqual(2, target.Count); } [Test] public void Can_Select_using_Endswith() { - var target = OpenDbConnection().Select(q => q.TextCol.EndsWith("123")); + var target = Db.Select(q => q.TextCol.EndsWith("123")); Assert.AreEqual(2, target.Count); } [Test] public void Can_Select_using_Contains() { - var target = OpenDbConnection().Select(q => q.TextCol.Contains("df")); + var target = Db.Select(q => q.TextCol.Contains("df")); Assert.AreEqual(2, target.Count); } @@ -163,9 +254,9 @@ public void Can_Select_using_Contains() public void Can_Selelct_using_chained_string_operations() { var value = "ASDF"; - var visitor = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor.Where(q => q.TextCol.ToUpper().StartsWith(value)); - var target = OpenDbConnection().Select(visitor); + var q = Db.From(); + q.Where(x => x.TextCol.ToUpper().StartsWith(value)); + var target = Db.Select(q); Assert.AreEqual(2, target.Count); } @@ -174,13 +265,13 @@ public void Can_Select_using_object_Array_Contains() { var vals = new object[]{ TestEnum.Val0, TestEnum.Val1 }; - var visitor1 = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor1.Where(q => vals.Contains(q.EnumCol) || vals.Contains(q.EnumCol)); - var sql1 = visitor1.ToSelectStatement(); + var q1 = Db.From(); + q1.Where(q => vals.Contains(q.EnumCol) || vals.Contains(q.EnumCol)); + var sql1 = q1.ToSelectStatement(); - var visitor2 = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor2.Where(q => Sql.In(q.EnumCol, vals) || Sql.In(q.EnumCol, vals)); - var sql2 = visitor2.ToSelectStatement(); + var q2 = Db.From(); + q2.Where(q => Sql.In(q.EnumCol, vals) || Sql.In(q.EnumCol, vals)); + var sql2 = q2.ToSelectStatement(); Assert.AreEqual(sql1, sql2); } @@ -188,19 +279,623 @@ public void Can_Select_using_object_Array_Contains() [Test] public void Can_Select_using_int_Array_Contains() { - var vals = new int[] { (int)TestEnum.Val0, (int)TestEnum.Val1 }; + var vals = new[] { (int)TestEnum.Val0, (int)TestEnum.Val1 }; - var visitor1 = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor1.Where(q => vals.Contains((int)q.EnumCol) || vals.Contains((int)q.EnumCol)); - var sql1 = visitor1.ToSelectStatement(); + var q1 = Db.From(); + q1.Where(q => vals.Contains((int)q.EnumCol) || vals.Contains((int)q.EnumCol)); + var sql1 = q1.ToSelectStatement(); - var visitor2 = OrmLiteConfig.DialectProvider.SqlExpression(); - visitor2.Where(q => Sql.In(q.EnumCol, vals) || Sql.In(q.EnumCol, vals)); - var sql2 = visitor2.ToSelectStatement(); + var q2 = Db.From(); + q2.Where(q => Sql.In(q.EnumCol, vals) || Sql.In(q.EnumCol, vals)); + var sql2 = q2.ToSelectStatement(); Assert.AreEqual(sql1, sql2); } + [Test] + public void Can_Select_using_boolean_constant() + { + var q = Db.From().Where(x => true); + var target = Db.Select(q); + Assert.AreEqual(4, target.Count); + + q = Db.From().Where(x => false); + target = Db.Select(q); + Assert.AreEqual(0, target.Count); + } + + [Test] + public void Can_Select_using_expression_evaluated_to_constant() + { + var a = 5; + var b = 6; + int? nullableInt = null; + + var q = Db.From().Where(x => a < b); // "a < b" is evaluated by SqlExpression (not at compile time!) to ConstantExpression (true) + var target = Db.Select(q); + Assert.AreEqual(4, target.Count); + + q = Db.From().Where(x => x.NullableIntCol == nullableInt); // Expression evaluated to "null" in SqlExpression + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 2 }, target.Select(t => t.Id).ToArray()); + + q = Db.From().Where(x => nullableInt == x.NullableIntCol); // Same with the null on the left + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 2 }, target.Select(t => t.Id).ToArray()); + + // Expression = or <> true or false + + q = Db.From().Where(x => x.NullableIntCol.HasValue == 5 < 6); // Evaluated to "true" at compile time: equivalent to "x.NullableIntCol != null" + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3, 4 }, target.Select(t => t.Id).ToArray()); + + q = Db.From().Where(x => x.NullableIntCol.HasValue == 5 > 6); // Evaluated to "false" at compile time: equivalent to "x.NullableIntCol == null" + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 2 }, target.Select(t => t.Id).ToArray()); + + q = Db.From().Where(x => x.NullableIntCol.HasValue != 5 > 6); // != false + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3, 4 }, target.Select(t => t.Id).ToArray()); + + q = Db.From().Where(x => x.NullableIntCol.HasValue != 5 < 6); // != true + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 2 }, target.Select(t => t.Id).ToArray()); + + // Same, but with the constant on the left + + q = Db.From().Where(x => 5 < 6 == x.NullableIntCol.HasValue); + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3, 4 }, target.Select(t => t.Id).ToArray()); + + q = Db.From().Where(x => 5 > 6 != x.NullableIntCol.HasValue); + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3, 4 }, target.Select(t => t.Id).ToArray()); + + // Same, but with the expression evaluated inside SqlExpression (not at compile time) + + q = Db.From().Where(x => x.NullableIntCol.HasValue == a < b); + target = Db.Select(q); + CollectionAssert.AreEquivalent(new[] { 1, 3, 4 }, target.Select(t => t.Id).ToArray()); + } + + [Test] + public void Can_Where_using_filter_with_nested_properties() + { + string filterText2 = "2.1"; + string filterText3 = "3.3"; + bool? nullableTrue = true; + + var q = Db.From(). + Join(). + Where(x => (!x.NullableBoolCol.HasValue || x.NullableBoolCol.Value) && x.NullableIntCol.HasValue && x.TestType2ObjCol.BoolCol); + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + + var minDate = new DateTime(1900, 01, 01); + + q = Db.From(). + Join(). + Where(x => x.TestType2ObjCol.BoolCol && x.DateCol != minDate); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + + q = Db.From(). + Join(). + Where(x => x.TestType2ObjCol.BoolCol && x.TestType2ObjCol.BoolCol == nullableTrue && + x.DateCol != minDate && x.TestType2ObjCol.TestType2Name == filterText2); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + var intValue = 300; + q = Db.From(). + Join(). + Join(). + Where(x => !x.NullableBoolCol.HasValue && x.TestType2ObjCol.BoolCol && + x.TestType2ObjCol.TestType3ObjCol.TestType3Name == filterText3 && + x.TestType2ObjCol.TestType3ObjCol.CustomInt == new CustomInt(intValue)); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + q = Db.From(). + Join(). + Join(). + Where(x => !x.NullableBoolCol.HasValue && x.TestType2ObjCol.BoolCol && + x.NullableIntCol == new CustomInt(10)). + GroupBy(x => x.TestType2ObjCol.TestType3ObjCol.CustomInt). + Having(x => (Sql.Max(x.TestType2ObjCol.TestType3ObjCol.CustomInt) ?? 0) == new CustomInt(100)). + Select(x => x.TestType2ObjCol.TestType3ObjCol.CustomInt); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + //q = Db.From(). + // Join(). + // Join(). + // Where(x => !x.NullableBoolCol.HasValue && x.TestType2ObjCol.BoolCol && + // x.NullableIntCol == new CustomInt(10)). + // GroupBy(x => x.TestType2ObjCol.TestType3ObjCol.CustomInt). + // Having(x => (Sql.Max(x.TestType2ObjCol.TestType3ObjCol.CustomInt) ?? 0) != 10). + // Select(x => x.TestType2ObjCol.TestType3ObjCol.CustomInt); + //target = Db.Select(q); + //Assert.That(target.Count, Is.EqualTo(1)); + //Assert.That(q.Params[0].Value, Is.EqualTo(10)); + //Assert.That(q.Params[1].Value, Is.EqualTo(0)); //= "{Value:0}" + //Assert.That(q.Params[2].Value, Is.EqualTo(10)); + } + + [Test] + public void Can_Where_using_filter_with_ToString() + { + string filterText = "10"; + int filterInt = 10; + + var q = Db.From().Where(x => x.NullableIntCol.ToString() == filterText); + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + q = Db.From().Where(x => x.NullableIntCol.ToString() == null); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + q = Db.From().Where(x => x.NullableIntCol.ToString() == filterInt.ToString()); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + q = Db.From().Where(x => x.NullableIntCol.ToString() == "NotNumeric"); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(0)); + + q = Db.From(). + Join(). + Where( x => x.NullableIntCol.ToString() == filterText && x.TestType2ObjCol.NullableIntCol.ToString() == filterText); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + q = Db.From(). + Join(). + Where(x => x.NullableIntCol.ToString() == filterText && x.TestType2ObjCol.NullableIntCol.ToString() == "NotNumeric"); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(0)); + + var filterText2 = "qwer"; + + q = Db.From().Where(x => x.TextCol.ToString() == filterText2); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + q = Db.From().Where(x => x.NullableIntCol.ToString().EndsWith("0")); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(3)); + } + + [Test] + public void Can_Where_using_filter_with_Concat() + { + string filterText = "asdf"; + int filterInt = 10; + + System.Linq.Expressions.Expression> filter = x => String.Concat(x.TextCol, x.NullableIntCol.ToString()) == filterText + filterInt; + var q = Db.From().Where(filter); + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + filter = x => String.Concat(x.TextCol, ".", x.NullableIntCol.ToString()) == filterText + "." + filterInt; + q = Db.From().Where(filter); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + + filter = x => x.TextCol + "." + x.NullableIntCol.ToString() == filterText + "." + filterInt; + q = Db.From().Where(filter); + target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_constant_filter() + { + object left = null; + var right = PartialSqlString.Null; + + System.Linq.Expressions.Expression> filter = x => left == right; + var q = Db.From().Where(filter);//todo: here Where: null is NULL. May be need to change to 1=1 ? + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + } + + [Test] + public void Can_Where_using_Conditional_filter() + { + System.Linq.Expressions.Expression> filter = x => (x.NullableIntCol == null ? 0 : x.NullableIntCol) == 10; + var q = Db.From().Where(filter); + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_Bool_Conditional_filter() + { + System.Linq.Expressions.Expression> filter = x => (x.BoolCol ? x.NullableIntCol : 0) == 10; + var q = Db.From().Where(filter); + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_Method_with_Conditional_filter() + { + System.Linq.Expressions.Expression> filter = x => (x.TextCol == null ? null : x.TextCol).StartsWith("asdf"); + var q = Db.From().Where(filter); + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_Where_using_Constant_Conditional_filter() + { + var filterConditional = 10; + System.Linq.Expressions.Expression> filter = x => (filterConditional > 50 ? 123456789 : x.NullableIntCol) == 10; + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement(), Does.Not.Contain("123456789")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_Bool_Constant_Conditional_filter() + { + var filterConditional = true; + System.Linq.Expressions.Expression> filter = x => (filterConditional ? x.NullableIntCol : 123456789) == 10; + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement(), Does.Not.Contain("123456789")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_SqlIn_filter() + { + var subQ = Db.From().Where(x=>x.NullableIntCol == 10).Select(x=>x.Id); + var q = Db.From(); + q.PrefixFieldWithTableName = true; + q.Where(x=>Sql.In(x.Id, subQ)); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_IfConcat_filter() + { + System.Linq.Expressions.Expression> filter = x => (String.Concat("Text: ", x.TextCol) == null ? null : String.Concat("Text: ", x.TextCol)).EndsWith("asdf"); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("text")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_IfWithStringConstant_filter() + { + System.Linq.Expressions.Expression> filter = x => (String.Concat("Text: ", x.TextCol) == null ? " " : String.Concat("Text: ", x.TextCol)).EndsWith("asdf"); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("text")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_OrderBy_using_isnull() + { + System.Linq.Expressions.Expression> orderBy = x => x.TextCol == null ? x.TextCol : x.NullableIntCol.ToString(); + var q = Db.From().OrderBy(orderBy); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("isnull")); + + var target = Db.Select(q); + Assert.IsTrue(target.Count > 0); + } + + [Test] + public void Can_Where_using_Convert() + { + var paramExpr = System.Linq.Expressions.Expression.Parameter(typeof(TestType)); + var propExpr = System.Linq.Expressions.Expression.Property(paramExpr, nameof(TestType.TextCol)); + var convert = System.Linq.Expressions.Expression.Convert(propExpr, typeof(object)); + var methodToString = typeof(object).GetMethod(nameof(ToString)); + var toString = System.Linq.Expressions.Expression.Call(convert, methodToString); + var equal = System.Linq.Expressions.Expression.Equal(toString, System.Linq.Expressions.Expression.Constant("asdf")); + var lambda = System.Linq.Expressions.Expression.Lambda>(equal, paramExpr); + + var q = Db.From().Where(lambda); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_filter_with_Compare() + { + string filterText = "asdf"; + + System.Linq.Expressions.Expression> filter = x => String.Compare(x.TextCol, filterText) == 0; + var q = Db.From().Where(filter); + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(1)); + } + + [Test] + public void Can_Where_using_Only_Conditional_filter() + { + System.Linq.Expressions.Expression> filter = x => (x.NullableBoolCol.HasValue ? false : x.TextCol.Contains("qwer")); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_Where_using_Equal_Conditional_filter() + { + System.Linq.Expressions.Expression> filter = x => ((x.NullableBoolCol.HasValue ? false : x.TextCol.Contains("qwer")) == true); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_Where_using_And_Conditional_filter() + { + System.Linq.Expressions.Expression> filter = x => x.Id > 2 && (x.NullableBoolCol.HasValue ? false : x.TextCol.Contains("qwer")); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_Where_using_And_Equal_Conditional_filter() + { + System.Linq.Expressions.Expression> filter = x => x.Id > 2 && (x.NullableBoolCol.HasValue ? false : x.TextCol.Contains("qwer")) == true; + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_filter1() + { + var i = 0; + System.Linq.Expressions.Expression> filter = x => i > 0 ? x.BoolCol : x.TextCol.Contains("qwer"); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_filter2() + { + var i = 10; + System.Linq.Expressions.Expression> filter = x => i > 0 ? x.BoolCol : x.TextCol.Contains("qwer"); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_filter3() + { + var i = 0; + var fake = 1; + System.Linq.Expressions.Expression> filter = x => x.Id > 0 ? fake != fake : x.TextCol.Contains("zxcv"); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(0)); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_filter4() + { + var i = 10; + var fake = 1; + System.Linq.Expressions.Expression> filter = x => i > 0 ? fake != fake : x.TextCol.Contains("qwer"); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(0)); + } + + + [Test] + public void Can_Where_using_Constant_in_Conditional_filter5() + { + var i = 10; + var fake = 1; + System.Linq.Expressions.Expression> filter = x => i > 0 ? x.Id == x.Id : x.TextCol.Contains("qwer"); + var q = Db.From().Where(filter); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("=")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=1")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + } + + [Test] + public void Can_Where_using_Conditional_order1() + { + var i = 0; + var fake = 1; + System.Linq.Expressions.Expression> order = x => x.Id > 2 ? x.BoolCol : x.TextCol.Contains("qwer"); + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_order1() + { + var i = 0; + var fake = 1; + System.Linq.Expressions.Expression> order = x => i > 0 ? x.BoolCol : x.TextCol.Contains("qwer"); + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain(" like ")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("case when ")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_order2() + { + var i = 10; + var fake = 1; + System.Linq.Expressions.Expression> order = x => i > 0 ? x.BoolCol : x.TextCol.Contains("qwer"); + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + Assert.That(q.ToSelectStatement().NormalizeSql(), Does.Contain("order by boolcol")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("qwer", text); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_order3() + { + var i = 0; + var fake = 1; + System.Linq.Expressions.Expression> order = x => i > 0 ? false : x.TextCol.Contains("qwer"); + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain(Db.GetDialectProvider().ParamString + "0")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain("case when ")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_order4() + { + var i = 10; + var fake = 1; + System.Linq.Expressions.Expression> order = x => i > 0 ? false : x.TextCol.Contains("qwer"); + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain(Db.GetDialectProvider().ParamString + "0")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_order5() + { + var i = 0; + System.Linq.Expressions.Expression> order = x => i > 0 ? x.TextCol : ""; + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain(Db.GetDialectProvider().ParamString + "0")); + Assert.That(q.ToSelectStatement().ToLower().NormalizeSql(), Does.Contain("order by id")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_order6() + { + var i = 10; + System.Linq.Expressions.Expression> order = x => i > 0 ? x.TextCol : "www"; + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("@0")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_Constant_in_Conditional_order7() + { + var i = 10; + System.Linq.Expressions.Expression> order = x => x.Id > 0 ? x.TextCol : "www"; + var q = Db.From().OrderBy(order).ThenBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain("=")); + Assert.That(q.ToSelectStatement().ToLower(), Does.Contain(Db.GetDialectProvider().ParamString + "0")); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(4)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_StaticInsideNonStaticMethod() + { + System.Linq.Expressions.Expression> filter = x => String.Concat(x.TextCol, "test").StartsWith("asdf"); + var q = Db.From().Where(filter).OrderBy(x => x.Id); + Assert.That(q.ToSelectStatement().ToLower(), Does.Not.Contain(SqlExpression.TrueLiteral)); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_StringLengthProperty1() + { + System.Linq.Expressions.Expression> filter = x => x.TextCol.Length == 4; + var q = Db.From().Where(filter).OrderBy(x => x.Id); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(2)); + var text = target[0].TextCol; + Assert.AreEqual("asdf", text); + } + + [Test] + public void Can_Where_using_StringLengthProperty2() + { + System.Linq.Expressions.Expression> filter = x => x.TextCol.Length == 0; + var q = Db.From().Where(filter).OrderBy(x => x.Id); + + var target = Db.Select(q); + Assert.That(target.Count, Is.EqualTo(0)); + } + private int MethodReturningInt(int val) { return val; @@ -230,8 +925,75 @@ public class TestType public int Id { get; set; } public string TextCol { get; set; } public bool BoolCol { get; set; } + public bool? NullableBoolCol { get; set; } + public DateTime DateCol { get; set; } + public TestEnum EnumCol { get; set; } + public TestType ComplexObjCol { get; set; } + public int? NullableIntCol { get; set; } + + [ForeignKey(typeof(TestType2))] + public int TestType2ObjColId { get; set; } + public TestType2 TestType2ObjCol { get; set; } + } + + public class TestType2 + { + public int Id { get; set; } + public string TextCol { get; set; } + public bool BoolCol { get; set; } + public bool? NullableBoolCol { get; set; } public DateTime DateCol { get; set; } public TestEnum EnumCol { get; set; } public TestType ComplexObjCol { get; set; } + public int? NullableIntCol { get; set; } + public string TestType2Name { get; set; } + + [ForeignKey(typeof(TestType3))] + public int TestType3ObjColId { get; set; } + public TestType3 TestType3ObjCol { get; set; } + } + + public class TestType3 + { + public int Id { get; set; } + public string TextCol { get; set; } + public bool BoolCol { get; set; } + public bool? NullableBoolCol { get; set; } + public DateTime DateCol { get; set; } + public TestEnum EnumCol { get; set; } + public TestType3 ComplexObjCol { get; set; } + public int? NullableIntCol { get; set; } + public string TestType3Name { get; set; } + public CustomInt CustomInt { get; set; } + } + + /// + /// For testing VisitUnary with expression "u" that: u.Method != null (implicit conversion) + /// + public class CustomInt + { + private readonly int _value; + + public CustomInt(int value) + { + _value = value; + } + + public int Value + { + get { return _value; } + } + + + public static implicit operator int(CustomInt s) + { + return s.Value; + } + + public static implicit operator CustomInt(int s) + { + return new CustomInt(s); + } + } } diff --git a/tests/ServiceStack.OrmLite.Tests/Expressions/RestrictionTests.cs b/tests/ServiceStack.OrmLite.Tests/Expressions/RestrictionTests.cs deleted file mode 100644 index a788cf192..000000000 --- a/tests/ServiceStack.OrmLite.Tests/Expressions/RestrictionTests.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Data; -using NUnit.Framework; - -namespace ServiceStack.OrmLite.Tests.Expressions -{ - [TestFixture] - public class ExpressionTests : OrmLiteTestBase - { - #region Setup/Teardown - - [SetUp] - public void SetUp() - { - db = ConnectionString.OpenDbConnection(); - db.CreateTable(overwrite: true); - - //People.ToList().ForEach(x => dbCmd.Insert(x)); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - - #endregion - - public class Person - { - public Person() - { - } - - public Person(int id, string firstName, string lastName, int age) - { - Id = id; - FirstName = firstName; - LastName = lastName; - Age = age; - } - - public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public int? Age { get; set; } - } - - private IDbConnection db; - - public Person[] People = new[] - { - new Person(1, "Jimi", "Hendrix", 27), - new Person(2, "Janis", "Joplin", 27), - new Person(3, "Jim", "Morrisson", 27), - new Person(4, "Kurt", "Cobain", 27), - new Person(5, "Elvis", "Presley", 42), - new Person(6, "Michael", "Jackson", 50), - }; - - [Test] - public void Can_Chain_Expressions_Using_Or_and_And() - { - db.InsertAll(People); - - SqlExpressionVisitor visitor = db.CreateExpression(); - - visitor.Where(x => x.FirstName.StartsWith("Jim")).Or(x => x.LastName.StartsWith("Cob")); - - var results = db.Select(visitor); - Assert.AreEqual(3,results.Count); - - visitor.Where(); //clear where expression - - visitor.Where(x => x.FirstName.StartsWith("Jim")).And(x => x.LastName.StartsWith("Hen")); - results = db.Select(visitor); - - Assert.AreEqual(1,results.Count); - } - - [Test] - public void Can_get_rowcount_from_expression_visitor() - { - db.InsertAll(People); - - SqlExpressionVisitor visitor = db.CreateExpression(); - - visitor.Where(x => x.FirstName.StartsWith("Jim")).Or(x => x.LastName.StartsWith("Cob")); - - visitor.Count(); - - var count = db.GetScalar(visitor.CountExpression); - - var results = db.Select(visitor); - Assert.AreEqual(count, results.Count); - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ForeignKeyAttributeTests.cs b/tests/ServiceStack.OrmLite.Tests/ForeignKeyAttributeTests.cs index 9ca5ceb11..df227ad8b 100644 --- a/tests/ServiceStack.OrmLite.Tests/ForeignKeyAttributeTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/ForeignKeyAttributeTests.cs @@ -3,119 +3,123 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class ForeignKeyAttributeTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class ForeignKeyAttributeTests : OrmLiteProvidersTestBase { - [TestFixtureSetUp] + public ForeignKeyAttributeTests(DialectContext context) : base(context) {} + + [OneTimeSetUp] public void Setup() { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - dbConn.DropTable(); - - dbConn.DropAndCreateTable(); - } + using var dbConn = OpenDbConnection(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + dbConn.DropTable(); + + dbConn.CreateTable(); } [Test] public void CanCreateSimpleForeignKey() { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } + using var dbConn = OpenDbConnection(); + dbConn.DropAndCreateTable(); } [Test] public void CanCreateForeignWithOnDeleteCascade() { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } + using var dbConn = OpenDbConnection(); + dbConn.DropAndCreateTable(); } [Test] + [IgnoreDialect(Dialect.Sqlite, "no support for cascade deletes")] public void CascadesOnDelete() { - //Ignore for Sqlite who doesn't support Cascade deletes. TODO: group tests around db features - if (OrmLiteConfig.DialectProvider == SqliteDialect.Provider) - return; + // TODO: group tests around db features + Setup(); + using var db = OpenDbConnection(); + db.CreateTableIfNotExists(); + db.Save(new ReferencedType { Id = 1 }); + db.Save(new TypeWithOnDeleteCascade { RefId = 1 }); - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - - dbConn.Save(new ReferencedType { Id = 1 }); - dbConn.Save(new TypeWithOnDeleteCascade { RefId = 1 }); + Assert.AreEqual(1, db.Select().Count); + Assert.AreEqual(1, db.Select().Count); - Assert.AreEqual(1, dbConn.Select().Count); - Assert.AreEqual(1, dbConn.Select().Count); + db.Delete(r => r.Id == 1); - dbConn.Delete(r => r.Id == 1); - - Assert.AreEqual(0, dbConn.Select().Count); - Assert.AreEqual(0, dbConn.Select().Count); - } + Assert.AreEqual(0, db.Select().Count); + Assert.AreEqual(0, db.Select().Count); } [Test] public void CanCreateForeignWithOnDeleteCascadeAndOnUpdateCascade() { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } + using var dbConn = OpenDbConnection(); + dbConn.DropAndCreateTable(); } - [NUnit.Framework.Ignore("Not supported in sqlite?")] [Test] + [IgnoreDialect(Tests.Dialect.Sqlite, "Not supported in sqlite?")] public void CanCreateForeignWithOnDeleteNoAction() { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } + using var dbConn = OpenDbConnection(); + dbConn.DropAndCreateTable(); } [Test] public void CanCreateForeignWithOnDeleteRestrict() { - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } + using var dbConn = OpenDbConnection(); + dbConn.DropAndCreateTable(); } - + [Test] public void CanCreateForeignWithOnDeleteSetDefault() { - if (OrmLiteConfig.DialectProvider == MySqlDialect.Provider) + // ignoring Not supported in InnoDB: http://stackoverflow.com/a/1498015/85785 + if (DialectProvider == MySqlDialect.Provider) { - //ignoring Not supported in InnoDB: http://stackoverflow.com/a/1498015/85785 + Assert.Ignore("MySql FK's not supported, skipping"); return; } - using (var dbConn = OpenDbConnection()) - { - dbConn.DropAndCreateTable(); - } + using var dbConn = OpenDbConnection(); + dbConn.DropAndCreateTable(); } [Test] public void CanCreateForeignWithOnDeleteSetNull() { - using (var dbConn = OpenDbConnection()) + using var dbConn = OpenDbConnection(); + dbConn.DropAndCreateTable(); + } + + [Test] + public void Can_Skip_creating_ForeignKeys() + { + OrmLiteConfig.SkipForeignKeys = true; + Setup(); + + using (var db = OpenDbConnection()) { - dbConn.DropAndCreateTable(); + db.CreateTableIfNotExists(); + db.Save(new ReferencedType { Id = 1 }); + db.Save(new TypeWithOnDeleteCascade { RefId = 1 }); + + db.Delete(r => r.Id == 1); + + Assert.That(db.Select().Count, Is.EqualTo(0)); + Assert.That(db.Select().Count, Is.EqualTo(1)); } + + OrmLiteConfig.SkipForeignKeys = false; } } diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/AutoQueryJoinTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/AutoQueryJoinTests.cs new file mode 100644 index 000000000..d0d30d992 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/AutoQueryJoinTests.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class Product + { + [AutoIncrement] + public int Id { get; set; } + public string ProductType { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public int DisplayOrder { get; set; } + public bool LimitedToStores { get; set; } + public string Sku { get; set; } + public decimal Price { get; set; } + public decimal OldPrice { get; set; } + public decimal SpecialPrice { get; set; } + public decimal DiscountPercentage { get; set; } + public DateTime? DateChanged { get; set; } + public DateTime? DateCreated { get; set; } + + [Reference] + public List StockItems { get; set; } = new List(); + } + + public class StockItem + { + [AutoIncrement] + public int Id { get; set; } + [References(typeof(Product))] + public int ProductId { get; set; } + public string Size { get; set; } + public int TotalStockQuantity { get; set; } + public string Gtin { get; set; } + public int DisplayOrder { get; set; } + + [Reference] + public Product Product { get; set; } + } + + [TestFixtureOrmLite] + public class AutoQueryJoinTests : OrmLiteProvidersTestBase + { + public AutoQueryJoinTests(DialectContext context) : base(context) {} + + [Test] + public void Can_select_references_with_join() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.Save(new Product + { + ProductType = "A", + Name = "Name A", + DisplayOrder = 1, + Sku = "SKU A", + Price = 1, + DateCreated = DateTime.UtcNow, + StockItems = new List + { + new StockItem { Size = "1", TotalStockQuantity = 1, DisplayOrder = 1 }, + new StockItem { Size = "2", TotalStockQuantity = 2, DisplayOrder = 2 }, + } + }, references: true); + + db.Save(new Product + { + ProductType = "B", + Name = "Name B", + DisplayOrder = 2, + Sku = "SKU B", + Price = 2, + DateCreated = DateTime.UtcNow, + StockItems = new List + { + new StockItem { Size = "3", TotalStockQuantity = 3, DisplayOrder = 3 }, + new StockItem { Size = "4", TotalStockQuantity = 4, DisplayOrder = 4 }, + } + }, references: true); + + db.Insert(new Product + { + ProductType = "C", + Name = "Name C", + DisplayOrder = 3, + Sku = "SKU C", + Price = 3, + DateCreated = DateTime.UtcNow, + }); + + var results = db.LoadSelect(); + Assert.That(results.Count, Is.EqualTo(3)); + + var q = db.From().Join(); + var products = db.Select(q.SelectDistinct()); + var stockItems = db.Select(); + + products.Merge(stockItems); + + Assert.That(products.Count, Is.EqualTo(2)); + Assert.That(products[0].StockItems.Count, Is.EqualTo(2)); + Assert.That(products[1].StockItems.Count, Is.EqualTo(2)); + + db.DropTable(); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/BelongsToIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/BelongsToIssue.cs new file mode 100644 index 000000000..5e77f694b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/BelongsToIssue.cs @@ -0,0 +1,68 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + class A + { + public int Id { get; set; } + public string SomeAProperty { get; set; } + } + class B + { + public int Id { get; set; } + public string SomeBProperty { get; set; } + public int AId { get; set; } + } + class C + { + public int Id { get; set; } + public string SomeCProperty { get; set; } + public int BId { get; set; } + } + class D + { + public int Id { get; set; } + + [BelongTo(typeof(B))] + public int BId { get; set; } + + public int CId { get; set; } + + public string SomeAProperty { get; set; } + public string SomeBProperty { get; set; } + public string SomeCProperty { get; set; } + } + + [TestFixtureOrmLite] + public class BelongsToIssue : OrmLiteProvidersTestBase + { + public BelongsToIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_use_BelongsTo_to_specify_Attribute() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new A { Id = 1, SomeAProperty = "A1" }); + db.Insert(new A { Id = 2, SomeAProperty = "A2" }); + db.Insert(new A { Id = 3, SomeAProperty = "A3" }); + db.Insert(new B { Id = 10, SomeBProperty = "B1", AId = 1 }); + db.Insert(new B { Id = 11, SomeBProperty = "B2", AId = 2 }); + db.Insert(new C { Id = 20, SomeCProperty = "C", BId = 10 }); + + var q = db.From() + .Join() + .LeftJoin(); + + var results = db.Select(q); + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(results.Map(x => x.BId), Is.EquivalentTo(new[] { 10, 11 })); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CanBuildExpressionWithAbstractType.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CanBuildExpressionWithAbstractType.cs new file mode 100644 index 000000000..106346806 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CanBuildExpressionWithAbstractType.cs @@ -0,0 +1,36 @@ +using NUnit.Framework; +using ServiceStack.Model; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + abstract class ProductBase : IHasIntId + { + public int Id { get; set; } + + public string ManufacturingMessage { get; set; } + } + + class ProductSheet : ProductBase + { + + } + + [TestFixtureOrmLite] + public class CanBuildExpressionWithAbstractType : OrmLiteProvidersTestBase + { + public CanBuildExpressionWithAbstractType(DialectContext context) : base(context) {} + + [Test] + public void Can_Update_Property_In_Abstract_Base_Class() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.Insert(new ProductSheet { Id = 23, ManufacturingMessage = "test" }); + db.UpdateOnlyFields(new ProductSheet { ManufacturingMessage = "toto" }, p => p.ManufacturingMessage, p => p.Id == 23); + var sheet = db.SingleById(23); + Assert.That(sheet.ManufacturingMessage, Is.EqualTo("toto")); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/ColumnGuessingTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/ColumnGuessingTests.cs new file mode 100644 index 000000000..f4eb75c32 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/ColumnGuessingTests.cs @@ -0,0 +1,47 @@ +using System.Linq; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class ColumnGuessingTests : OrmLiteProvidersTestBase + { + public ColumnGuessingTests(DialectContext context) : base(context) {} + + private class Person + { + public string Name { get; set; } + public string LastName { get; set; } + public string NameAtBirth { get; set; } + } + + [Test] + public void Dont_guess_extra_columns_when_match_found() + { + // Only the specified column should be selected. The value of Name should not be written to FirstName nor NameAtBirth, + // since there is already a match for the requested column in the data model class. + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.Insert(new Person { LastName = "Smith", Name = "John", NameAtBirth = "Black" }); + + var row = db.Select(db.From().Select(r => new { r.LastName })).Single(); + AssertPerson(new Person { LastName = "Smith" }, row); + + row = db.Select(db.From().Select(r => new { r.Name })).Single(); + AssertPerson(new Person { Name = "John" }, row); + + row = db.Select(db.From().Select(r => new { r.NameAtBirth })).Single(); + AssertPerson(new Person { NameAtBirth = "Black" }, row); + } + } + + private static void AssertPerson(Person expected, Person actual) + { + Assert.AreEqual(expected.Name, actual.Name, "Name differs"); + Assert.AreEqual(expected.LastName, actual.LastName, "LastName differs"); + Assert.AreEqual(expected.NameAtBirth, actual.NameAtBirth, "NameAtBirth differs"); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/ComplexJoinWithAlias.cs b/tests/ServiceStack.OrmLite.Tests/Issues/ComplexJoinWithAlias.cs index b0c13e822..4ce6b4946 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/ComplexJoinWithAlias.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/ComplexJoinWithAlias.cs @@ -24,10 +24,11 @@ public class ClassB : IHasIntId public string ColumnB { get; set; } } - [TestFixture] - public class ComplexJoinWithAlias - : OrmLiteTestBase + [TestFixtureOrmLite] + public class ComplexJoinWithAlias : OrmLiteProvidersTestBase { + public ComplexJoinWithAlias(DialectContext context) : base(context) {} + private static long _classAColumnAId; private static void Init(IDbConnection db) diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CompositeIndexNamingStrategyIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CompositeIndexNamingStrategyIssue.cs new file mode 100644 index 000000000..df25207e9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CompositeIndexNamingStrategyIssue.cs @@ -0,0 +1,44 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [Alias("UserAuth")] + [CompositeIndex(true, "CompanyId", "UserName")] + public class MyCustomUserAuth + { + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(Company))] + public int CompanyId { get; set; } + + public string UserName { get; set; } + + public string Email { get; set; } + } + + public class Company + { + public int Id { get; set; } + public string Name { get; set; } + } + + [TestFixtureOrmLite] + public class CompositeIndexNamingStrategyIssue : OrmLiteProvidersTestBase + { + public CompositeIndexNamingStrategyIssue(DialectContext context) : base(context) {} + + [Test] + public void Can_Create_composite_index_with_property_name_indexes() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CountDistinctTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CountDistinctTests.cs new file mode 100644 index 000000000..fe4b98079 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CountDistinctTests.cs @@ -0,0 +1,24 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class CountDistinctTests : OrmLiteTestBase + { + public class CountDistinctIssueTable + { + public long AutoId { get; set; } + } + + [Test] + public void Ignores_paging_in_Scalar_queries() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var query = db.From(); + query.Skip(0); + + db.Scalar(query.Select(x => Sql.CountDistinct(x.AutoId))); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CreateTableAliasTest.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CreateTableAliasTest.cs new file mode 100644 index 000000000..7d50d0a76 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CreateTableAliasTest.cs @@ -0,0 +1,64 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [Alias("UV_Child")] + public partial class UV_Child + { + public int? KindergartenId { get; set; } + public string KindergartenName { get; set; } + public int? ClassId { get; set; } + public string ClassName { get; set; } + [Required] + public int ChildId { get; set; } + [Required] + public string ChildName { get; set; } + public int? ParentId { get; set; } + public string DisplayName { get; set; } + public string UserName { get; set; } + public string PhoneNumber { get; set; } + public string ImageName { get; set; } + } + + public class ChildResponse + { + public int? KindergartenId { get; set; } + public string KindergartenName { get; set; } + public int? ClassId { get; set; } + public string ClassName { get; set; } + public int ChildId { get; set; } + public string ChildName { get; set; } + public int? ParentId { get; set; } + public string DisplayName { get; set; } + public string UserName { get; set; } + public string PhoneNumber { get; set; } + public string ImageName { get; set; } + } + + [TestFixtureOrmLite] + public class CreateTableAliasTest : OrmLiteProvidersTestBase + { + public CreateTableAliasTest(DialectContext context) : base(context) {} + + [Test] + public void Can_Create_and_Select_from_table() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.GetLastSql().Print(); + + var results = db.LoadSelect( + db.From() + .Where(x => x.ClassId == 112)); + + db.GetLastSql().Print(); + + results.PrintDump(); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CsvTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CsvTests.cs new file mode 100644 index 000000000..644ccd302 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CsvTests.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Dapper; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class CsvTests : OrmLiteProvidersTestBase + { + public CsvTests(DialectContext context) : base(context) {} + + [Test] + public void Can_serialize_Dapper_results_to_CSV() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Poco { Id = 1, Name = "Foo" }); + db.Insert(new Poco { Id = 2, Name = "Bar" }); + + var results = db.Query("select * from Poco Order By Id"); + + var json = JsonSerializer.SerializeToString(results); + Assert.That(json.ToLower(), Is.EqualTo("[{\"Id\":1,\"Name\":\"Foo\"},{\"Id\":2,\"Name\":\"Bar\"}]".ToLower())); + + var csv = CsvSerializer.SerializeToCsv(results); + Assert.That(csv.NormalizeNewLines().ToLower(), Is.EqualTo("Id,Name\n1,Foo\n2,Bar".ToLower())); + } + } + + [Test] + public void Can_serialize_OrmLite_results_to_CSV() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Poco { Id = 1, Name = "Foo" }); + db.Insert(new Poco { Id = 2, Name = "Bar" }); + + var results = db.Select(); + + var json = JsonSerializer.SerializeToString(results); + Assert.That(json.ToLower(), Is.EqualTo("[{\"Id\":1,\"Name\":\"Foo\"},{\"Id\":2,\"Name\":\"Bar\"}]".ToLower())); + + var csv = results.ToCsv(); + Assert.That(csv.NormalizeNewLines().ToLower(), Is.EqualTo("Id,Name\n1,Foo\n2,Bar".ToLower())); + + var rows = db.Select>("select * from Poco Order By Id"); + csv = rows.ToCsv(); + Assert.That(csv.NormalizeNewLines().ToLower(), Is.EqualTo("Id,Name\n1,Foo\n2,Bar".ToLower())); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CustomFieldTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CustomFieldTests.cs new file mode 100644 index 000000000..1327ddbe9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CustomFieldTests.cs @@ -0,0 +1,38 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class ModelWithCustomFields + { + public int Id { get; set; } + + [DecimalLength(12,3)] + public decimal? Decimal { get; set; } + + [CustomField(OrmLiteVariables.MaxText)] + public string MaxText { get; set; } + } + + [TestFixtureOrmLite] + public class CustomFieldTests : OrmLiteProvidersTestBase + { + public CustomFieldTests(DialectContext context) : base(context) {} + + [Test] + public void Can_create_custom_Decimal_field() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var sql = db.GetLastSql(); + + sql.Print(); + + Assert.That(sql, Does.Contain("DECIMAL(12,3)")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CustomInsertIntoSelectJoinIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CustomInsertIntoSelectJoinIssue.cs new file mode 100644 index 000000000..add41b8e9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CustomInsertIntoSelectJoinIssue.cs @@ -0,0 +1,87 @@ +using System; +using System.Net; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class InsertIntoSource + { + [AutoIncrement] + public long Id { get; set; } + + public string Url { get; set; } + public string Provider { get; set; } + public string DomainKey { get; set; } + public bool NoFollow { get; set; } + public HttpStatusCode HttpStatusCode { get; set; } + public DateTime? LastScanTime { get; set; } + public string Anchors { get; set; } + public int? OutboundLinks { get; set; } + public long TargetDomainRecordId { get; set; } + public long UserAuthCustomId { get; set; } + } + + public class InertIntoTarget + { + [PrimaryKey] + public long WatchedUrlRecordId { get; set; } + + public string Url { get; set; } + public string DomainKey { get; set; } + public long TargetDomainRecordId { get; set; } + public string TargetDomainKey { get; set; } + public DateTime CreateDate { get; set; } = DateTime.UtcNow; + public int Tries { get; set; } + public DateTime? DeferUntil { get; set; } + public long UserAuthCustomId { get; set; } + public bool FirstScan { get; set; } + } + + public class InsertIntoJoin + { + [AutoIncrement] + public long Id { get; set; } + + public string Url { get; set; } + public string DomainKey { get; set; } + public DateTime CreateDate { get; set; } = DateTime.Now; + public DateTime? DeleteDate { get; set; } + public bool IsDeleted { get; set; } + public bool Active { get; set; } = true; + public long UserAuthCustomId { get; set; } + } + + public class CustomInsertIntoSelectJoinIssue : OrmLiteTestBase + { + [Test] + public void Can_custom_join_into_select() + { + using var db = OpenDbConnection(); + + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var ids = new[] {1, 2, 3}; + // OrmLiteUtils.PrintSql(); + + var q = db.From() + .Join((w, t) => w.TargetDomainRecordId == t.Id) + .Where(x => Sql.In(x.Id, ids)) + .Select((w, t) => new { + UserAuthCustomId = w.UserAuthCustomId, + DomainKey = w.DomainKey, + CreateDate = DateTime.UtcNow, + DeferUntil = (DateTime?) null, + TargetDomainKey = t.DomainKey, + Tries = 0, + TargetDomainRecordId = w.TargetDomainRecordId, + Url = w.Url, + WatchedUrlRecordId = w.Id + }); + + var inserted = db.InsertIntoSelect(q, dbCmd => dbCmd.OnConflictIgnore()); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/CustomTypeTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/CustomTypeTests.cs new file mode 100644 index 000000000..785074cc0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/CustomTypeTests.cs @@ -0,0 +1,61 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class CustomTypeTests : OrmLiteProvidersTestBase + { + public CustomTypeTests(DialectContext context) : base(context) {} + + public class PocoWithCustomTypes + { + [AutoIncrement] + public int Id { get; set; } + + [Index] + public Guid Guid { get; set; } + + public Uri Uri { get; set; } + } + + [Test] + public void Can_select_Guid() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var dto = new PocoWithCustomTypes + { + Guid = Guid.NewGuid() + }; + + long id = db.Insert(dto, selectIdentity: true); + var row = db.Single(r => r.Id == id); + + Assert.That(row.Guid, Is.EqualTo(dto.Guid)); + } + } + + [Test] + public void Can_select_Uri() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var dto = new PocoWithCustomTypes + { + Uri = new Uri("http://a.com") + }; + + long id = db.Insert(dto, selectIdentity: true); + var row = db.Single(r => r.Id == id); + + Assert.That(row.Uri.ToString(), Is.EqualTo(dto.Uri.ToString())); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/DynamicDataIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/DynamicDataIssue.cs new file mode 100644 index 000000000..b225e68fc --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/DynamicDataIssue.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Data; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class ParentTbl + { + [AutoIncrement] + public long Id { get; set; } + + public DateTime? DateMarried { get; set; } + + [Reference] + public List Childs { get; set; } = new List(); + + public DateTime? DateOfBirth { get; set; } + } + + public class ChildTbl + { + [AutoIncrement] + public long Id { get; set; } + + [References(typeof(ParentTbl))] + public long ParentId { get; set; } + + public DateTime? DateOfDeath { get; set; } + } + + [TestFixtureOrmLite] + public class DynamicDataIssue : OrmLiteProvidersTestBase + { + public DynamicDataIssue(DialectContext context) : base(context) {} + + private static void InitTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + } + + [Test] + public void Can_select_null_DateTime_in_nullable_Tuple() + { + var date = new DateTime(2000,1,1); + + using (var db = OpenDbConnection()) + { + InitTables(db); + + db.Insert(new ParentTbl { DateOfBirth = date }); + db.Insert(new ParentTbl { DateOfBirth = null }); + + db.Select(); + db.Select<(int, DateTime?)>(db.From()); + db.Select<(int, DateTime?)>(db.From().Select(x => new { x.Id, x.DateOfBirth })); + db.Select<(int, DateTime)>(db.From().Select(x => new { x.Id, x.DateOfBirth })); + } + } + + [Test] + public void Complex_example() + { + using (var db = OpenDbConnection()) + { + InitTables(db); + + var parentTbl = new ParentTbl { DateMarried = DateTime.Today }; + parentTbl.Id = db.Insert(parentTbl, selectIdentity:true); + db.Insert(new ChildTbl { ParentId = parentTbl.Id, DateOfDeath = null }); + + var q = db.From() + .RightJoin((c, p) => c.ParentId == p.Id || c.Id == null) + .GroupBy((p) => new { p.Id }) + .Select((c, p) => new { p.Id, MaxKeyValuePeriodEnd = Sql.Max(c.DateOfDeath) }); + + var theSqlStatement = q.ToSelectStatement(); + + theSqlStatement.Print(); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/DynamicDbNullIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/DynamicDbNullIssue.cs new file mode 100644 index 000000000..7dee86b7b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/DynamicDbNullIssue.cs @@ -0,0 +1,35 @@ +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class DynamicDbNullIssue : OrmLiteTestBase + { + public class Test + { + public int id { get; set; } + + public string name { get; set; } + } + + [Test] + public async Task Does_convert_DbNull_Values_in_Async_Results() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Test { id = 1, name = "A" }, + new Test { id = 2, name = null }); + + var rows = db.Select("select id, name from Test"); + Assert.That(rows.Any(x => x.name == null)); + + rows = await db.SelectAsync("select id, name from Test"); + Assert.That(rows.Any(x => x.name == null)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/DynamicResultsNamingStrategyTest.cs b/tests/ServiceStack.OrmLite.Tests/Issues/DynamicResultsNamingStrategyTest.cs new file mode 100644 index 000000000..b31f4a9fa --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/DynamicResultsNamingStrategyTest.cs @@ -0,0 +1,118 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class DynamicResultsNamingStrategyTest : OrmLiteProvidersTestBase + { + public DynamicResultsNamingStrategyTest(DialectContext context) : base(context) {} + + public class Menu : EntityBase + { + [AutoIncrement] + public int Id { get; set; } + + [ForeignKey(typeof(Menu))] + public int? ParentId { get; set; } + +// [Required] +// public MenuType Type { get; set; } + + [Required, StringLength(100)] + public string Name { get; set; } + + [StringLength(100)] + public string Form { get; set; } + + [StringLength(50)] + public string Icon { get; set; } + + [StringLength(1000)] + public string Style { get; set; } + +// [ForeignKey(typeof(User))] + public int? UserId { get; set; } + } + + public abstract class EntityBase // : IEntity + { + [Required, Default(typeof(bool), "{FALSE}")] + public bool IsDeleted { get; set; } + [Required, Default(typeof(bool), "{TRUE}")] + public bool IsActive { get; set; } = true; + public int? Position { get; set; } + //public ulong RowVersion { get; set; } + public Guid RecId { get; set; } + } + + public class DatabaseNamingStrategy : OrmLiteNamingStrategyBase + { + public override string GetTableName(string name) + { + return ToUnderscoreSeparated(name); + } + + public override string GetColumnName(string name) + { + return ToUnderscoreSeparated(name); + } + + + string ToUnderscoreSeparated(string name) + { + + string r = char.ToLower(name[0]).ToString(); + + for (int i = 1; i < name.Length; i++) + { + char c = name[i]; + if (char.IsUpper(name[i])) + { + r += "_"; + r += char.ToLower(name[i]); + } + else + { + r += name[i]; + } + } + return r; + } + } + + [Test] + public void Can_select_dynamic_results_from_custom_NamingStrategy() + { + OrmLiteConfig.BeforeExecFilter = dbCmd => Console.WriteLine(dbCmd.GetDebugString()); + + var hold = SqliteDialect.Provider.NamingStrategy; + SqliteDialect.Provider.NamingStrategy = new DatabaseNamingStrategy(); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var rows = new[] { + new Menu { + Name = "Test List", + RecId = new Guid("2F96233B-152E-4D20-BE08-5633431A9EBC") + } + }; + + db.InsertAll(rows); + + var q = db.From().Select(x => new { x.Id, x.RecId, x.Name }); + var results = db.Select<(int id, Guid recId, string name)>(q); + + var expected = rows[0]; + Assert.That(results[0].id, Is.EqualTo(1)); + Assert.That(results[0].recId, Is.EqualTo(expected.RecId)); + Assert.That(results[0].name, Is.EqualTo(expected.Name)); + } + + SqliteDialect.Provider.NamingStrategy = hold; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/EnumAsIntAsPkTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/EnumAsIntAsPkTests.cs new file mode 100644 index 000000000..18595ce8d --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/EnumAsIntAsPkTests.cs @@ -0,0 +1,72 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class EnumAsIntAsPkTests : OrmLiteProvidersTestBase + { + public EnumAsIntAsPkTests(DialectContext context) : base(context) {} + + [Test] + public void CanCreateTable() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + } + } + + [Test] + public void CanStoreEnumValue() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.Save(new LookupTypeWithEnumAsIntAsPk { EnumAsIntAsPkId = LookupTypeEnum.Value1, EnumValueThatWouldGoInAsString = SomeEnum.Value1 }); + } + } + + [Test] + public void CanGetEnumValue() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var obj = new LookupTypeWithEnumAsIntAsPk { EnumAsIntAsPkId = LookupTypeEnum.Value1, EnumValueThatWouldGoInAsString = SomeEnum.Value1 }; + db.Save(obj); + + var target = db.SingleById(obj.EnumAsIntAsPkId); + Assert.AreEqual(obj.EnumAsIntAsPkId, target.EnumAsIntAsPkId); + Assert.AreEqual(obj.EnumValueThatWouldGoInAsString, target.EnumValueThatWouldGoInAsString); + } + } + } + + /// + /// We store all enum values in the db for + /// + [EnumAsInt] + public enum LookupTypeEnum + { + Value1 = 0, + Value2 = 1, + Value3 = 2 + } + + [Alias("LookupTypeWithEnumAsIntAsPk")] + public class LookupTypeWithEnumAsIntAsPk + { + [PrimaryKey] + public LookupTypeEnum EnumAsIntAsPkId { get; set; } + + + public SomeEnum EnumValueThatWouldGoInAsString { get; set; } + + /// + /// Allow this lookup type to be soft deleted in the future, but retaining referential integrity + /// + public bool IsDeleted { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/GeneratedSqlIssues.cs b/tests/ServiceStack.OrmLite.Tests/Issues/GeneratedSqlIssues.cs new file mode 100644 index 000000000..bf06a9643 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/GeneratedSqlIssues.cs @@ -0,0 +1,27 @@ +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class GeneratedSqlIssues : OrmLiteProvidersTestBase + { + public GeneratedSqlIssues(DialectContext context) : base(context) {} + + [Test] + public void Does_generate_valid_sql_when_param_contains_dollar_char() + { + using (var db = OpenDbConnection()) + { + var model = new Poco + { + Id = 1, + Name = "Guest$" + }; + + var sql = db.ToUpdateStatement(model); + Assert.That(sql, Is.EqualTo($"UPDATE {DialectProvider.GetQuotedTableName("Poco")} SET {DialectProvider.GetQuotedColumnName("Name")}='Guest$' WHERE {DialectProvider.GetQuotedColumnName("Id")}=1")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/JoinAliasIntIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/JoinAliasIntIssue.cs new file mode 100644 index 000000000..fdf4ee23d --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/JoinAliasIntIssue.cs @@ -0,0 +1,137 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class JoinAliasIntIssue : OrmLiteProvidersTestBase + { + public JoinAliasIntIssue(DialectContext context) : base(context) {} + + class Team + { + public int Id { get; set; } + + public string Name { get; set; } + + public int? TeamLeaderId { get; set; } + } + + class Teamuser + { + public int Id { get; set; } + + public string Name { get; set; } + + public int TeamId { get; set; } + } + + [Test] + public void Can_create_query_with_int_JoinAlias() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.InsertAll(new[] { + new Team + { + Id = 1, + Name = "Team 1" + }, + }); + + db.InsertAll(new[] + { + new Teamuser + { + Id = 1, + Name = "User 1", + TeamId = 1 + }, + new Teamuser + { + Id = 2, + Name = "User 2", + TeamId = 1 + }, + }); + + db.UpdateOnlyFields(new Team { TeamLeaderId = 1 }, + onlyFields: x => x.TeamLeaderId, + where: x => x.Id == 1); + + var q = db.From(); + q.Join((t, u) => t.Id == u.TeamId, db.JoinAlias("Teamuser")); + q.Join((t, u) => t.TeamLeaderId == u.Id, db.JoinAlias("Leader")); + q.Where((t, u) => t.Id == Sql.JoinAlias(u.TeamId, "Leader")); + q.Where(u => Sql.JoinAlias(u.Id, "Leader") == 1); + q.Where((t, u) => Sql.JoinAlias(t.Id, q.DialectProvider.GetQuotedTableName(ModelDefinition.Definition)) == Sql.JoinAlias(u.TeamId, "Leader")); // Workaround, but only works for fields, not constants + q.Where((user, leader) => Sql.JoinAlias(user.Id, "Teamuser") < Sql.JoinAlias(leader.Id, "Leader")); + q.Select((t, u, l) => new + { + TeamName = Sql.As(t.Name, "TeamName"), + UserName = Sql.As(u.Name, "UserName"), + LeaderName = Sql.As(l.Name, "LeaderName") + }); + + var results = db.Select(q); + } + } + + [Test] + public void Can_create_query_with_int_TableAlias() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.InsertAll(new[] { + new Team + { + Id = 1, + Name = "Team 1" + }, + }); + + db.InsertAll(new[] + { + new Teamuser + { + Id = 1, + Name = "User 1", + TeamId = 1 + }, + new Teamuser + { + Id = 2, + Name = "User 2", + TeamId = 1 + }, + }); + + db.UpdateOnlyFields(new Team { TeamLeaderId = 1 }, + onlyFields: x => x.TeamLeaderId, + where: x => x.Id == 1); + + var q = db.From(); + q.Join((t, u) => t.Id == u.TeamId, db.TableAlias("tu")); + q.Join((t, u) => t.TeamLeaderId == u.Id, db.TableAlias("leader")); + q.Where((t, u) => t.Id == Sql.TableAlias(u.TeamId, "Leader")); + q.Where(u => Sql.TableAlias(u.Id, "leader") == 1); + q.Where((t, u) => Sql.TableAlias(t.Id, q.DialectProvider.GetQuotedTableName(ModelDefinition.Definition)) == Sql.TableAlias(u.TeamId, "leader")); // Workaround, but only works for fields, not constants + q.Where((user, leader) => Sql.TableAlias(user.Id, "tu") < Sql.TableAlias(leader.Id, "leader")); + q.Select((t, u, l) => new + { + TeamName = t.Name, + UserName = Sql.TableAlias(u.Name, "tu"), + LeaderName = Sql.TableAlias(l.Name, "leader"), + }); + + var results = db.Select(q); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/JoinAliasWithSchemaIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/JoinAliasWithSchemaIssue.cs new file mode 100644 index 000000000..b4d031c33 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/JoinAliasWithSchemaIssue.cs @@ -0,0 +1,82 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [Schema("Schema")] + public class ModelWithSchema + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + + public int Value { get; set; } + } + + [TestFixtureOrmLite] + public class JoinAliasWithSchemaIssue : OrmLiteProvidersTestBase + { + public JoinAliasWithSchemaIssue(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void OneTimeSetup() + { + if (!DialectFeatures.SchemaSupport) return; + + using (var db = OpenDbConnection()) + { + db.CreateSchema(); + } + } + + [Test] + public void Can_perform_join_alias_on_ModelWithSchema() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithSchema { Name = "One", Value = 1 }); + db.Insert(new ModelWithSchema { Name = "Uno", Value = 1 }); + + var q = db.From() + .Join((a, b) => a.Value == b.Value, db.JoinAlias("b")) + .Select(x => new + { + AName = x.Name, + BName = Sql.JoinAlias(x.Name, "b") + }); + + var results = db.Select(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2 * 2)); + } + } + + [Test] + public void Can_perform_table_alias_on_ModelWithSchema() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithSchema { Name = "One", Value = 1 }); + db.Insert(new ModelWithSchema { Name = "Uno", Value = 1 }); + + var q = db.From() + .Join((a, b) => a.Value == b.Value, db.TableAlias("b")) + .Select(x => new + { + AName = x.Name, + BName = Sql.TableAlias(x.Name, "b") + }); + + var results = db.Select(q); + db.GetLastSql().Print(); + Assert.That(results.Count, Is.EqualTo(2 * 2)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/JoinBoolSqlServerIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/JoinBoolSqlServerIssue.cs new file mode 100644 index 000000000..0f84d8e12 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/JoinBoolSqlServerIssue.cs @@ -0,0 +1,86 @@ +using System.Diagnostics; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class JoinBoolSqlServerIssue : OrmLiteProvidersTestBase + { + public JoinBoolSqlServerIssue(DialectContext context) : base(context) {} + + [Test] + public void Can_Join_on_bool() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + var q = db.From() + .LeftJoin((t1, t2) => t2.BoolCol == true && t1.Id == t2.Id); + var results = db.Select(q); + + q = db.From() + .LeftJoin((t1, t2) => t2.NullableBoolCol == true && t1.Id == t2.Id); + results = db.Select(q); + + results.PrintDump(); + } + } + + [Test] + public void Can_compare_bool_in_join_expression() + { + var db = OpenDbConnection(); + + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + var exp1 = db.From() + .LeftJoin((a, ch) => a.Id == ch.AccountId && ch.TestBoolB == true); + + Debug.WriteLine(exp1.BodyExpression); + db.Select(exp1).PrintDump(); + + var exp2 = db.From() + .LeftJoin((a, ch) => a.Id == ch.AccountId && a.TestBoolA == true); + + Debug.WriteLine(exp2.BodyExpression); + db.Select(exp2).PrintDump(); + + + var exp3 = db.From() + .Where(a => a.TestBoolA == true); + Debug.WriteLine(exp3.BodyExpression); + db.Select(exp3).PrintDump(); + } + } + + public class Account + { + [PrimaryKey] + public int Id { get; set; } + + public bool TestBoolA { get; set; } + } + + public class CardHolder + { + [PrimaryKey] + public int Id { get; set; } + + [References(typeof(Account))] + public int AccountId { get; set; } + + public bool TestBoolB { get; set; } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/JoinsWithSchemas.cs b/tests/ServiceStack.OrmLite.Tests/Issues/JoinsWithSchemas.cs index f3fa4a8b0..d6fd5b96a 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/JoinsWithSchemas.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/JoinsWithSchemas.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using ServiceStack.DataAnnotations; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests.Issues { @@ -25,8 +24,22 @@ public class PlainModel public int Entity2Id { get; set; } } - public class JoinsWithSchemas : OrmLiteTestBase + [TestFixtureOrmLite] + public class JoinsWithSchemas : OrmLiteProvidersTestBase { + public JoinsWithSchemas(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void OneTimeSetup() + { + if (!DialectFeatures.SchemaSupport) return; + + using (var db = OpenDbConnection()) + { + db.CreateSchema(); + } + } + [Test] public void Can_detect_if_table_with_schema_exists() { @@ -49,7 +62,6 @@ public void Can_detect_if_table_with_schema_exists() exists = db.TableExists(); Assert.That(exists, Is.True); - } } diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/JsonUpdateOnlyIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/JsonUpdateOnlyIssue.cs new file mode 100644 index 000000000..feb50a7f5 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/JsonUpdateOnlyIssue.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)] + public class JsonUpdateOnlyIssue : OrmLiteProvidersTestBase + { + public JsonUpdateOnlyIssue(DialectContext context) : base(context) {} + + [Test] + public void Can_Update_Answer_CustomField_json() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var createTableSql = db.GetLastSql(); + Assert.That(createTableSql, Does.Contain("\"answers\" json NULL")); + + db.Insert(new Question + { + Id = 1, + Answers = new List + { + new Answer { Id = 1, Text = "Q1 Answer1" } + } + }); + + var question = db.SingleById(1); + Assert.That(question.Answers.Count, Is.EqualTo(1)); + Assert.That(question.Answers[0].Text, Is.EqualTo("Q1 Answer1")); + + db.UpdateOnly(() => new Question + { + Answers = new List { new Answer { Id = 1, Text = "Q1 Answer1 Updated" } } + }, + @where: q => q.Id == 1); + + question = db.SingleById(1); + Assert.That(question.Answers[0].Text, Is.EqualTo("Q1 Answer1 Updated")); + } + } + } + + public class Question + { + public int Id { get; set; } + public string Text { get; set; } + + [PgSqlJson] + public List Answers { get; set; } + } + + public class Answer + { + public int Id { get; set; } + public string Text { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LRAIssues.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LRAIssues.cs new file mode 100644 index 000000000..84f5f713b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LRAIssues.cs @@ -0,0 +1,829 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class AdhocJoinIssue : OrmLiteProvidersTestBase + { + public AdhocJoinIssue(DialectContext context) : base(context) {} + + [Test] + public void Can_run_LRA_Query() + { + using (var db = OpenDbConnection()) + { + CreateTables(db); + + var query = db.From() + .Join((ana, cont) => ana.ContenitoreId == cont.Id) + .Join((cont, ric) => cont.RichiestaId == ric.Id) + .Join((ric, paz) => ric.PazienteId == paz.Id) + .Select((ana, cont, ric, paz) => + new + { + AnalisiId = ana.Id, + ContenitoreId = cont.Id, + RichiestaId = ric.Id, + DataAccettazioneRichiesta = ric.DataOraAccettazione, + DataCheckinContenitore = cont.DataOraPrimoCheckin, + DataEsecuzioneAnalisi = ana.DataOraEsecuzione, + DataPrelievoContenitore = cont.DataOraPrelievo, + DataValidazioneAnalisi = ana.DataOraValidazione, + sessoPaziente = paz.Sesso, + dataDiNascitaPaziente = paz.DataDiNascita, + etaPazienteRichiesta = ric.EtaPaziente, + dataOraAccettazioneRichiesta = ric.DataOraAccettazione, + unitaMisuraEtaPaziente = ric.UnitaDiMisuraEtaPaziente, + settimaneGravidanza = ric.SettimaneGravidanza, + repartoId = ric.RepartoId, + prioritaRichiesta = ric.PrioritaId, + laboratorioRichiedente = ric.LaboratorioRichiedenteId, + prioritaContenitore = cont.PrioritaId, + idLaboratorioEsecutoreCandidatoAnalisi = ana.LaboratorioEsecutoreCandidatoId + }); + } + } + + [Test] + public void Can_run_expression_using_captured_lambda_params() + { + using (var db = OpenDbConnection()) + { + CreateTables(db); + + var idContenitore = 1; + + var q = db.From() + .Where(ana => ana.ContenitoreId == idContenitore) + .And(ana => !Sql.In(ana.Id, db.From() + .Where(ris => ris.Id == ana.ContenitoreId) + .Select(ris => new { Id = ris.Id }) + ) + ) + .Select(x => new { A = 1 }); + + var sql = q.ToSelectStatement(); + sql.Print(); + Assert.That(sql, Is.Not.Null); + } + } + + [Test] + public void Does_select_aliases_on_custom_expressions() + { + var statements = new List(); + OrmLiteConfig.BeforeExecFilter = cmd => statements.Add(cmd.GetDebugString()); + + using (var db = OpenDbConnection()) + { + var ADeviceId = 1; + + var q = db.From(); + q.LeftJoin((a,b)=>a.Id==b.DeviceId); + q.LeftJoin((a, b) => a.Id == b.DeviceID && b.Visto==(int)SiNo.No); + q.Where(x => x.Id == ADeviceId); + q.GroupBy((dev,con, ale) => new {dev.Id, con.DeviceId, ale.DeviceID,ale.Tipo }); + q.Select((dev, con, ale) => new //DeviceDashboardDTO + { + DeviceId = dev.Id, + //Device = dev, + StatoLinea = Sql.Min(con.StatoConnessione), + StatoQC = (Sql.Count(ale.Tipo == (int)TipoAlert.AlertQC ? ale.Id : 0) > 0 ? (int)SiNo.Si : (int)SiNo.No), + StatoWarning = (Sql.Count(ale.Tipo == (int)TipoAlert.WarningDevice ? ale.Id : 0) > 0 ? (int)SiNo.Si : (int)SiNo.No) + }); + + + try + { + var results = db.Select(q); + } + catch {} // no tables + + var lastStatement = statements.Last(); + lastStatement.Print(); + + lastStatement = lastStatement.NormalizeSql(); + Assert.That(lastStatement, Does.Contain("as deviceid")); + Assert.That(lastStatement, Does.Contain("as statolinea")); + Assert.That(lastStatement, Does.Contain("as statoqc")); + Assert.That(lastStatement, Does.Contain("as statowarning")); + } + } + + [Test] + public async Task Does_RowCount_LRARichiesta_Async() + { + using (var db = OpenDbConnection()) + { + CreateTables(db); + + var q = db.From() + .Where(x => x.Id > 0); + + var result = await db.RowCountAsync(q); + } + } + + [Test] + public void Does_InsertIntoSelect_LRARichiesta() + { + using (var db = OpenDbConnection()) + { + RecreateLRARichiesta(db); + + long numeroRichieste = db.Count(); + + var q = db.From() + .Select(ric => new //LRARisultato + { + AnalisiId = 1, + Commento = ric.Commento, + TipoValore = 1, + Stato = 1, + RisultatoId = 1, + DataOraRicezione = DateTime.UtcNow, + DataModifica = DateTime.UtcNow, + VersioneRecord = 1, + InviareALIS = 1, + RisultatoPrincipale = 1, + TipoInserimento = 1, + Citrato = 1, + }); + + long result = db.InsertIntoSelect(q); + + Assert.That(result, Is.EqualTo(numeroRichieste)); + } + } + + private static void RecreateLRARichiesta(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + } + + [Test] + public async Task Does_InsertIntoSelect_LRARichiesta_Async() + { + using (var db = OpenDbConnection()) + { + RecreateLRARichiesta(db); + + long numeroRichieste = await db.CountAsync(); + + var q = db.From() + .Select(ric => new //LRARisultato + { + AnalisiId = 1, + Commento = ric.Commento, + TipoValore = 1, + Stato = 1, + RisultatoId = 1, + DataOraRicezione = DateTime.UtcNow, + DataModifica = DateTime.UtcNow, + VersioneRecord = 1, + InviareALIS = 1, + RisultatoPrincipale = 1, + TipoInserimento = 1, + Citrato = 1, + }); + + long result = await db.InsertIntoSelectAsync(q); + + Assert.That(result, Is.EqualTo(numeroRichieste)); + } + } + + private static void CreateTables(IDbConnection db) + { + DropTables(db); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + } + + private static void DropTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + } + + private static void InitAliasTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + + db.Insert(new LRDAnalisi + { + Codice = "TEST", + Descrizione = "DESCRIPTION", + DataModifica = DateTime.UtcNow + }); + + db.Insert(new LRDProfiloAnalisi + { + AnalisiId = 1, + DataModifica = DateTime.UtcNow, + VersioneRecord = 1, + ProfiloAnalisiId = null + }); + } + + [Test] + public void Table_Alias() + { + using (var db = OpenDbConnection()) + { + InitAliasTables(db); + + var q = db.From(options => { + options.SetTableAlias("dana"); + options.UseSelectPropertiesAsAliases = true; + }) + .Join((dana, dcont) => dana.ContenitoreId == dcont.Id, db.TableAlias("c")) + .Join((dana, dprofana) => dana.Id == dprofana.AnalisiId, db.TableAlias("dprofana")) + .Where(dprofana => Sql.TableAlias(dprofana.ProfiloAnalisiId, "dprofana") == null) + .SelectDistinct((dana, dprofana, dcont) => + new //ProfiloAnalisiDTO + { + Id = Sql.TableAlias(dprofana.Id, "dprofana"), + AnalisiId = dana.Id, + Codice = dana.Codice, + Descrizione = dana.Descrizione, + ContenitoreId = dana.ContenitoreId, + ContenitoreCodice = Sql.TableAlias(dcont.Codice, "c"), + ContenitoreDescrizione = Sql.TableAlias(dcont.Descrizione, "c"), + VersioneRecord = Sql.TableAlias(dprofana.VersioneRecord, "dprofana") + }); + + var result = db.Select(q); + } + } + + [Test] + public void Join_Alias() + { + using (var db = OpenDbConnection()) + { + InitAliasTables(db); + + var q = db.From() + .Join((dana, dcont) => dana.ContenitoreId == dcont.Id, db.JoinAlias("c")) + .Join((dana, dprofana) => dana.Id == dprofana.AnalisiId, db.JoinAlias("dprofana")) + .Where(dprofana => Sql.JoinAlias(dprofana.ProfiloAnalisiId, "dprofana") == null) + .SelectDistinct((dana, dprofana, dcont) => + new //ProfiloAnalisiDTO + { + Id = Sql.JoinAlias(dprofana.Id, "dprofana"), + AnalisiId = dana.Id, + Codice = dana.Codice, + Descrizione = dana.Descrizione, + ContenitoreId = Sql.JoinAlias(dcont.Id, "c"), + ContenitoreCodice = Sql.JoinAlias(dcont.Codice, "c"), + ContenitoreDescrizione = Sql.JoinAlias(dcont.Descrizione, "c"), + VersioneRecord = Sql.JoinAlias(dprofana.VersioneRecord, "dprofana") + }); + + var result = db.Select(q); + } + } + } + + public class ElementoProfiloAnalisiDTO + { + public int Id { get; set; } + + public int ProfiloAnalisiId { get; set; } + + public int AnalisiId { get; set; } + + public string CodiceAnalisi { get; set; } + + public string DescrizioneAnalisi { get; set; } + + public int VersioneRecord { get; set; } + } + + public class ProfiloAnalisiDTO + { + public int Id { get; set; } + + public string Codice { get; set; } + + public string Descrizione { get; set; } + + public int ContenitoreId { get; set; } + + public string ContenitoreCodice { get; set; } + + public string ContenitoreDescrizione { get; set; } + + public int VersioneRecord { get; set; } + + public int AnalisiId { get; set; } + + public IEnumerable Elementi { get; set; } + } + + + public class DBObject : ICloneable + { + [Alias("DATAMODIFICA")] + public DateTime DataModifica { get; set; } + + [Default(1)] + [Alias("VERSIONERECORD")] + public int VersioneRecord { get; set; } + + public object Clone() + { + return MemberwiseClone(); + } + } + + public class SessiPaziente + { + public const int NonDichiarato = 0; + } + + public class UnitaMisuraEtaPaziente + { + public const int Anni = 0; + } + + [Alias("LRAANALISI")] + public class LRAAnalisi : IHasId + { + [PrimaryKey] + [AutoIncrement] + [Alias("IDAANALISI")] + public int Id { get; set; } + + [Alias("ACONTENITOREID")] + [References(typeof(LRAContenitore))] + public int ContenitoreId { get; set; } + + [Reference] + public LRAContenitore Contenitore { get; set; } + + [Alias("DATAORAVALIDAZIONE")] + public DateTime? DataOraValidazione { get; set; } + + [Alias("DLABORATORIOCANDIDATOID")] + [References(typeof(LRDLaboratorio))] + public int? LaboratorioEsecutoreCandidatoId { get; set; } + + [Alias("DATAORAESECUZIONE")] + public DateTime? DataOraEsecuzione { get; set; } + } + + [Alias("LRACONTENITORI")] + public class LRAContenitore : DBObject, IHasId + { + [PrimaryKey] + [AutoIncrement] + [Alias("IDACONTENITORE")] + public int Id { get; set; } + + [Alias("ARICHIESTAID")] + [References(typeof(LRARichiesta))] + public int RichiestaId { get; set; } + + [Alias("DPRIORITAID")] + [References(typeof(LRDPriorita))] + public int PrioritaId { get; set; } + + [Alias("DATAORAPRELIEVO")] + public DateTime? DataOraPrelievo { get; set; } + + [Alias("DATAORAPRIMOCHECKIN")] + public DateTime? DataOraPrimoCheckin { get; set; } + } + + [Alias("LRARICHIESTE")] + public class LRARichiesta : DBObject, IHasId + { + [PrimaryKey] + [AutoIncrement] + [Alias("IDARICHIESTA")] + public int Id { get; set; } + + [Alias("APAZIENTEID")] + [ForeignKey(typeof(LRAPaziente))] + public int PazienteId { get; set; } + + [Index(Unique = false)] + [Alias("DATAORAACCETTAZIONE")] + public DateTime DataOraAccettazione { get; set; } + + [Alias("ETAPAZIENTE")] + public int? EtaPaziente { get; set; } + + [Alias("UNITADIMISURAETAPAZIENTE")] + [Default((int) UnitaMisuraEtaPaziente.Anni)] + public int UnitaDiMisuraEtaPaziente { get; set; } + + [Alias("SETTIMANEGRAVIDANZA")] + public int? SettimaneGravidanza { get; set; } + + [Alias("DREPARTOID")] + [References(typeof(LRDReparto))] + public int? RepartoId { get; set; } + + [Required] + [Alias("DPRIORITAID")] + [References(typeof(LRDPriorita))] + public int PrioritaId { get; set; } + + [Required] + [References(typeof(LRDLaboratorio))] + [Alias("DLABORATORIORICHIEDENTEID")] + public int? LaboratorioRichiedenteId { get; set; } + + [Alias("COMMENTO")] + [StringLength(StringLengthAttribute.MaxText)] + public string Commento { get; set; } + } + + [Alias("LRAPAZIENTI")] + public class LRAPaziente : DBObject, IHasId + { + [PrimaryKey] + [AutoIncrement] + [Alias("IDAPAZIENTE")] + public int Id { get; set; } + + [Alias("SESSO")] + [Default((int) SessiPaziente.NonDichiarato)] + public int Sesso { get; set; } + + [Alias("DATADINASCITA")] + public DateTime? DataDiNascita { get; set; } + } + + public class LRDReparto + { + public int Id { get; set; } + } + + public class LRDPriorita + { + public int Id { get; set; } + } + + public class LRDLaboratorio + { + public int Id { get; set; } + } + + public class LRDDevice + { + public int Id { get; set; } + } + + public class LRDConnessione + { + public int Id { get; set; } + + public int DeviceId { get; set; } + + public int StatoConnessione { get; set; } + } + + public class LRAAlert + { + public int Id { get; set; } + + public int DeviceID { get; set; } + + public int Visto { get; set; } + + public int Tipo { get; set; } + } + + public static class SiNo + { + public static int No { get; set; } + + public static int Si { get; set; } + } + + public static class TipoAlert + { + public static int AlertQC { get; set; } + + public static int WarningDevice { get; set; } + } + + public class DeviceDashboardDTO + { + public int DeviceId { get; set; } + public int StatoLinea { get; set; } + public int StatoQC { get; set; } + public int StatoWarning { get; set; } + } + + [Alias("LRARISULTATI")] + [CompositeIndex("AANALISIID", "DRISULTATOID", "STATO", Unique = false, Name = "IDXLRARISULTATI")] + public class LRARisultato : DBObject, IHasId + { + [PrimaryKey] + [AutoIncrement] + [Alias("IDARISULTATO")] + public int Id { get; set; } + + [Index] + [Alias("AANALISIID")] + public int AnalisiId { get; set; } + + [Required] + [Alias("TIPOVALORE")] + public int TipoValore { get; set; } + + [Alias("OPERATORERELAZIONALE")] + public string OperatoreRelazionale { get; set; } + + [Alias("VALORENUMERICO")] + public decimal? ValoreNumerico { get; set; } + + [Index] + [Alias("DTESTOCODIFICATOID")] + public int? TestoCodificatoId { get; set; } + + [Alias("TESTOLIBERO")] + [StringLength(StringLengthAttribute.MaxText)] + public string TestoLibero { get; set; } + + [Index] + [Alias("DRISULTATOID")] + public int RisultatoId { get; set; } + + [Required] + [Alias("STATO")] + public int Stato { get; set; } + + [Alias("INVIAREALIS")] + public int InviareALIS { get; set; } + + [Alias("RISULTATOPRINCIPALE")] + public int RisultatoPrincipale { get; set; } + + [Alias("TIPOINSERIMENTO")] + public int TipoInserimento { get; set; } + + [Index] + [Alias("DOPERATOREINSERIMENTOID")] + public int? OperatoreInserimentoId { get; set; } + + [Index] + [Alias("DDEVICEID")] + public int? DeviceId { get; set; } + + [Index] + [Alias("DLABORATORIOESECUTOREID")] + public int? LaboratorioEsecutoreId { get; set; } + + [Alias("CITRATO")] + public int Citrato { get; set; } + + [Alias("DATAORARIPETIZIONE")] + public DateTime? DataOraRipetizione { get; set; } + + [Alias("DATAORAESECUZIONE")] + public DateTime? DataOraEsecuzione { get; set; } + + [Alias("DATAORARICEZIONE")] + public DateTime DataOraRicezione { get; set; } + + [Alias("IDENTIFICATIVODEVICE")] + public string IdentificativoDevice { get; set; } + + [Alias("POSIZIONESUDEVICE")] + public string PosizioneSuDevice { get; set; } + + [Alias("REAGENTE")] + public string Reagente { get; set; } + + [Alias("LOTTOREAGENTE")] + public string LottoReagente { get; set; } + + [Alias("DATASCADENZAREAGENTE")] + public DateTime? DataScadenzaReagente { get; set; } + + [Alias("CURVADICALIBRAZIONE")] + public string CurvaDiCalibrazione { get; set; } + + [Index] + [Alias("DDILUIZIONEID")] + public int? DiluizioneId { get; set; } + + [Index] + [Alias("DRANGENORMALITAID")] + public int? RangeNormalitaId { get; set; } + + [Index] + [Alias("DRANGECONVALIDAID")] + public int? RangeConvalidaId { get; set; } + + [Index] + [Alias("DDELTACHECKSTORICOID")] + public int? DeltaCheckStoricoId { get; set; } + + [Index] + [Alias("DDELTACHECKROUTINEID")] + public int? DeltaCheckRoutineId { get; set; } + + [Index] + [Alias("DREGOLACONVALIDAID")] + public int? RegolaConvalidaId { get; set; } + + [Alias("COMMENTO")] + [StringLength(StringLengthAttribute.MaxText)] + public string Commento { get; set; } + + [StringLength(250)] + [Alias("RISULTATORAW")] + public string RisultatoRaw { get; set; } + + [Index] + [References(typeof(LRARisultato))] + [Alias("ADELTARISULTATOSTORICODID")] + public int? DeltaRisultatoStoricoId { get; set; } + + [Index] + [References(typeof(LRARisultato))] + [Alias("ADELTARISULTATOPRECEDENTEID")] + public int? DeltaRisultatoPrecedenteId { get; set; } + } + + [Alias("LRDPROFILOANALISI")] + [CompositeIndex("DPROFILOANALISIID", "DANALISIID", Unique = true, Name = "IDXPROFILO")] + public class LRDProfiloAnalisi : DBObject, IHasId + { + [Alias("IDDPROFILOANALISI")] + [AutoIncrement] + [PrimaryKey] + public int Id { get; set; } + + [ApiMember(Description = "Analisi profilo a cui appartiene l'analisi")] + [Alias("DPROFILOANALISIID")] + [References(typeof(LRDProfiloAnalisi))] + public int? ProfiloAnalisiId { get; set; } // dove NULL allora DANALISIID e' l'analisi profilo + + [ApiMember(Description = "Analisi dal dizionario")] + [Alias("DANALISIID")] + [References(typeof(LRDAnalisi))] + public int AnalisiId { get; set; } + } + + [Alias("LRDCONTENITORI")] + public class LRDContenitore : DBObject, IHasId + { + private const int CColore = 7; // lunghezza colore HTML es. #AABBCC + private const int CPrefisso = 5; + + [Alias("IDDCONTENITORE")] + [AutoIncrement] + [PrimaryKey] + public int Id { get; set; } + + [Alias("CODICE")] + [Required] + [Index(Unique = true)] + public string Codice { get; set; } + + [Required] + [Alias("DESCRIZIONE")] + public string Descrizione { get; set; } + + [Alias("DESCRIZIONEESTESA")] + public string DescrizioneEstesa { get; set; } + + [Alias("ORDINE")] + [Required] + public int Ordine { get; set; } + + [Required] + [Alias("TIPOCONTENITORE")] + public int TipoContenitore { get; set; } + + [Alias("COLORE")] + [StringLength(CColore)] + public string Colore { get; set; } + + [Alias("PREFISSO")] + [StringLength(CPrefisso)] + public string Prefisso { get; set; } + + [Alias("PROGRESSIVOBARCODEMIN")] + [DecimalLength(30, 0)] + public decimal ProgressivoBarcodeMin { get; set; } + + [Alias("PROGRESSIVOBARCODEMAX")] + [DecimalLength(30, 0)] + [Default(int.MaxValue)] + public decimal ProgressivoBarcodeMax { get; set; } + + [Alias("DMATERIALEID")] + public int? MaterialeId { get; set; } + + [Alias("DETICHETTAID")] + public int? EtichettaId { get; set; } + + [Required] + [Alias("EMATOLOGIA")] + public int Ematologia { get; set; } + + [Required] + [Alias("URINE")] + public int Urine { get; set; } + } + + [Alias("LRDANALISI")] + public class LRDAnalisi : DBObject, IHasId + { + [Alias("IDDANALISI")] + [AutoIncrement] + [PrimaryKey] + public int Id { get; set; } + + [Alias("CODICE")] + [Required] + [Index(Unique = true)] + public string Codice { get; set; } + + [Alias("DESCRIZIONE")] + [Required] + public string Descrizione { get; set; } + + [Alias("DESCRIZIONEESTESA")] + public string DescrizioneEstesa { get; set; } + + [Alias("CODICEREGIONALE")] + public string CodiceRegionale { get; set; } + + [Alias("DCONTENITOREID")] + public int ContenitoreId { get; set; } + + [Alias("ORDINE")] + public int Ordine { get; set; } + + [Alias("DMETODOID")] + public int? MetodoId { get; set; } + + [Alias("DPANNELLOANALISIID")] + public int? PannelloAnalisiId { get; set; } + + [Alias("DCLASSEANALISIID")] + public int? ClasseAnalisiId { get; set; } + + [Alias("QCREGISTRAZIONERISULTATI")] + public int QCRegistrazioneRisultati { get; set; } + + [Alias("QCVERIFICA")] + public int QCVerifica { get; set; } + + [Alias("QCOREINTERVALLOVERIFICA")] + public int? QCOreIntervalloVerifica { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferenceIssueWithCyclicalForeignKeys.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferenceIssueWithCyclicalForeignKeys.cs new file mode 100644 index 000000000..efa4c4153 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferenceIssueWithCyclicalForeignKeys.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLiteDialects(Dialect.Sqlite | Dialect.MySql)] + public class LoadReferenceIssueWithCyclicalForeignKeys : OrmLiteProvidersTestBase + { + public LoadReferenceIssueWithCyclicalForeignKeys(DialectContext context) : base(context) { } + + public class BaseEntity + { + [AutoIncrement] + [PrimaryKey] + public long Id { get; set; } + } + + public class ResearchEntity : BaseEntity + { + [References(typeof(NameEntity))] + public long? PrimaryNameId { get; set; } + + [Reference] + public NameEntity PrimaryName { get; set; } + + [Reference] + public List Names { get; set; } = new List(); + } + + public class NameEntity : BaseEntity + { + public string Value { get; set; } + + [References(typeof(ResearchEntity))] + public long ResearchId { get; set; } + + [Reference] + public ResearchEntity Research { get; set; } + } + + private void RecreateTables(IDbConnection db) + { + db.DisableForeignKeysCheck(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + db.EnableForeignKeysCheck(); + } + + [Test] + public void Does_update_self_FK_Key_when_saving_references() + { + using var db = OpenDbConnection(); + RecreateTables(db); + + for (var i = 1; i <= 5; i++) + { + var research = new ResearchEntity(); + research.Names.Add(new NameEntity {Value = $"test {1 + i}"}); + research.Names.Add(new NameEntity {Value = $"test {2 + i}"}); + research.Names.Add(new NameEntity {Value = $"test {3 + i}"}); + + db.Save(research, references: true); + research.PrimaryNameId = research.Names[1].Id; + db.Save(research); + } + + OrmLiteUtils.PrintSql(); + var res = db.LoadSelect( + db.From().Where(x => x.Id == 5)) + .FirstNonDefault(); + Assert.That(res.PrimaryName.Id, Is.EqualTo(res.PrimaryNameId)); + } + + [Test] + public async Task Does_update_self_FK_Key_when_saving_references_Async() + { + using var db = await OpenDbConnectionAsync(); + RecreateTables(db); + + for (var i = 1; i <= 5; i++) + { + var research = new ResearchEntity(); + research.Names.Add(new NameEntity {Value = $"test {1 + i}"}); + research.Names.Add(new NameEntity {Value = $"test {2 + i}"}); + research.Names.Add(new NameEntity {Value = $"test {3 + i}"}); + + await db.SaveAsync(research, references: true); + research.PrimaryNameId = research.Names[1].Id; + await db.SaveAsync(research); + } + + OrmLiteUtils.PrintSql(); + var res = (await db.LoadSelectAsync( + db.From().Where(x => x.Id == 5))) + .FirstNonDefault(); + Assert.That(res.PrimaryName.Id, Is.EqualTo(res.PrimaryNameId)); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesCaseSensitiveTest.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesCaseSensitiveTest.cs new file mode 100644 index 000000000..7567cfb7a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesCaseSensitiveTest.cs @@ -0,0 +1,104 @@ +using ServiceStack.DataAnnotations; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + /// This test set is used to demonstrate that the OrmLite Load methods are unexpectedly case-sensitive for + /// string-based columns. A reference will not be loaded if there is a difference in case between otherwise matching parent + /// value and child values. For example, parent table has RegionCode = "WEST" while it's related lookup table Region has + /// RegionCode = "West". + /// Target database must be setup as case-insensitive or this exercise is pointless. Refer to custom + /// openDbConnection method included in this test set. + public class CustomerWithRegion + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + + [CustomField("VARCHAR(8000) COLLATE Latin1_General_CI_AS")] + public string RegionId { get; set; } + + [Reference] + public Region RegionDetail { get; set; } + } + + public class Region + { + [PrimaryKey] + [CustomField("VARCHAR(8000) COLLATE Latin1_General_CI_AS")] + public string Id { get; set; } + + public string RegionName { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class LoadReferencesCaseSensitiveTest : OrmLiteProvidersTestBase + { + public LoadReferencesCaseSensitiveTest(DialectContext context) : base(context) {} + + const string regionCode = "West"; + const string regionName = "Western Region"; + + /// This test is used to demonstrate that the OrmLite Load methods are unexpectedly case-sensitive for + /// string-based columns. A reference will not be loaded if there is a difference in case between otherwise matching parent + /// value and child values. For example, parent table has RegionCode = "WEST" while it's related lookup table Region has + /// RegionCode = "West". + [Test] + public void LoadReference_with_Case_Variance() + { + OrmLiteConfig.IsCaseInsensitive = true; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + //db.GetLastSql().Print(); + db.DropAndCreateTable(); + //db.GetLastSql().Print(); + + var region = new Region { Id = regionCode, RegionName = regionName }; + db.Save(region); + + var caseInsensitiveRegion = db.Single(x => x.Id == regionCode.ToUpper()); + Assert.That(caseInsensitiveRegion.Id, Is.EqualTo(regionCode)); + + var customers = new List + { + new CustomerWithRegion { Name = "Acme Anvil Co.", RegionId = regionCode }, + new CustomerWithRegion { Name = "Penny's Poodle Emporium", RegionId = regionCode.ToUpper() }, + }; + + foreach (var customer in customers) + { + db.Save(customer); + + var dbCustomer = db.LoadSelect(s => s.Name == customer.Name).FirstOrDefault(); + + dbCustomer.PrintDump(); + + Assert.That( + dbCustomer.RegionId, + Is.Not.Null, + $"Region code missing for {customer.Name}"); + Assert.That( + dbCustomer.RegionId.ToLower() == regionCode.ToLower(), + $"Region code incorrect for {customer.Name}"); + + // The following assertion will fail because LoadSelect considers CustomWithRegion.RegionCode of "WEST" != to Region.RegionCode of "West". + Assert.That( + dbCustomer.RegionDetail, + Is.Not.Null, + $"Region detail record missing for {customer.Name}"); + Assert.That( + dbCustomer.RegionDetail.RegionName == regionName, + $"Region name incorrect for {customer.Name}"); + } + } + + OrmLiteConfig.IsCaseInsensitive = false; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesFKandSelfRefIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesFKandSelfRefIssue.cs new file mode 100644 index 000000000..08fda4166 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesFKandSelfRefIssue.cs @@ -0,0 +1,54 @@ +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class PareInfo + { + [AutoIncrement] + public int Id { get; set; } + public string name { get; set; } + public int? PareInfoId { get; set; } + [Reference] + public PareInfo Pare { get; set; } + } + + [TestFixtureOrmLite] + public class LoadReferencesFKandSelfRefIssue : OrmLiteProvidersTestBase + { + public LoadReferencesFKandSelfRefIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_not_populate_both_FK_and_self_reference() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var p1 = new PareInfo { name = "p1" }; + var p2 = new PareInfo + { + name = "p2", + }; + p1.Pare = p2; + + db.Save(p1, references: true); + + var p1AndRefs = db.LoadSingleById(p1.Id); + Assert.That(p1AndRefs.Pare, Is.Not.Null); + Assert.That(p1AndRefs.PareInfoId, Is.EqualTo(p2.Id)); + + var p2AndRefs = db.LoadSingleById(p2.Id); + Assert.That(p2AndRefs.Pare, Is.Null); + Assert.That(p2AndRefs.PareInfoId, Is.Null); + + var rows = db.Select().OrderBy(x => x.Id).ToList(); + Assert.That(rows[0].name, Is.EqualTo("p1")); + Assert.That(rows[0].PareInfoId, Is.EqualTo(p2.Id)); + Assert.That(rows[1].name, Is.EqualTo("p2")); + Assert.That(rows[1].PareInfoId, Is.Null); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesForeignKeyTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesForeignKeyTests.cs new file mode 100644 index 000000000..5eb9c65be --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesForeignKeyTests.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class Root + { + [PrimaryKey] + public int RootId { get; set; } + + [Reference] + public List Items { get; set; } + } + + public class RootItem + { + [PrimaryKey] + public int RootItemId { get; set; } + + public int RootId { get; set; } //`{Parent}Id` convention to refer to Client + + public string MyValue { get; set; } + } + + [TestFixtureOrmLite] + public class LoadReferencesForeignKeyTests : OrmLiteProvidersTestBase + { + public LoadReferencesForeignKeyTests(DialectContext context) : base(context) {} + + [Test] + public void Does_populate_Ref_Ids_of_non_convention_PrimaryKey_Tables() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var root = new Root { + RootId = 1, + Items = new List { + new RootItem { RootItemId = 2, MyValue = "x" } + } + }; + + db.Save(root, references: true); + + Assert.That(root.Items[0].RootId, Is.EqualTo(root.RootId)); + } + } + + [Alias("Users")] + public class User + { + [AutoId] + public Guid Id { get; set; } + + [Reference] + public List Branches { get; set; } + + [Reference] + public UserMeta Meta { get; set; } + + [Reference] + public List Addresses { get; set; } + } + + [Alias("UserMetas")] + public class UserMeta + { + [PrimaryKey] + [ForeignKey(typeof(User), OnDelete = "CASCADE", OnUpdate = "CASCADE")] + [References(typeof(User))] + public Guid UserId { get; set; } + } + + [Alias("UserBranches")] + public class UserBranch + { + [AutoId] + public Guid Id { get; set; } + + [ForeignKey(typeof(User), OnDelete = "CASCADE", OnUpdate = "CASCADE")] + public Guid UserId { get; set; } + + public string Details { get; set; } + } + + [Alias("UserAddresses")] + public class UserAddress + { + [AutoId] + public Guid Id { get; set; } + + [ForeignKey(typeof(User), OnDelete = "CASCADE", OnUpdate = "CASCADE")] + public Guid UserId { get; set; } + + public string Details { get; set; } + } + + private static void InitDb(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + } + + [Test] + public void Can_create_tables_with_multiple_references() + { + using (var db = OpenDbConnection()) + { + InitDb(db); + } + + var userMeta = new UserMeta(); + var user = new User + { + Meta = userMeta + }; + + using (var db = OpenDbConnection()) + { + user.Branches = new List { new() { UserId = user.Id }}; + user.Addresses = new List { new() { UserId = user.Id }}; + + db.Save(user, references: true); + + var fromDb = db.LoadSingleById(user.Id); + fromDb.Dump().Print(); + } + } + + [Test] + public async Task Can_create_tables_with_multiple_references_async() + { + using (var db = await OpenDbConnectionAsync()) + { + InitDb(db); + } + + var userMeta = new UserMeta(); + var user = new User + { + Meta = userMeta + }; + + using (var db = await OpenDbConnectionAsync()) + { + user.Branches = new List { new() { UserId = user.Id }}; + user.Addresses = new List { new() { UserId = user.Id }}; + + await db.SaveAsync(user, references: true); + + var fromDb = await db.LoadSingleByIdAsync(user.Id); + fromDb.Dump().Print(); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesNullReferenceIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesNullReferenceIssue.cs new file mode 100644 index 000000000..c9e97de99 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LoadReferencesNullReferenceIssue.cs @@ -0,0 +1,48 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class DepartmentEntity + { + [PrimaryKey] + [StringLength(250)] + public string Name { get; set; } + + public string Description { get; set; } + + [StringLength(254)] + public string Email { get; set; } + + [References(typeof(UserAuth))] + public int? ManagerId { get; set; } + + [Reference] + public UserAuth Manager { get; set; } + } + + [TestFixtureOrmLite] + public class LoadReferencesNullReferenceIssue : OrmLiteProvidersTestBase + { + public LoadReferencesNullReferenceIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_not_load_references_when_RefId_is_null() + { + using (var db = OpenDbConnection()) + { + //db.DropAndCreateTable(); //This test shouldn't query this table + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new DepartmentEntity { Name = "Dept A", Email = "asif@depta.com" }); + + var result = db.LoadSingleById("Dept A"); + + db.DropTable(); + + Assert.That(result, Is.Not.Null); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LoadSelectIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LoadSelectIssue.cs new file mode 100644 index 000000000..90128057c --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LoadSelectIssue.cs @@ -0,0 +1,232 @@ +using System; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class LoadSelectIssue : OrmLiteProvidersTestBase + { + public LoadSelectIssue(DialectContext context) : base(context) {} + + public class PlayerEquipment + { + public string Id => $"{PlayerId}/{ItemId}"; + + public int PlayerId { get; set; } + + [References(typeof(ItemData))] + public int ItemId { get; set; } + + public int Quantity { get; set; } + + public bool IsEquipped { get; set; } + + [Reference] + public ItemData ItemData { get; set; } + } + + public class ItemData + { + [AutoIncrement] + public int Id { get; set; } + + public string Data { get; set; } + } + + [Test] + public void Can_LoadSelect_PlayerEquipment() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + var item1 = new ItemData { Data = "ITEM1" }; + db.Save(item1); + + db.Save(new PlayerEquipment + { + PlayerId = 1, + ItemId = item1.Id, + Quantity = 1, + IsEquipped = true, + }); + + var item2 = new ItemData { Data = "ITEM2" }; + db.Save(item2); + + db.Save(new PlayerEquipment + { + PlayerId = 1, + ItemId = item2.Id, + Quantity = 1, + IsEquipped = false, + }); + + var playerId = 1; + var results = db.LoadSelect(q => q.PlayerId == playerId); + + results.PrintDump(); + } + } + + [Alias("EventCategory")] + public class EventCategoryTbl : IHasSoftDelete, IHasTimeStamp + { + [PrimaryKey] + public Guid EventCategoryId { get; set; } + + + [System.ComponentModel.DataAnnotations.Required] + public string Name { get; set; } + + /// + /// Link to the file record that contains any image related to this category + /// + [References(typeof(FileTbl))] + public Guid LinkedImageId { get; set; } + + [Reference] + public FileTbl LinkedImage { get; set; } + + public bool IsDeleted { get; set; } + + [RowVersion] + public ulong RowVersion { get; set; } + } + + [Alias("File")] + public class FileTbl : IHasSoftDelete, IHasTimeStamp + { + [PrimaryKey] + public Guid FileId { get; set; } + + public string Name { get; set; } + + public string Extension { get; set; } + + public long FileSizeBytes { get; set; } + + public bool IsDeleted { get; set; } + + [RowVersion] + public ulong RowVersion { get; set; } + } + + public interface IHasTimeStamp + { + [RowVersion] + ulong RowVersion { get; set; } + } + + public interface IHasSoftDelete + { + bool IsDeleted { get; set; } + } + + private static void CreateTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + } + + [Test] + public void Can_execute_LoadSelect_when_child_references_implement_IHasSoftDelete() + { + // Automatically filter out all soft deleted records, for ALL table types. + OrmLiteConfig.SqlExpressionSelectFilter = q => + { + if (q.ModelDef.ModelType.HasInterface(typeof(IHasSoftDelete))) + { + q.Where(x => x.IsDeleted != true); + } + }; + + using (var db = OpenDbConnection()) + { + CreateTables(db); + + var results = db.LoadSelect(); + } + + OrmLiteConfig.SqlExpressionSelectFilter = null; + } + + [Test] + public void Can_execute_SoftDelete_with_GroupBy() + { + OrmLiteConfig.SqlExpressionSelectFilter = q => + { + if (q.ModelDef.ModelType.HasInterface(typeof(IHasSoftDelete))) + { + q.Where(x => x.IsDeleted != true); + } + }; + + using (var db = OpenDbConnection()) + { + CreateTables(db); + + var name = "name"; + var q = db.From() + .Where(x => x.Name == name && x.FileSizeBytes > 1000) + .GroupBy(x => x.Extension) + .Select(x => new { x.Extension, Total = Sql.As(Sql.Count("*"), "Total") }); + + var results = db.Dictionary(q); + } + + OrmLiteConfig.SqlExpressionSelectFilter = null; + } + + public class Person + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + + public int ContactId { get; set; } + + [Reference] + public Contact Contact { get; set; } + } + + public class Contact + { + [AutoIncrement] + public int Id { get; set; } + + public string Mobile { get; set; } + } + + [Test] + public async Task Can_order_by_parent_table_in_LoadSelectAsync() + { + OrmLiteConfig.BeforeExecFilter = cmd => cmd.GetDebugString().Print(); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + string[] include = null; + var personQuery = db.From(); + personQuery.OrderByFields("Id"); + + var results = await db.LoadSelectAsync(personQuery, include); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/LoadSelectResultFilterIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/LoadSelectResultFilterIssue.cs new file mode 100644 index 000000000..d88b22ae4 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/LoadSelectResultFilterIssue.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class TestResultsFilter : OrmLiteResultsFilter + { + public TestResultsFilter() + { + ResultsFn = TestFilter; + //RefResultsFn = TestFilter; //used to mock LoadSelect child references + } + + private IEnumerable TestFilter(IDbCommand dbCmd, Type refType) + { + var typedResults = dbCmd.ExecuteReader().ConvertToList(dbCmd.GetDialectProvider(), refType); + return typedResults; + } + } + + public class Parent + { + [AutoIncrement] + public long Id { get; set; } + public string Content { get; set; } + + [Reference] + public List Children { get; set; } + } + + + public class Child + { + [AutoIncrement] + public long Id { get; set; } + public string Content { get; set; } + + [References(typeof(Parent))] + public long? ParentId { get; set; } + [Reference] + public Parent Parent { get; set; } + } + + [TestFixtureOrmLite] + public class LoadSelectResultFilterIssue : OrmLiteProvidersTestBase + { + public LoadSelectResultFilterIssue(DialectContext context) : base(context) {} + + [Test] + public void Can_use_results_filter_in_LoadSelect() + { + using (var db = OpenDbConnection()) + { + try + { + db.DropTable(); + db.DropTable(); + } + catch (Exception e) + { + db.DropTable(); + db.DropTable(); + } + + db.CreateTable(); + db.CreateTable(); + + var newParent = new Parent + { + Content = "Test Parent", + Children = new List + { + new Child {Content = "Test Child 1"}, + new Child {Content = "Test Child 2"} + } + }; + + db.Save(newParent, references: true); + } + + using (new TestResultsFilter()) + using (var db = OpenDbConnection()) + { + var savedParents = db.LoadSelect(); + Assert.That(savedParents.Count, Is.EqualTo(1)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MappingFieldIssues.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MappingFieldIssues.cs new file mode 100644 index 000000000..c479e0aab --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MappingFieldIssues.cs @@ -0,0 +1,53 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class MappingFieldIssues : OrmLiteProvidersTestBase + { + public MappingFieldIssues(DialectContext context) : base(context) {} + + public class OriginalTable + { + public int Id { get; set; } + public DateTime SaleDate { get; set; } + public TimeSpan SaleTime { get; set; } + public int NumberOfItems { get; set; } + public decimal Amount { get; set; } + } + + [Alias("OriginalTable")] + public class MismatchTable + { + public int Id { get; set; } + public DateTime SaleDate { get; set; } + public DateTime SaleTime { get; set; } + public int NumberOfItems { get; set; } + public decimal Amount { get; set; } + } + + [Test] + public void Does_map_remaining_columns_after_failed_mapping() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.Insert(new OriginalTable + { + Id = 1, + SaleDate = new DateTime(2001, 01, 01), + SaleTime = new TimeSpan(1,1,1,1), + NumberOfItems = 2, + Amount = 3 + }); + + var result = db.SingleById(1); + Assert.That(result.NumberOfItems, Is.EqualTo(2)); + Assert.That(result.Amount, Is.EqualTo(3)); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MappingFieldsFromStoredProcedureTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MappingFieldsFromStoredProcedureTests.cs index e435d214f..cafb45aac 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/MappingFieldsFromStoredProcedureTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MappingFieldsFromStoredProcedureTests.cs @@ -37,11 +37,12 @@ public class DomainUserDto public string Details { get; set; } } - [NUnit.Framework.Ignore("Requires existing tables / SP at https://gist.github.com/mythz/6f336094f8dd07c22d91")] - [TestFixture] - public class MappingFieldsFromStoredProcedureTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class MappingFieldsFromStoredProcedureTests : OrmLiteProvidersTestBase { - [Test] + public MappingFieldsFromStoredProcedureTests(DialectContext context) : base(context) {} + + [NUnit.Framework.Ignore("Requires existing tables / SP at https://gist.github.com/mythz/6f336094f8dd07c22d91"), Test] public void Can_select_from_Custom_stored_procedure() { using (var db = OpenDbConnection()) diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MergeParamsIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MergeParamsIssue.cs new file mode 100644 index 000000000..9c5cf1f7e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MergeParamsIssue.cs @@ -0,0 +1,53 @@ +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class Record + { + public int Id { get; set; } + public int Value { get; set; } + } + + [TestFixtureOrmLite] + public class MergeParamsIssue : OrmLiteProvidersTestBase + { + public MergeParamsIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_merge_params_correctly() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertAll(new[] { + new Record { Id = 1, Value = 1, }, + }); + + var x1 = db.SingleById(1); + var q = db.From(); + q.Where(x => x.Value == 1); + q.Where(x => x.Value == 1); + q.Where(x => x.Value == 1); + q.Where(x => x.Value == 1); + q.Where(x => x.Value == 1); + q.Where(x => x.Value == 1); + q.Where(x => x.Value == 1); + q.Where(x => x.Value == 1); + + var qIn = db.From(); + qIn.Where(x => x.Value == 1); + qIn.Where(x => x.Value == 1 && x.Value == 1); + q.Where(x => Sql.In(x.Value, qIn)); + var expression = q.ToSelectStatement(); + expression.Print(); + + for (var i = 0; i < 11; i++) + { + Assert.That(expression, Does.Contain(DialectProvider.ParamString + i)); + } + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MergingNestedSqlExpressionIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MergingNestedSqlExpressionIssue.cs new file mode 100644 index 000000000..1f9c972ec --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MergingNestedSqlExpressionIssue.cs @@ -0,0 +1,66 @@ +using System; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class Organization + { + public Guid Id { get; set; } + public bool IsActive { get; set; } + public string Name { get; set; } + } + + public class OrganizationMembership + { + public Guid Id { get; set; } + public Guid OrganizationId { get; set; } + public bool HasA { get; set; } + public bool HasB { get; set; } + public bool HasC { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.Sqlite)] + public class MergingNestedSqlExpressionIssue : OrmLiteProvidersTestBase + { + public MergingNestedSqlExpressionIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_merge_subselect_params_correctly() + { + // select a group of ids + var ids = DialectProvider.SqlExpression(); + ids.Where(x => x.HasA == true && x.HasB == true && x.HasC == true); + ids.SelectDistinct(x => x.OrganizationId); + + //0 params + var q = DialectProvider.SqlExpression(); + q.Where(x => Sql.In(x.Id, ids)); + Assert.That(q.WhereExpression, Is.EqualTo( + "WHERE \"Id\" IN (SELECT DISTINCT \"OrganizationId\" \nFROM \"OrganizationMembership\"\nWHERE (((\"HasA\" = @0) AND (\"HasB\" = @1)) AND (\"HasC\" = @2)))")); + + //1 param + q = DialectProvider.SqlExpression(); + q.Where(x => x.IsActive == true); + q.Where(x => Sql.In(x.Id, ids)); + Assert.That(q.WhereExpression, Is.EqualTo( + "WHERE (\"IsActive\" = @0) AND \"Id\" IN (SELECT DISTINCT \"OrganizationId\" \nFROM \"OrganizationMembership\"\nWHERE (((\"HasA\" = @1) AND (\"HasB\" = @2)) AND (\"HasC\" = @3)))")); + + //2 params + q = DialectProvider.SqlExpression(); + q.Where(x => x.IsActive == true); + q.Where(x => x.IsActive == true); + q.Where(x => Sql.In(x.Id, ids)); + Assert.That(q.WhereExpression, Is.EqualTo( + "WHERE (\"IsActive\" = @0) AND (\"IsActive\" = @1) AND \"Id\" IN (SELECT DISTINCT \"OrganizationId\" \nFROM \"OrganizationMembership\"\nWHERE (((\"HasA\" = @2) AND (\"HasB\" = @3)) AND (\"HasC\" = @4)))")); + + //3 params + q = DialectProvider.SqlExpression(); + q.Where(x => x.IsActive == true); + q.Where(x => x.IsActive == true); + q.Where(x => x.IsActive == true); + q.Where(x => Sql.In(x.Id, ids)); + Assert.That(q.WhereExpression, Is.EqualTo( + "WHERE (\"IsActive\" = @0) AND (\"IsActive\" = @1) AND (\"IsActive\" = @2) AND \"Id\" IN (SELECT DISTINCT \"OrganizationId\" \nFROM \"OrganizationMembership\"\nWHERE (((\"HasA\" = @3) AND (\"HasB\" = @4)) AND (\"HasC\" = @5)))")); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MetadataPrimaryKeyIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MetadataPrimaryKeyIssue.cs new file mode 100644 index 000000000..7a466cf77 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MetadataPrimaryKeyIssue.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Expression; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class MetadataPrimaryKeyIssue : OrmLiteProvidersTestBase + { + public MetadataPrimaryKeyIssue(DialectContext context) : base(context) {} + + [Test] + public void Should_generate_select_statement_multi_threaded() + { + typeof(LetterFrequency).GetModelMetadata(); + + Task task1 = Task.Run(() => SelectStatement()); + Task task2 = Task.Run(() => SelectStatement()); + Task.WaitAll(task1, task2); + + Assert.AreEqual(task1.Result, task2.Result); + } + + private string SelectStatement() + { + var pk = typeof(LetterFrequency).GetModelMetadata().PrimaryKey; + using (var db = OpenDbConnection()) + { + return db.From().OrderByFields(pk).ToSelectStatement(); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MismatchSchemaTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MismatchSchemaTests.cs index 10d732a8e..c599dcddc 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/MismatchSchemaTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MismatchSchemaTests.cs @@ -28,10 +28,11 @@ public class ModelIntValue } } - [TestFixture] - public class MismatchSchemaTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class MismatchSchemaTests : OrmLiteProvidersTestBase { + public MismatchSchemaTests(DialectContext context) : base(context) {} + [Test] public void Does_allow_reading_from_table_with_mismatched_nullable_int_type() { @@ -64,7 +65,7 @@ public void Does_allow_reading_from_table_with_mismatched_number_types() } } - [Schema("Schema1")] + [Schema("schema1")] public class Poco { public int Id { get; set; } @@ -78,16 +79,18 @@ public void Can_change_schema_at_runtime() using (var db = OpenDbConnection()) { var modelDef = OrmLiteUtils.GetModelDefinition(typeof(Poco)); + + modelDef.Schema = "schema2"; db.SingleById(1); - Assert.That(captured.SqlStatements.Last(), Is.StringContaining("Schema1")); + Assert.That(captured.SqlStatements.Last().ToLower(), Does.Contain("schema2")); - modelDef.Schema = "Schema2"; + modelDef.Schema = "schema3"; db.SingleById(1); - Assert.That(captured.SqlStatements.Last(), Is.StringContaining("Schema2")); + Assert.That(captured.SqlStatements.Last().ToLower(), Does.Contain("schema3")); } } } diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultiColumnOrderByDescending.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultiColumnOrderByDescending.cs index 41fef6b40..e35eb5a07 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/MultiColumnOrderByDescending.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MultiColumnOrderByDescending.cs @@ -1,15 +1,19 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using NUnit.Framework; using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests.Issues { - [TestFixture] - public class MultiColumnOrderByDescending : OrmLiteTestBase + [TestFixtureOrmLite] + public class MultiColumnOrderByDescending : OrmLiteProvidersTestBase { + public MultiColumnOrderByDescending(DialectContext context) : base(context) {} + private List _people; - [TestFixtureSetUp] + [OneTimeSetUp] public new void TestFixtureSetUp() { _people = new List @@ -83,5 +87,37 @@ public void Does_orderbydescending_multiple_columns_using_orderbydescending() Assert.That(result[0].Id, Is.EqualTo(2)); } } + + public class Record + { + public int Id { get; set; } + public double Value { get; set; } + public DateTime? Time { get; set; } + } + + [Test] + public void Can_OrderBy_DateTime() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertAll(new[] { + new Record + { + Id = 1, + Value = 50, + Time = DateTime.Now, + }, + }); + + var q = db.From(); + q.OrderByDescending(x => x.Time ?? DateTime.UtcNow); + + var results = db.Select(q); + + results.PrintDump(); + } + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultiFieldReferenceTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultiFieldReferenceTests.cs index dd36bc11b..a4c930d56 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/MultiFieldReferenceTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MultiFieldReferenceTests.cs @@ -34,11 +34,11 @@ public class AliasedCustomer public int Id { get; set; } public string Name { get; set; } - [Alias("_id_home_address")] + [Alias("id_home_address")] [ForeignKey(typeof(AliasedCustomerAddress))] public int? HomeAddressId { get; set; } - [Alias("_id_work_address")] + [Alias("id_work_address")] [ForeignKey(typeof(AliasedCustomerAddress))] public int? WorkAddressId { get; set; } @@ -62,10 +62,11 @@ public class AliasedCustomerAddress } - [TestFixture] - public class MultiFieldReferenceTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class MultiFieldReferenceTests : OrmLiteProvidersTestBase { + public MultiFieldReferenceTests(DialectContext context) : base(context) {} + [Test] public void Does_select_correct_reference_field() { diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultiThreadedUpdateTransactionIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultiThreadedUpdateTransactionIssue.cs new file mode 100644 index 000000000..44d1cd8c0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MultiThreadedUpdateTransactionIssue.cs @@ -0,0 +1,56 @@ +using System.Threading; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite, Explicit] + public class MultiThreadedUpdateTransactionIssue : OrmLiteProvidersTestBase + { + public MultiThreadedUpdateTransactionIssue(DialectContext context) : base(context) {} + + public class ModelWithIdAndName + { + [AutoIncrement] + public int Id { get; set; } + public string Name { get; set; } + } + + [Test] + public void Can_Insert_Update_record_across_multiple_threads() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + } + + int count = 0; + + 20.Times(i => + { + ThreadPool.QueueUserWorkItem(state => + { + 40.Times(_ => + { + using (var db = OpenDbConnection()) + { + var objA = new ModelWithIdAndName { Name = "A" }; + var objB = new ModelWithIdAndName { Name = "B" }; + + objA.Id = (int)db.Insert(objA, selectIdentity: true); + + objB.Id = (int)db.Insert(objB, selectIdentity: true); + objB.Name = objA.Name; + + db.Update(objB); + Interlocked.Increment(ref count); + } + }); + }); + }); + + Thread.Sleep(5000); + Assert.That(count, Is.EqualTo(20 * 40)); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithAliases.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithAliases.cs deleted file mode 100644 index cd04a3927..000000000 --- a/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithAliases.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.Tests.Issues -{ - public interface IHaveTenantId - { - Guid TenantId { get; } - } - - public class Contact : IHaveTenantId - { - public Guid Id { get; set; } - - public Guid TenantId { get; set; } - - public string FirstName { get; set; } - - public string LastName { get; set; } - } - - public class Sale : IHaveTenantId - { - public Guid Id { get; set; } - - public Guid TenantId { get; set; } - - [ForeignKey(typeof(Contact), OnDelete = "NO ACTION")] - public Guid BuyerId { get; set; } - - [ForeignKey(typeof(Contact), OnDelete = "NO ACTION")] - public Guid SellerId { get; set; } - - public int AmountCents { get; set; } - } - - public class SaleView - { - public Guid Id { get; set; } - public Guid TenantId { get; set; } - public string BuyerFirstName { get; set; } - public string BuyerLastName { get; set; } - public string SellerFirstName { get; set; } - public string SellerLastName { get; set; } - public int AmountCents { get; set; } - } - - public class MultipleSelfJoinsWithAliases : OrmLiteTestBase - { - [Test] - public void Can_use_cusom_SqlExpression_to_add_multiple_self_Left_Joins() - { - using (var db = OpenDbConnection()) - { - db.DropTable(); - db.DropTable(); - - db.CreateTable(); - db.CreateTable(); - - var tenantId = Guid.NewGuid(); - - var buyer = new Contact { - Id = Guid.NewGuid(), - TenantId = tenantId, - FirstName = "Buyer", - LastName = "LastBuyer" - }; - - var seller = new Contact { - Id = Guid.NewGuid(), - TenantId = tenantId, - FirstName = "Seller", - LastName = "LastSeller" - }; - - db.Insert(buyer, seller); - - var sale = new Sale { - Id = Guid.NewGuid(), - TenantId = tenantId, - BuyerId = buyer.Id, - SellerId = seller.Id, - AmountCents = 100, - }; - - db.Insert(sale); - - var q = db.From() - .CustomJoin("LEFT JOIN Contact seller on (Sale.{0} = seller.Id)".Fmt("SellerId".SqlColumn())) - .CustomJoin("LEFT JOIN Contact buyer on (Sale.{0} = buyer.Id)".Fmt("BuyerId".SqlColumn())) - .Select(@"Sale.* - , buyer.{0} AS BuyerFirstName - , buyer.{1} AS BuyerLastName - , seller.{0} AS SellerFirstName - , seller.{1} AS SellerLastName" - .Fmt("FirstName".SqlColumn(), "LastName".SqlColumn())); - - q.Where(x => x.TenantId == tenantId); - - var sales = db.Select(q); - - Assert.That(sales.Count, Is.EqualTo(1)); - var salesView = sales[0]; - - salesView.PrintDump(); - - Assert.That(salesView.Id, Is.EqualTo(sale.Id)); - Assert.That(salesView.TenantId, Is.EqualTo(sale.TenantId)); - Assert.That(salesView.BuyerFirstName, Is.EqualTo(buyer.FirstName)); - Assert.That(salesView.BuyerLastName, Is.EqualTo(buyer.LastName)); - Assert.That(salesView.SellerFirstName, Is.EqualTo(seller.FirstName)); - Assert.That(salesView.SellerLastName, Is.EqualTo(seller.LastName)); - Assert.That(salesView.AmountCents, Is.EqualTo(sale.AmountCents)); - } - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithJoinAliases.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithJoinAliases.cs new file mode 100644 index 000000000..ef0c6bf7d --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithJoinAliases.cs @@ -0,0 +1,264 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class MultipleSelfJoinsWithJoinAliases : OrmLiteProvidersTestBase + { + public MultipleSelfJoinsWithJoinAliases(DialectContext context) : base(context) {} + + private static Sale PopulateData(IDbConnection db, Guid tenantId) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + var buyer = new ContactIssue + { + Id = Guid.NewGuid(), + TenantId = tenantId, + FirstName = "BuyerFirst", + LastName = "LastBuyer" + }; + + var seller = new ContactIssue + { + Id = Guid.NewGuid(), + TenantId = tenantId, + FirstName = "SellerFirst", + LastName = "LastSeller" + }; + + db.Insert(buyer, seller); + + var sale = new Sale + { + Id = Guid.NewGuid(), + TenantId = tenantId, + BuyerId = buyer.Id, + SellerId = seller.Id, + AmountCents = 100, + }; + + db.Insert(sale); + return sale; + } + + [Test] + public void Can_use_custom_SqlExpression_to_add_multiple_self_Left_Joins() + { + using var db = OpenDbConnection(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .CustomJoin("LEFT JOIN {0} seller on (Sale.{1} = seller.Id)" + .Fmt("ContactIssue".SqlTable(DialectProvider), "SellerId".SqlColumn(DialectProvider))) + .CustomJoin("LEFT JOIN {0} buyer on (Sale.{1} = buyer.Id)" + .Fmt("ContactIssue".SqlTable(DialectProvider), "BuyerId".SqlColumn(DialectProvider))) + .Select(@"Sale.* + , buyer.{0} AS BuyerFirstName + , buyer.{1} AS BuyerLastName + , seller.{0} AS SellerFirstName + , seller.{1} AS SellerLastName" + .Fmt("FirstName".SqlColumn(DialectProvider), "LastName".SqlColumn(DialectProvider))); + + q.Where(x => x.TenantId == tenantId); + + var sales = db.Select(q); + Assert.That(sales.Count, Is.EqualTo(1)); + + OrmLiteUtils.PrintSql(); + //Alternative + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s, c) => new + { + s, + BuyerFirstName = Sql.TableAlias(c.FirstName, "buyer"), + BuyerLastName = Sql.TableAlias(c.LastName, "buyer"), + SellerFirstName = Sql.TableAlias(c.FirstName, "seller"), + SellerLastName = Sql.TableAlias(c.LastName, "seller"), + }); + + q.Where(x => x.TenantId == tenantId); + + sales = db.Select(q); + Assert.That(sales.Count, Is.EqualTo(1)); + + + var salesView = sales[0]; + + //salesView.PrintDump(); + + Assert.That(salesView.Id, Is.EqualTo(sale.Id)); + Assert.That(salesView.TenantId, Is.EqualTo(sale.TenantId)); + Assert.That(salesView.AmountCents, Is.EqualTo(sale.AmountCents)); + Assert.That(salesView.BuyerFirstName, Is.EqualTo("BuyerFirst")); + Assert.That(salesView.BuyerLastName, Is.EqualTo("LastBuyer")); + Assert.That(salesView.SellerFirstName, Is.EqualTo("SellerFirst")); + Assert.That(salesView.SellerLastName, Is.EqualTo("LastSeller")); + + q.Select("seller.*, 0 EOT, buyer.*"); + + var multi = db.Select>(q); + multi.PrintDump(); + + Assert.That(multi[0].Item1.FirstName, Is.EqualTo("SellerFirst")); + Assert.That(multi[0].Item2.FirstName, Is.EqualTo("BuyerFirst")); + } + + [Test] + public void Can_use_CustomSql() + { + var customFmt = ""; + if (Dialect == Dialect.SqlServer || Dialect == Dialect.SqlServer2012) + customFmt = "CONCAT(LEFT({0}, 1),LEFT({1},1))"; + else if (Dialect == Dialect.Sqlite) + customFmt = "substr({0}, 1, 1) || substr({1}, 1, 1)"; + + if (string.IsNullOrEmpty(customFmt)) + return; + + using var db = OpenDbConnection(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s, c) => new + { + s, + BuyerFirstName = Sql.TableAlias(c.FirstName, "buyer"), + BuyerLastName = Sql.TableAlias(c.LastName, "buyer"), + BuyerInitials = Sql.Custom(customFmt.Fmt("buyer.FirstName", "buyer.LastName")), + SellerFirstName = Sql.TableAlias(c.FirstName, "seller"), + SellerLastName = Sql.TableAlias(c.LastName, "seller"), + SellerInitials = Sql.Custom(customFmt.Fmt("seller.FirstName", "seller.LastName")), + }); + + var sales = db.Select(q); + var salesView = sales[0]; + + Assert.That(salesView.BuyerFirstName, Is.EqualTo("BuyerFirst")); + Assert.That(salesView.BuyerLastName, Is.EqualTo("LastBuyer")); + Assert.That(salesView.BuyerInitials, Is.EqualTo("BL")); + Assert.That(salesView.SellerFirstName, Is.EqualTo("SellerFirst")); + Assert.That(salesView.SellerLastName, Is.EqualTo("LastSeller")); + Assert.That(salesView.SellerInitials, Is.EqualTo("SL")); + } + + void AssertTupleResults(List> results) + { + var result = results[0]; + var sales = result.Item1; + var buyer = result.Item2; + var seller = result.Item3; + + Assert.That(sales.AmountCents, Is.EqualTo(100)); + Assert.That(buyer.FirstName, Is.EqualTo("BuyerFirst")); + Assert.That(buyer.LastName, Is.EqualTo("LastBuyer")); + Assert.That(seller.FirstName, Is.EqualTo("SellerFirst")); + Assert.That(seller.LastName, Is.EqualTo("LastSeller")); + } + + [Test] + public void Can_use_Custom_Select_with_Tuples() + { + using var db = OpenDbConnection(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s,c) => new { + s, + buyer = Sql.TableAlias(c, "buyer"), + seller = Sql.TableAlias(c, "seller"), + }); + + AssertTupleResults(db.Select>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s,c) => new { + s, + t1 = Sql.EOT, + buyer = Sql.TableAlias(c, "buyer"), + t2 = Sql.EOT, + seller = Sql.TableAlias(c, "seller"), + }); + + AssertTupleResults(db.Select>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select("Sale.*, 0 EOT, buyer.*, 0 EOT, seller.*, 0 EOT"); + + AssertTupleResults(db.Select>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")); + + AssertTupleResults(db.SelectMulti(q, new[] { "Sale.*", "buyer.*", "seller.*" })); + } + + [Test] + public async Task Can_use_Custom_Select_with_Tuples_Async() + { + using var db = await OpenDbConnectionAsync(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s,c) => new { + s, + buyer = Sql.TableAlias(c, "buyer"), + seller = Sql.TableAlias(c, "seller"), + }); + + AssertTupleResults(await db.SelectAsync>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s,c) => new { + s, + t1 = Sql.EOT, + buyer = Sql.TableAlias(c, "buyer"), + t2 = Sql.EOT, + seller = Sql.TableAlias(c, "seller"), + }); + + AssertTupleResults(await db.SelectAsync>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select("Sale.*, 0 EOT, buyer.*, 0 EOT, seller.*, 0 EOT"); + + AssertTupleResults(await db.SelectAsync>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")); + + AssertTupleResults(await db.SelectMultiAsync(q, new[] { "Sale.*", "buyer.*", "seller.*" })); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithNullableInts.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithNullableInts.cs new file mode 100644 index 000000000..b1d003c9b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithNullableInts.cs @@ -0,0 +1,86 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class ParentSelfRef + { + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(ChildSelfRef))] + public int? Child1Id { get; set; } + + [Reference] + public ChildSelfRef Child1 { get; set; } + + [References(typeof(ChildSelfRef))] + public int? Child2Id { get; set; } + + [Reference] + public ChildSelfRef Child2 { get; set; } + + public ulong RowVersion { get; set; } + } + + public class ChildSelfRef + { + [AutoIncrement] + public int Id { get; set; } + public string Name { get; set; } + } + + [TestFixtureOrmLite] + public class MultipleSelfJoinsWithNullableInts : OrmLiteProvidersTestBase + { + public MultipleSelfJoinsWithNullableInts(DialectContext context) : base(context) {} + + [Test] + public void Does_support_multiple_self_joins_with_nullable_ints() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + var row = new ParentSelfRef + { + Child1 = new ChildSelfRef + { + Name = "Child 1" + }, + Child2 = new ChildSelfRef + { + Name = "Child 2" + }, + }; + + db.Save(row, references: true); + + row.PrintDump(); + + Assert.That(row.Id, Is.EqualTo(1)); + Assert.That(row.Child1Id, Is.EqualTo(1)); + Assert.That(row.Child1.Id, Is.EqualTo(1)); + Assert.That(row.Child1.Name, Is.EqualTo("Child 1")); + Assert.That(row.Child2Id, Is.EqualTo(2)); + Assert.That(row.Child2.Id, Is.EqualTo(2)); + Assert.That(row.Child2.Name, Is.EqualTo("Child 2")); + + row = db.LoadSingleById(row.Id); + + Assert.That(row.Id, Is.EqualTo(1)); + Assert.That(row.Child1Id, Is.EqualTo(1)); + Assert.That(row.Child1.Id, Is.EqualTo(1)); + Assert.That(row.Child1.Name, Is.EqualTo("Child 1")); + Assert.That(row.Child2Id, Is.EqualTo(2)); + Assert.That(row.Child2.Id, Is.EqualTo(2)); + Assert.That(row.Child2.Name, Is.EqualTo("Child 2")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithTableAliases.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithTableAliases.cs new file mode 100644 index 000000000..188dfc2bd --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithTableAliases.cs @@ -0,0 +1,384 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public interface IHaveTenantId + { + Guid TenantId { get; } + } + + public class ContactIssue : IHaveTenantId + { + public Guid Id { get; set; } + + public Guid TenantId { get; set; } + + public string FirstName { get; set; } + + public string LastName { get; set; } + } + + public class Sale : IHaveTenantId + { + public Guid Id { get; set; } + + public Guid TenantId { get; set; } + + [ForeignKey(typeof(ContactIssue), OnDelete = "NO ACTION")] + public Guid BuyerId { get; set; } + + [ForeignKey(typeof(ContactIssue), OnDelete = "NO ACTION")] + public Guid SellerId { get; set; } + + public int AmountCents { get; set; } + } + + public class SaleView + { + public Guid Id { get; set; } + public Guid TenantId { get; set; } + public string BuyerFirstName { get; set; } + public string BuyerLastName { get; set; } + public string BuyerInitials { get; set; } + public string SellerFirstName { get; set; } + public string SellerLastName { get; set; } + public string SellerInitials { get; set; } + public int AmountCents { get; set; } + } + + public class SaleJson : Sale + { + public string Json { get; set; } + + private List results; + public List Results => results ??= CustomJsonSerializer.FromJson>(Json); + } + + public static class CustomJsonSerializer + { + public static T FromJson(string json) + { + using var scope = JsConfig.With(new Config { PropertyConvention = PropertyConvention.Lenient }); + return json.FromJson(); + } + } + + [TestFixtureOrmLite] + public class MultipleSelfJoinsWithTableAliases : OrmLiteProvidersTestBase + { + public MultipleSelfJoinsWithTableAliases(DialectContext context) : base(context) {} + + private static Sale PopulateData(IDbConnection db, Guid tenantId) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + var buyer = new ContactIssue + { + Id = Guid.NewGuid(), + TenantId = tenantId, + FirstName = "BuyerFirst", + LastName = "LastBuyer" + }; + + var seller = new ContactIssue + { + Id = Guid.NewGuid(), + TenantId = tenantId, + FirstName = "SellerFirst", + LastName = "LastSeller" + }; + + db.Insert(buyer, seller); + + var sale = new Sale + { + Id = Guid.NewGuid(), + TenantId = tenantId, + BuyerId = buyer.Id, + SellerId = seller.Id, + AmountCents = 100, + }; + + db.Insert(sale); + return sale; + } + + [Test] + public void Can_use_custom_SqlExpression_to_add_multiple_self_Left_Joins_with_TableAlias() + { + using var db = OpenDbConnection(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .CustomJoin("LEFT JOIN {0} seller on (Sale.{1} = seller.Id)" + .Fmt("ContactIssue".SqlTable(DialectProvider), "SellerId".SqlColumn(DialectProvider))) + .CustomJoin("LEFT JOIN {0} buyer on (Sale.{1} = buyer.Id)" + .Fmt("ContactIssue".SqlTable(DialectProvider), "BuyerId".SqlColumn(DialectProvider))) + .Select(@"Sale.* + , buyer.{0} AS BuyerFirstName + , buyer.{1} AS BuyerLastName + , seller.{0} AS SellerFirstName + , seller.{1} AS SellerLastName" + .Fmt("FirstName".SqlColumn(DialectProvider), "LastName".SqlColumn(DialectProvider))); + + q.Where(x => x.TenantId == tenantId); + + var sales = db.Select(q); + Assert.That(sales.Count, Is.EqualTo(1)); + + //Alternative + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s, c) => new + { + s, + BuyerFirstName = Sql.TableAlias(c.FirstName, "buyer"), + BuyerLastName = Sql.TableAlias(c.LastName, "buyer"), + SellerFirstName = Sql.TableAlias(c.FirstName, "seller"), + SellerLastName = Sql.TableAlias(c.LastName, "seller"), + }); + + q.Where(x => x.TenantId == tenantId); + + sales = db.Select(q); + Assert.That(sales.Count, Is.EqualTo(1)); + + + var salesView = sales[0]; + + //salesView.PrintDump(); + + Assert.That(salesView.Id, Is.EqualTo(sale.Id)); + Assert.That(salesView.TenantId, Is.EqualTo(sale.TenantId)); + Assert.That(salesView.AmountCents, Is.EqualTo(sale.AmountCents)); + Assert.That(salesView.BuyerFirstName, Is.EqualTo("BuyerFirst")); + Assert.That(salesView.BuyerLastName, Is.EqualTo("LastBuyer")); + Assert.That(salesView.SellerFirstName, Is.EqualTo("SellerFirst")); + Assert.That(salesView.SellerLastName, Is.EqualTo("LastSeller")); + + q.Select("seller.*, 0 EOT, buyer.*"); + + var multi = db.Select>(q); + multi.PrintDump(); + + Assert.That(multi[0].Item1.FirstName, Is.EqualTo("SellerFirst")); + Assert.That(multi[0].Item2.FirstName, Is.EqualTo("BuyerFirst")); + } + + [Test] + public void Can_use_CustomSql_with_TableAlias() + { + var customFmt = ""; + if (Dialect == Dialect.SqlServer || Dialect == Dialect.SqlServer2012) + customFmt = "CONCAT(LEFT({0}, 1),LEFT({1},1))"; + else if (Dialect == Dialect.Sqlite) + customFmt = "substr({0}, 1, 1) || substr({1}, 1, 1)"; + + if (string.IsNullOrEmpty(customFmt)) + return; + + using var db = OpenDbConnection(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select((s, c) => new + { + s, + BuyerFirstName = Sql.TableAlias(c.FirstName, "buyer"), + BuyerLastName = Sql.TableAlias(c.LastName, "buyer"), + BuyerInitials = Sql.Custom(customFmt.Fmt("buyer.FirstName", "buyer.LastName")), + SellerFirstName = Sql.TableAlias(c.FirstName, "seller"), + SellerLastName = Sql.TableAlias(c.LastName, "seller"), + SellerInitials = Sql.Custom(customFmt.Fmt("seller.FirstName", "seller.LastName")), + }); + + var sales = db.Select(q); + var salesView = sales[0]; + + Assert.That(salesView.BuyerFirstName, Is.EqualTo("BuyerFirst")); + Assert.That(salesView.BuyerLastName, Is.EqualTo("LastBuyer")); + Assert.That(salesView.BuyerInitials, Is.EqualTo("BL")); + Assert.That(salesView.SellerFirstName, Is.EqualTo("SellerFirst")); + Assert.That(salesView.SellerLastName, Is.EqualTo("LastSeller")); + Assert.That(salesView.SellerInitials, Is.EqualTo("SL")); + } + + [Test] + public void Can_use_CustomSql_with_TableAlias_and_GroupBy() + { + var customFmt = ""; + if ((Dialect & Dialect.AnySqlServer) == Dialect) + customFmt = "CONCAT(LEFT({0}, 1),LEFT({1},1))"; + else if (Dialect == Dialect.Sqlite) + customFmt = "substr({0}, 1, 1) || substr({1}, 1, 1)"; + + if (string.IsNullOrEmpty(customFmt)) + return; + // OrmLiteUtils.PrintSql(); + + using (var db = OpenDbConnection()) + { + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + // .GroupBy((s,c) => new object[] { s.Id, "BuyerFirstName", "BuyerLastName" }) + // .GroupBy((s,c) => new { s.Id, BuyerFirstName = "BuyerFirstName", BuyerLastName = "BuyerLastName" }) + .GroupBy((s,c) => new { + s.Id, + BuyerFirstName = Sql.TableAlias(c.FirstName, "buyer"), + BuyerLastName = Sql.TableAlias(c.LastName, "buyer"), + SellerFirstName = Sql.TableAlias(c.FirstName, "seller"), + SellerLastName = Sql.TableAlias(c.LastName, "seller"), + }) + .Select((s, c) => new + { + s.Id, + BuyerFirstName = Sql.TableAlias(c.FirstName, "buyer"), + BuyerLastName = Sql.TableAlias(c.LastName, "buyer"), + BuyerInitials = Sql.Custom(customFmt.Fmt("buyer.FirstName", "buyer.LastName")), + SellerFirstName = Sql.TableAlias(c.FirstName, "seller"), + SellerLastName = Sql.TableAlias(c.LastName, "seller"), + SellerInitials = Sql.Custom(customFmt.Fmt("seller.FirstName", "seller.LastName")), + }); + + var sales = db.Select(q); + var salesView = sales[0]; + + Assert.That(salesView.BuyerFirstName, Is.EqualTo("BuyerFirst")); + Assert.That(salesView.BuyerLastName, Is.EqualTo("LastBuyer")); + Assert.That(salesView.BuyerInitials, Is.EqualTo("BL")); + Assert.That(salesView.SellerFirstName, Is.EqualTo("SellerFirst")); + Assert.That(salesView.SellerLastName, Is.EqualTo("LastSeller")); + Assert.That(salesView.SellerInitials, Is.EqualTo("SL")); + } + } + + void AssertTupleResults(List> results) + { + var result = results[0]; + var sales = result.Item1; + var buyer = result.Item2; + var seller = result.Item3; + + Assert.That(sales.AmountCents, Is.EqualTo(100)); + Assert.That(buyer.FirstName, Is.EqualTo("BuyerFirst")); + Assert.That(buyer.LastName, Is.EqualTo("LastBuyer")); + Assert.That(seller.FirstName, Is.EqualTo("SellerFirst")); + Assert.That(seller.LastName, Is.EqualTo("LastSeller")); + } + + [Test] + public void Can_use_Custom_Select_with_Tuples_with_TableAlias() + { + using var db = OpenDbConnection(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select("Sale.*, 0 EOT, buyer.*, 0 EOT, seller.*, 0 EOT"); + + AssertTupleResults(db.Select>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")); + + AssertTupleResults(db.SelectMulti(q, new[] { "Sale.*", "buyer.*", "seller.*" })); + } + + [Test] + public async Task Can_use_Custom_Select_with_Tuples_with_TableAlias_Async() + { + using var db = await OpenDbConnectionAsync(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .Select("Sale.*, 0 EOT, buyer.*, 0 EOT, seller.*, 0 EOT"); + + AssertTupleResults(await db.SelectAsync>(q)); + + q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")); + + AssertTupleResults(await db.SelectMultiAsync(q, new[] { "Sale.*", "buyer.*", "seller.*" })); + } + + [Test] + public async Task Can_select_custom_result_with_json_type() + { + if ((Dialect & Dialect.AnyPostgreSql) != Dialect) + return; + + using var db = await OpenDbConnectionAsync(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From(db.TableAlias("s")) + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .GroupBy(x => x.Id) + .Select("s.*, json_agg(seller) as Json"); + + var values = db.Select(q); + // values.PrintDump(); + var result = values[0].Results[0]; + Assert.That(result.Id, Is.Not.EqualTo(default(Guid))); + Assert.That(result.TenantId, Is.EqualTo(tenantId)); + Assert.That(result.FirstName, Is.Not.Null); + Assert.That(result.LastName, Is.Not.Null); + } + + public class ContactIssueJson + { + public string Json { get; set; } + } + + [Test] + public async Task Can_select_custom_json_result_in_Table_type() + { + if ((Dialect & Dialect.AnyPostgreSql) != Dialect) + return; + + using var db = await OpenDbConnectionAsync(); + var tenantId = Guid.NewGuid(); + var sale = PopulateData(db, tenantId); + + var q = db.From() + .LeftJoin((s, c) => s.SellerId == c.Id, db.TableAlias("seller")) + .LeftJoin((s, c) => s.BuyerId == c.Id, db.TableAlias("buyer")) + .GroupBy((s,c) => new { SaleId = s.Id, BuyerId = Sql.TableAlias(c.Id, "buyer") }) + .Select((s,c) => new { + s, + buyer = Sql.TableAlias(c, "buyer"), + Json = Sql.Custom($"json_agg(seller)"), + }); + + var results = db.Select>(q); + Assert.That(results[0].Item3.Json, Does.StartWith("[")); + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/MultithreadingIssueTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/MultithreadingIssueTests.cs index ef284d515..538d12f41 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/MultithreadingIssueTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/MultithreadingIssueTests.cs @@ -7,10 +7,12 @@ namespace ServiceStack.OrmLite.Tests.Issues { [Explicit] - [TestFixture] - public class MultithreadingIssueTests - : OrmLiteTestBase + [IgnoreDialect(Dialect.Sqlite, "doesn't support concurrent writes")] + [TestFixtureOrmLite] + public class MultithreadingIssueTests : OrmLiteProvidersTestBase { + public MultithreadingIssueTests(DialectContext context) : base(context) {} + [SetUp] public void SetUp() { @@ -34,7 +36,7 @@ public void Can_SaveAll_in_multiple_threads() var threadId = Thread.CurrentThread.ManagedThreadId; "Thread {0} started...".Print(threadId); - var rows = 10.Times(i => ModelWithDifferentNumTypes.Create(i)); + var rows = 10.Times(ModelWithDifferentNumTypes.Create); using (var db = OpenDbConnection()) { 100.Times(i => diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/NoSqlLoggingIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/NoSqlLoggingIssue.cs new file mode 100644 index 000000000..22c813944 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/NoSqlLoggingIssue.cs @@ -0,0 +1,52 @@ +using NUnit.Framework; +using ServiceStack.Logging; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class NoSqlLoggingIssue : OrmLiteProvidersTestBase + { + public NoSqlLoggingIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_log_SQL_Insert_for_Saves() + { + var sbLogFactory = new StringBuilderLogFactory(); + var hold = LogManager.LogFactory; + OrmLiteConfig.ResetLogFactory(sbLogFactory); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Save(new Person { Id = 1, FirstName = "first", LastName = "last", Age = 27 }); + } + + var sql = sbLogFactory.GetLogs(); + + Assert.That(sql, Does.Contain("INSERT INTO")); + OrmLiteConfig.ResetLogFactory(hold); + } + + [Test] + public void Does_log_SQL_Insert_for_Saves_with_Auto_Ids() + { + var sbLogFactory = new StringBuilderLogFactory(); + var hold = LogManager.LogFactory; + OrmLiteConfig.ResetLogFactory(sbLogFactory); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Save(new PersonWithAutoId { Id = 1, FirstName = "first", LastName = "last", Age = 27 }); + } + + var sql = sbLogFactory.GetLogs(); + + Assert.That(sql, Does.Contain("INSERT INTO")); + OrmLiteConfig.ResetLogFactory(hold); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/NoUpdateIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/NoUpdateIssue.cs new file mode 100644 index 000000000..87d9ea5c9 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/NoUpdateIssue.cs @@ -0,0 +1,51 @@ +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class LRDCategoria : IHasId + { + [Alias("IDDCATEGORIA")] + [AutoIncrement] + [PrimaryKey] + public int Id { get; set; } + + [Alias("CODICE")] + [Required] + [Index(Unique = true)] + [StringLength(50)] + public string Codice { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class NoUpdateIssue : OrmLiteProvidersTestBase + { + public NoUpdateIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_update_record() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new LRDCategoria { Codice = "A" }); + + var row = db.Select().FirstOrDefault(); + + row.Codice = ""; + + db.Update(row); + + row = db.Select().FirstOrDefault(); + + row.PrintDump(); + + Assert.That(row.Codice, Is.EqualTo("")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/NullReferenceIssues.cs b/tests/ServiceStack.OrmLite.Tests/Issues/NullReferenceIssues.cs new file mode 100644 index 000000000..fc97ddb9a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/NullReferenceIssues.cs @@ -0,0 +1,54 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class NullReferenceIssues : OrmLiteProvidersTestBase + { + public NullReferenceIssues(DialectContext context) : base(context) {} + + public class Foo + { + public int Id { get; set; } + + public string Name { get; set; } + + public string Key { get; set; } + + public int Int { get; set; } + } + + [Test] + [IgnoreDialect(Dialect.Sqlite, "Not supported")] + public void Can_AlterColumn() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.AlterColumn(typeof(Foo), new FieldDefinition + { + Name = nameof(Foo.Name), + FieldType = typeof(string), + IsNullable = true, + DefaultValue = null + }); + + db.AlterColumn(typeof(Foo), new FieldDefinition + { + Name = nameof(Foo.Int), + FieldType = typeof(int), + IsNullable = true, + DefaultValue = null + }); + + db.AddColumn(typeof(Foo), new FieldDefinition + { + Name = "Bool", + FieldType = typeof(bool), + }); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/ParamNameIssues.cs b/tests/ServiceStack.OrmLite.Tests/Issues/ParamNameIssues.cs new file mode 100644 index 000000000..60afde68e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/ParamNameIssues.cs @@ -0,0 +1,45 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class LegacyRow + { + [AutoIncrement] + public int ID { get; set; } + + public string Name { get; set; } + + [Alias("Age-In-Years")] + public int Age { get; set; } + } + + + [TestFixtureOrmLite] + public class ParamNameIssues : OrmLiteProvidersTestBase + { + public ParamNameIssues(DialectContext context) : base(context) {} + + [Test] + public void Does_use_ParamName_filter() + { + OrmLiteConfig.ParamNameFilter = name => name.Replace("-", ""); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertAll(new [] + { + new LegacyRow { Name = "Row1", Age = 1 }, + new LegacyRow { Name = "Row2", Age = 2 }, + }); + + var rows = db.Select(); + Assert.That(rows.Count, Is.EqualTo(2)); + } + + OrmLiteConfig.ParamNameFilter = null; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/RowVersionJoinIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/RowVersionJoinIssue.cs new file mode 100644 index 000000000..613489c27 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/RowVersionJoinIssue.cs @@ -0,0 +1,94 @@ +using System.Runtime.Serialization; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [Alias("makemodel")] + public class MakeModel + { + [Alias("id"), PrimaryKey] + public int Id { get; set; } + + [Alias("manufacturer")] + public string Manufacturer { get; set; } + + [Alias("model")] + public string Model { get; set; } + + [References(typeof(PerformanceCategory))] + [Alias("performance_category_id")] + public int PerformanceCategoryId { get; set; } + + public ulong RowVersion { get; set; } + } + + [Alias("performance_category")] + public class PerformanceCategory + { + [Alias("id"), PrimaryKey] + public int Id { get; set; } + + [Alias("category")] + public string Category { get; set; } + + [Alias("description")] + public string Description { get; set; } + } + + [DataContract] + public class VehicleDto : DataTransferObject + { + [DataMember(Name = "id")] + public string Id { get; set; } + + [DataMember(Name = "manufacturer")] + public string Manufacturer { get; set; } + + [DataMember(Name = "model")] + public string Model { get; set; } + + [DataMember(Name = "performance_category_id")] + public string PerformanceCategoryId { get; set; } + + [DataMember(Name = "category")] + public string Category { get; set; } + + [DataMember(Name = "row-version")] + public ulong RowVersion { get; set; } + } + + public class DataTransferObject { } + + [TestFixtureOrmLite] + public class RowVersionJoinIssue : OrmLiteProvidersTestBase + { + public RowVersionJoinIssue(DialectContext context) : base(context) {} + + [Test] + public void Can_join_on_table_with_RowVersion() + { + using (var db = OpenDbConnection()) + { + var id = 1; + + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.Insert(new PerformanceCategory { Id = 1, Category = "category" }); + db.Insert(new MakeModel { Id = 1, Manufacturer = "manufacturer", Model = "model", PerformanceCategoryId = 1 }); + + var row = db.Single(db.From().Where(v => v.Id == id)); + + db.GetLastSql().Print(); + + Assert.That(row.Id, Is.EqualTo("1")); + Assert.That(row.Category, Is.EqualTo("category")); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SaveAllIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SaveAllIssue.cs new file mode 100644 index 000000000..2c0e538ef --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SaveAllIssue.cs @@ -0,0 +1,32 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class SaveAllIssue : OrmLiteProvidersTestBase + { + public SaveAllIssue(DialectContext context) : base(context) {} + + class UserRole + { + public string Name { get; set; } + } + + [Test] + public void Can_use_SaveAll_to_save_one_column_table() + { + using var db = OpenDbConnection(); + db.CreateTableIfNotExists(); + + db.SaveAll(new[] + { + new UserRole { Name = "Admin" }, + new UserRole { Name = "Reader" }, + new UserRole { Name = "Writer" }, + }); + + var rows = db.Select(); + Assert.That(rows.Map(x => x.Name), Is.EquivalentTo(new[]{ "Admin", "Reader", "Writer"})); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SaveAllReferencesIssues.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SaveAllReferencesIssues.cs new file mode 100644 index 000000000..3cae7bbd2 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SaveAllReferencesIssues.cs @@ -0,0 +1,158 @@ +using System; +using System.Data; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class SaveAllReferencesIssues : OrmLiteProvidersTestBase + { + public SaveAllReferencesIssues(DialectContext context) : base(context) {} + + public class BranchRef + { + [AutoId] + public Guid Id { get; set; } + + [Reference] + public AddressRef Address { get; set; } + } + + public class AddressRef + { + [AutoId] + public Guid Id { get; set; } + + [ForeignKey(typeof(BranchRef), OnDelete = "CASCADE")] + [Required] + public Guid BranchRefId { get; set; } + + [Required] + public string StreetAddress { get; set; } + + [Required] + public string City { get; set; } + + [Required] + public string State { get; set; } + + [Required] + public string ZipCode { get; set; } + } + + private static void CreateRefTables(IDbConnection db) + { + if (db.TableExists()) + db.DeleteAll(); + + if (db.TableExists()) + db.DeleteAll(); + + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + } + + [Test] + public void Can_use_Save_References_with_ForeignKey() + { + using (var db = OpenDbConnection()) + { + CreateRefTables(db); + + //Generate dummy data + var branch = new BranchRef + { + Address = new AddressRef + { + StreetAddress = "2100 Gotham Lane", + City = "Gotham", + State = "NJ", + ZipCode = "12345" + } + }; + + db.Save(branch, references: true); + + Assert.That(branch.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(branch.Address.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(branch.Id, Is.EqualTo(branch.Address.BranchRefId)); + } + } + + public class BranchSelfRef + { + [AutoId] + public Guid Id { get; set; } + + [Reference] + public AddressSelfRef Address { get; set; } + + [ForeignKey(typeof(AddressSelfRef), OnDelete = "CASCADE")] + public Guid? AddressSelfRefId { get; set; } + } + + public class AddressSelfRef + { + [AutoId] + public Guid Id { get; set; } + + [Required] + public string StreetAddress { get; set; } + + [Required] + public string City { get; set; } + + [Required] + public string State { get; set; } + + [Required] + public string ZipCode { get; set; } + } + + private static void CreateSelfRefTables(IDbConnection db) + { + if (db.TableExists()) + db.DeleteAll(); + + if (db.TableExists()) + db.DeleteAll(); + + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + } + + [Test] + public void Can_use_Save_References_with_ForeignKey_using_Self_Reference_Id() + { + using (var db = OpenDbConnection()) + { + CreateSelfRefTables(db); + + var branch = new BranchSelfRef + { + Address = new AddressSelfRef + { + StreetAddress = "2100 Gotham Lane", + City = "Gotham", + State = "NJ", + ZipCode = "12345" + } + }; + + db.Save(branch, references: true); + + Assert.That(branch.Id, Is.Not.EqualTo(Guid.Empty)); + Assert.That(branch.AddressSelfRefId, Is.Not.EqualTo(Guid.Empty)); + Assert.That(branch.AddressSelfRefId, Is.EqualTo(branch.Address.Id)); + } + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SaveDomainUserReferencesIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SaveDomainUserReferencesIssue.cs index 7b11a2874..7959d873c 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/SaveDomainUserReferencesIssue.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SaveDomainUserReferencesIssue.cs @@ -16,7 +16,7 @@ public class DomainUser public Address HomeAddress { get; set; } [Reference] - public List Orders { get; set; } + public List Orders { get; set; } [DataAnnotations.Ignore] public UserType UserTypeEnum @@ -40,7 +40,7 @@ public enum UserType Domain = 2 } - public class Order + public class ProOrder { [AutoIncrement] public int Id { get; set; } @@ -51,18 +51,23 @@ public class Order } - [TestFixture] - public class SaveDomainUserReferencesIssue - : OrmLiteTestBase + [TestFixtureOrmLite] + public class SaveDomainUserReferencesIssue : OrmLiteProvidersTestBase { + public SaveDomainUserReferencesIssue(DialectContext context) : base(context) {} + [Test] public void Can_save_DomainUser_references() { using (var db = OpenDbConnection()) { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - db.DropAndCreateTable
(); + db.DropTable(); + db.DropTable
(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable
(); var user = new DomainUser { @@ -72,10 +77,10 @@ public void Can_save_DomainUser_references() { StreetName = "1 Street" }, - Orders = new List + Orders = new List { - new Order { Details = "Order1 Details" }, - new Order { Details = "Order2 Details" }, + new ProOrder { Details = "Order1 Details" }, + new ProOrder { Details = "Order2 Details" }, } }; @@ -97,7 +102,7 @@ public void Can_save_DomainUser_references() user.UserTypeEnum = UserType.Domain; user.HomeAddress.StreetName = "Some new street"; user.Orders[1].Details = "Nestle Chocolates"; - user.Orders.Add(new Order + user.Orders.Add(new ProOrder { ProUserId = user.Id, Details = "Reese", diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SchemaTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SchemaTests.cs index 41ff142a9..4fe7ddf79 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/SchemaTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SchemaTests.cs @@ -6,12 +6,22 @@ namespace ServiceStack.OrmLite.Tests.Issues { - [TestFixture] - public class SchemaTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class SchemaTests : OrmLiteProvidersTestBase { - public SchemaTests() + public SchemaTests(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void OneTimeSetup() { - Dialect = Dialect.Sqlite; //Other DB Providers needs creating out-of-band + if (DialectFeatures.SchemaSupport) + { + using (var db = OpenDbConnection()) + { + db.CreateSchema(); + db.CreateSchema(); + } + } } [Schema("Schema")] @@ -54,15 +64,15 @@ public void Can_join_on_table_with_schemas() Child = new SchemaTable2 { Name = "Bar" } }, references: true); - var rows = db.Select(q => q.Join()); + var rows = db.Select(db.From().Join()); Assert.That(rows.Count, Is.EqualTo(2)); - rows = db.Select(q => q.Join() + rows = db.Select(db.From().Join() .Where(x => x.Name == "Foo")); Assert.That(rows.Count, Is.EqualTo(1)); - rows = db.Select(q => q.LeftJoin()); + rows = db.Select(db.From().LeftJoin()); Assert.That(rows.Count, Is.EqualTo(2)); - rows = db.Select(q => q.LeftJoin() + rows = db.Select(db.From().LeftJoin() .Where(x => x.Name == "Foo")); Assert.That(rows.Count, Is.EqualTo(1)); } @@ -138,7 +148,7 @@ public void Does_complex_query_using_Schemas_with_LeftJoins() } [Alias("Editables")] - [Schema("MicroSite")] + [Schema("Schema")] public partial class Editable : IHasId { public string Content { get; set; } @@ -163,7 +173,7 @@ public partial class Editable : IHasId } [Alias("EditableRevisions")] - [Schema("MicroSite")] + [Schema("Schema")] public partial class EditableRevision : IHasId { public string Content { get; set; } @@ -188,7 +198,7 @@ public partial class EditableRevision : IHasId } [Alias("LogEntries")] - [Schema("MicroSite")] + [Schema("Schema")] public class LogEntry : IHasId { [Required] @@ -221,7 +231,7 @@ public class LogEntry : IHasId } [Alias("ReportPages")] - [Schema("MicroSite")] + [Schema("Schema")] public partial class Page : IHasId { [Required] @@ -257,7 +267,7 @@ public partial class Page : IHasId } [Alias("Reports")] - [Schema("MicroSite")] + [Schema("Schema")] public partial class Report : IHasId { [Required] @@ -277,7 +287,7 @@ public partial class Report : IHasId } [Alias("ReportSections")] - [Schema("MicroSite")] + [Schema("Schema")] public class Section : IHasId { [Alias("ReportSectionID")] diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SelectAliasIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SelectAliasIssue.cs new file mode 100644 index 000000000..da474c389 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SelectAliasIssue.cs @@ -0,0 +1,90 @@ +using System; +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class AddressAudit + { + [PrimaryKey, AutoIncrement] + [Alias("AddressId")] + public int Id { get; set; } + + [Alias("AddressLinkId")] + public int AddressId { get; set; } + } + + public interface ILookup + { + Guid Id { get; set; } + string Name { get; } + } + + public class TestLookup : ILookup + { + public Guid Id { get; set; } + public string Name { get; set; } + } + + public static class TestLookupExtensions + { + public static T Lookup(this IDbConnection db, T record) where T : ILookup, new() + { + var lkp = db.Single(r => r.Name == record.Name); + if (lkp != null) + return lkp; + + if (record.Id == Guid.Empty) + record.Id = Guid.NewGuid(); + db.Insert(record); + return record; + } + } + + [TestFixtureOrmLite] + public class SelectAliasIssue : OrmLiteProvidersTestBase + { + public SelectAliasIssue(DialectContext context) : base(context) {} + + [Test] + public void Does_populate_table_with_Aliases_having_same_name_as_alternative_field() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new AddressAudit { AddressId = 11 }); + db.Insert(new AddressAudit { AddressId = 12 }); + db.Insert(new AddressAudit { AddressId = 13 }); + + var rows = db.Select(); + Assert.That(rows.All(x => x.Id > 0)); + + var debtor = db.SingleById(2); + var row = db.Single(audit => audit.AddressId == debtor.AddressId); + + row.PrintDump(); + } + } + + [Test] + public void Select_against_interface_in_generic_method() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(); + + var newRecord = new TestLookup {Name = "new"}; + + var lkp = db.Single(r => r.Name == newRecord.Name); + + + var lookup = db.Lookup(newRecord); + Assert.That(lookup.Id != Guid.Empty); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SelectDistinctTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SelectDistinctTests.cs index c86e98882..1674f8c8a 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/SelectDistinctTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SelectDistinctTests.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using ServiceStack.DataAnnotations; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests.Issues @@ -17,10 +18,24 @@ public class DistinctJoinColumn public string Name { get; set; } } - [TestFixture] - public class SelectDistinctTests - : OrmLiteTestBase + [Alias("t1")] + class TableWithAliases { + public int Id { get; set; } + + [Alias("n1")] + public string Name { get; set; } + [Alias("n2")] + public string Name1 { get; set; } + [Alias("n3")] + public string Name2 { get; set; } + } + + [TestFixtureOrmLite] + public class SelectDistinctTests : OrmLiteProvidersTestBase + { + public SelectDistinctTests(DialectContext context) : base(context) {} + [Test] public void Can_Select_Multiple_Distinct_Columns() { @@ -43,12 +58,38 @@ public void Can_Select_Multiple_Distinct_Columns() var q = db.From() .Join() .SelectDistinct(dt => new { dt.Bar, dt.Foo }); - + var result = db.Select(q); db.GetLastSql().Print(); Assert.That(result.Count, Is.EqualTo(2)); } } + + [Test] + public void Does_select_alias_in_custom_select() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + for (var i = 1; i <= 5; i++) + { + db.Insert(new TableWithAliases { Id = i, Name = "foo" + i, Name1 = "bar" + i, Name2 = "qux" + i }); + } + + var uniqueTrackNames = db.ColumnDistinct( + db.From().Select(x => x.Name)); + + Assert.That(uniqueTrackNames, Is.EquivalentTo(new [] + { + "foo1", + "foo2", + "foo3", + "foo4", + "foo5", + })); + } + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SelectIntoTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SelectIntoTests.cs index 95839ad1d..3136c3dfa 100644 --- a/tests/ServiceStack.OrmLite.Tests/Issues/SelectIntoTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SelectIntoTests.cs @@ -20,30 +20,36 @@ public class DTOPoco public string Other_Id { get; set; } } - [TestFixture] - public class SelectIntoTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class SelectIntoTests : OrmLiteProvidersTestBase { + public SelectIntoTests(DialectContext context) : base(context) {} + [Test] public void Dont_guess_column_in_mismatched_Into_model() { OrmLiteConfig.DisableColumnGuessFallback = true; - using (var db = OpenDbConnection()) + try { - db.DropAndCreateTable(); + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); - db.Insert(new DbPoco { Id = "1", Other_Id = "OTHER" }); + db.Insert(new DbPoco { Id = "1", Other_Id = "OTHER" }); - var row = db.Select(db.From()).First(); + var row = db.Select(db.From()).First(); - row.PrintDump(); + row.PrintDump(); - Assert.That(row._Id, Is.Null); - Assert.That(row.Other_Id, Is.EqualTo("OTHER")); + Assert.That(row._Id, Is.Null); + Assert.That(row.Other_Id, Is.EqualTo("OTHER")); + } + } + finally + { + OrmLiteConfig.DisableColumnGuessFallback = false; } - - OrmLiteConfig.DisableColumnGuessFallback = false; } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SelectScalarTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SelectScalarTests.cs new file mode 100644 index 000000000..6d419389e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SelectScalarTests.cs @@ -0,0 +1,47 @@ +using System; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class SelectScalarTests : OrmLiteProvidersTestBase + { + public SelectScalarTests(DialectContext context) : base(context) {} + + public class TestPerson + { + public Guid Id { get; set; } + public long Long { get; set; } + public float Float { get; set; } + public double Double { get; set; } + public decimal Decimal { get; set; } + } + + [Test] + public void Should_Return_Scalar_Value() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var row = new TestPerson + { + Id = Guid.NewGuid(), + Long = 1, + Decimal = 1.1M, + Double = 1.1, + Float = 1.1f, + }; + db.Insert(row); + + var q = db.From().Where(x => x.Id == row.Id); + + Assert.That(db.Scalar(q.Select(x => x.Id)), Is.EqualTo(row.Id)); + Assert.That(db.Scalar(q.Select(x => x.Long)), Is.EqualTo(row.Long)); + Assert.That(db.Scalar(q.Select(x => x.Decimal)), Is.EqualTo(row.Decimal)); + Assert.That(db.Scalar(q.Select(x => x.Double)), Is.EqualTo(row.Double).Within(.1d)); + Assert.That(db.Scalar(q.Select(x => x.Float)), Is.EqualTo(row.Float)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SelectWithBytesIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SelectWithBytesIssue.cs new file mode 100644 index 000000000..6b7554881 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SelectWithBytesIssue.cs @@ -0,0 +1,39 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class SelectWithBytesIssue : OrmLiteProvidersTestBase + { + public SelectWithBytesIssue(DialectContext context) : base(context) {} + + public class ModelWithBytes + { + public int Id { get; set; } + public byte[] Bytes { get; set; } + } + + [Test] + public void Can_select_ModelWithBytes_using_anon_type() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithBytes + { + Id = 1, + Bytes = 1.ToUtf8Bytes() + }); + + var result = db.Single(new + { + Bytes = 1.ToUtf8Bytes() + }); + + Assert.That(result, Is.Not.Null); + } + } + + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SimpleInsertSelectBenchmark.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SimpleInsertSelectBenchmark.cs new file mode 100644 index 000000000..0c637a3fb --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SimpleInsertSelectBenchmark.cs @@ -0,0 +1,110 @@ +using System.Diagnostics; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class TableWithStrings + { + [AutoIncrement] + public int Id { get; set; } + public string String01 { get; set; } + public string String02 { get; set; } + public string String03 { get; set; } + public string String04 { get; set; } + public string String05 { get; set; } + public string String06 { get; set; } + public string String07 { get; set; } + public string String08 { get; set; } + public string String09 { get; set; } + public string String10 { get; set; } + public string String11 { get; set; } + public string String12 { get; set; } + public string String13 { get; set; } + public string String14 { get; set; } + public string String15 { get; set; } + public string String16 { get; set; } + public string String17 { get; set; } + public string String18 { get; set; } + public string String19 { get; set; } + public string String20 { get; set; } + + public static TableWithStrings Create(int i) + { + return new TableWithStrings + { + String01 = "String: " + i, + String02 = "String: " + i, + String03 = "String: " + i, + String04 = "String: " + i, + String05 = "String: " + i, + String06 = "String: " + i, + String07 = "String: " + i, + String08 = "String: " + i, + String09 = "String: " + i, + String10 = "String: " + i, + String11 = "String: " + i, + String12 = "String: " + i, + String13 = "String: " + i, + String14 = "String: " + i, + String15 = "String: " + i, + String16 = "String: " + i, + String17 = "String: " + i, + String18 = "String: " + i, + String19 = "String: " + i, + String20 = "String: " + i, + }; + } + } + + [NUnit.Framework.Ignore("Benchmark"), TestFixture] + [Category("Benchmark")] + public class SimpleInsertSelectBenchmark + { + [Test] + public void Simple_Perf_test_using_InMemory_Sqlite() + { + var dbFactory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider); + using (var db = dbFactory.Open()) + { + db.DropAndCreateTable(); + + var sw = Stopwatch.StartNew(); + for (int i = 0; i < 100; i++) + { + var row = TableWithStrings.Create(i); + db.Insert(row); + } + "[:memory:] Time to INSERT 100 rows: {0}ms".Print(sw.ElapsedMilliseconds); + + sw = Stopwatch.StartNew(); + var rows = db.Select(); + "[:memory:] Time to SELECT {0} rows: {1}ms".Print(rows.Count, sw.ElapsedMilliseconds); + } + } + + [Test] + public void Simple_Perf_test_using_File_Sqlite() + { + var dbPath = "~/App_Data/db.sqlite".MapProjectPath(); + var dbFactory = new OrmLiteConnectionFactory(dbPath, SqliteDialect.Provider); + using (var db = dbFactory.Open()) + { + db.DropAndCreateTable(); + + var sw = Stopwatch.StartNew(); + for (int i = 0; i < 100; i++) + { + var row = TableWithStrings.Create(i); + db.Insert(row); + } + "[db.sqlite] Time to INSERT 100 rows: {0}ms".Print(sw.ElapsedMilliseconds); + + sw = Stopwatch.StartNew(); + var rows = db.Select(); + "[db.sqlite] Time to SELECT {0} rows: {1}ms".Print(rows.Count, sw.ElapsedMilliseconds); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionIssues.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionIssues.cs new file mode 100644 index 000000000..ea52dcfd2 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionIssues.cs @@ -0,0 +1,33 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class SqlExpressionIssues : OrmLiteProvidersTestBase + { + public SqlExpressionIssues(DialectContext context) : base(context) {} + + public class MetadataEntity + { + [AutoIncrement] + public int Id { get; set; } + public int ObjectTypeCode { get; set; } + public string LogicalName { get; set; } + } + + [Test] + public void Can_Equals_method_and_operator_with_Scalar() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new MetadataEntity {ObjectTypeCode = 1, LogicalName = "inno_subject"}); + + Assert.That(db.Scalar(e => e.ObjectTypeCode, e => e.LogicalName == "inno_subject"), Is.EqualTo(1)); + Assert.That(db.Scalar(e => e.ObjectTypeCode, e => e.LogicalName.Equals("inno_subject")), Is.EqualTo(1)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionJoinWithRowversionTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionJoinWithRowversionTests.cs new file mode 100644 index 000000000..7fc4abe30 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionJoinWithRowversionTests.cs @@ -0,0 +1,85 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Expression; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + [TestFixtureOrmLite] + public class SqlExpressionJoinWithRowversionTests : ExpressionsTestBase + { + public SqlExpressionJoinWithRowversionTests(DialectContext context) : base(context) {} + + public class TableA + { + public int Id { get; set; } + public bool Bool { get; set; } + public string Name { get; set; } + + public ulong RowVersion { get; set; } + } + + public class TableB + { + public int Id { get; set; } + public int TableAId { get; set; } + public string Name { get; set; } + public ulong RowVersion { get; set; } + } + + private class JoinSelectResults2 + { + // From TableA + public int Id { get; set; } + public bool Bool { get; set; } + public string Name { get; set; } + + public ulong RowVersion { get; set; } + + + // From TableB + public int TableBId { get; set; } + public string TableBName { get; set; } + + public override bool Equals(object obj) + { + var other = (JoinSelectResults2)obj; + return Id == other.Id && Bool == other.Bool && Name == other.Name && TableBId == other.TableBId && TableBName == other.TableBName; + } + + public override int GetHashCode() => + ((23 * 37 + Id) * 37 + TableBId) + ^ Name.GetHashCode() + ^ TableBName.GetHashCode() + ^ (Bool ? 65535 : 0); + + } + + [Test] + public void Can_select_entire_tables_with_rowversion() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + db.Insert(new TableA { Id = 1, Bool = false, Name = "NameA1" }); + db.Insert(new TableA { Id = 2, Bool = true, Name = "NameA2" }); + db.Insert(new TableB { Id = 1, TableAId = 1, Name = "NameB1" }); + db.Insert(new TableB { Id = 2, TableAId = 2, Name = "NameB2" }); + db.Insert(new TableB { Id = 3, TableAId = 2, Name = "NameB3" }); + + var q1 = db.From() + .Join(); + + var results = db.Select(q1); + Assert.That(results.Count, Is.EqualTo(3)); + + var q2 = db.From() + .Join() + .Select((a, b) => new { a, TableBId = b.Id, TableBName = b.Name }); + + results = db.Select(q2); + Assert.That(results.Count, Is.EqualTo(3)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionSubSqlExpressionIssue.cs b/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionSubSqlExpressionIssue.cs new file mode 100644 index 000000000..51af9894b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionSubSqlExpressionIssue.cs @@ -0,0 +1,393 @@ +using System; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.SqlServer; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class AnyObjectClass + { + [Alias("_id")] + public Guid Id { get; set; } + + [Alias("_identity")] + public Guid? Identity { get; set; } + + [Alias("_name")] + [StringLength(250)] + public string Name { get; set; } + } + + [TestFixtureOrmLite] + public class SqlExpressionSubSqlExpressionIssue : OrmLiteProvidersTestBase + { + public SqlExpressionSubSqlExpressionIssue(DialectContext context) : base(context) {} + + private static void RecreateAnyObjectTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + } + + [Test] + public void Can_compare_null_constant_in_subquery() + { + using (var db = OpenDbConnection()) + { + RecreateAnyObjectTables(db); + + var inQ = db.From() + .Where(y => y.Identity != null) + .Select(y => y.Identity.Value); + + var q = db.From().Where(x => Sql.In(x.Identity, inQ)); + + var results = db.Select(q); + + results.PrintDump(); + } + } + + [Test] + public void Can_compare_null_constant_in_subquery_nested_in_SqlExpression() + { + using (var db = OpenDbConnection()) + { + RecreateAnyObjectTables(db); + + var q = db.From().Where(x => Sql.In(x.Identity, + db.From() + .Where(y => y.Identity != null) + .Select(y => y.Identity.Value))); + + var results = db.Select(q); + + results.PrintDump(); + } + } + + public class Person2 + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + } + + public class Order2 + { + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(Person2))] + public int Person2Id { get; set; } + + public DateTime OrderDate { get; set; } + + public int OrderTypeId { get; set; } + } + + [Test] + public void Can_reference_variable_in_sub_expression() + { + int orderTypeId = 2; + + using (var db = OpenDbConnection()) + { + var subExpr = db.From() + .Where(y => y.OrderTypeId == orderTypeId) + .Select(y => y.Person2Id); + + subExpr.ToSelectStatement().Print(); + Assert.That(subExpr.ToSelectStatement().NormalizeSql(), Does.Contain("@0")); + + var expr = db.From() + .Where(x => Sql.In(x.Id, subExpr)); + + expr.ToSelectStatement().Print(); + Assert.That(expr.ToSelectStatement().NormalizeSql(), Does.Contain("@0")); + } + } + + public class AnyObjectClass + { + public Guid? Identity { get; set; } + + public string Name { get; set; } + + public IDbConnection db; + + [DataAnnotations.Ignore] + public decimal CustomProperty + { + get + { + return db.Select + (s => Sql.In(s.Identity, + db.From() + .Where(b => b.AnyObjectClassId == this.Identity) + .Select(b => b.Identity)) + ).Sum(r => r.PurchasePrice); + } + } + } + + public class AnyObjectClassItem + { + public Guid? Identity { get; set; } + + public string Name { get; set; } + + public decimal PurchasePrice { get; set; } + + [ForeignKey(typeof(AnyObjectClass))] + public Guid AnyObjectClassId { get; set; } + + public AnyObjectClass AnyObjectClass { get; set; } + } + + [Test] + public void Can_select_sub_expression_when_called_within_a_datamodel() + { + using (var db = OpenDbConnection()) + { + RecreateAnyObjectTables(db); + + var model = new AnyObjectClass { db = db }; + var result = model.CustomProperty; + + result.PrintDump(); + db.GetLastSql().PrintDump(); + Assert.That(db.GetLastSql().NormalizeSql(), Does.Contain("is null")); + + model = new AnyObjectClass { db = db, Identity = Guid.Parse("104ECE6A-7117-4205-961C-126AD276565C") }; + result = model.CustomProperty; + + result.PrintDump(); + db.GetLastSql().PrintDump(); + Assert.That(db.GetLastSql().NormalizeSql(), Does.Contain("@")); + } + } + + [Test] + public void SubExpressions2() + { + int orderTypeId = 2; + using (var db = OpenDbConnection()) + { + var subExpr = db.From() + .Where(y => y.Order2TypeId == orderTypeId) + .Select(y => y.Person2Id); + + Assert.That(subExpr.ToSelectStatement().NormalizeSql(), Does.Contain("@")); + + var expr = db.From() + .Where(x => Sql.In(x.Id, subExpr)); + + Assert.That(subExpr.ToSelectStatement().NormalizeSql(), Does.Contain("@")); + } + } + + [Test] + public void Can_query_sub_expression_using_lambda() + { + using (var db = OpenDbConnection()) + { + var q = db.From() + .Where(x => Sql.In(x.Person2Id, + db.From() + .Where(p => p.Id == x.Person2Id) + .Select(p => new {p.Id}) + )); + + q.ToSelectStatement().Print(); + } + } + + [Test] + public void SubExpressions_TestMethod1() + { + using (var db = OpenDbConnection()) + { + var w = new Waybill(db) + { + Identity = Guid.Empty, + Name = "WaybillTest" + }; + + w.TestMethod1(); + } + } + + [Test] + public void SubExpressions_TestMethod2() + { + using (var db = OpenDbConnection()) + { + var w = new Waybill(db) + { + Identity = Guid.Empty, + Name = "WaybillTest" + }; + + w.TestMethod2(); + } + } + + [Test] + public void SubExpressions_TestMethod3() + { + using (var db = OpenDbConnection()) + { + var w = new Waybill(db) + { + Identity = Guid.Empty, + Name = "WaybillTest" + }; + + w.TestMethod3(); + } + } + + [Test] + public void SubExpressions_with_CustomSqlExpression_and_merging_multiple_predicates() + { + var db = new OrmLiteConnection(new OrmLiteConnectionFactory("test", new CustomSqlServerDialectProvider())); + + var q = db.From().Where(s => Sql.In(s.Identity, + db.From() + .Where(w => Sql.In(w.WaybillId, + db.From() + .Where(bb => bb.Identity == null) + .And(bb => bb.Name == "test") + .Select(ww => ww.Identity)) + ) + .Select(b => b.MarginItemId))); + + Assert.That(q.ToSelectStatement().NormalizeSql(), Does.Contain("@")); + } + } + + class CustomSqlExpression : SqlServerExpression + { + private Expression> _whereExpression; + + public CustomSqlExpression(IOrmLiteDialectProvider dialectProvider) : base(dialectProvider) {} + + public override SqlExpression And(Expression> predicate) + { + _whereExpression = _whereExpression == null ? predicate : predicate.And(_whereExpression); + return base.And(predicate); + } + } + + class CustomSqlServerDialectProvider : SqlServerOrmLiteDialectProvider + { + public override SqlExpression SqlExpression() + { + return new CustomSqlExpression(this); + } + } + + public class WaybillItem : BaseObject + { + public string WbItemName { get; set; } + + [ForeignKey(typeof(Waybill))] + public Guid WaybillId { get; set; } + + [ForeignKey(typeof(MarginItem))] + public Guid? MarginItemId { get; set; } + } + + public class MarginItem : BaseObject + { + public string MarginName { get; set; } + } + + + //------------------------- + public class Person3 + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + } + + public class Order3 + { + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(Person3))] + public int Person2Id { get; set; } + + public DateTime Order2Date { get; set; } + + public int Order2TypeId { get; set; } + } + + public class BaseObject + { + public Guid? Identity { get; set; } + } + + public class Waybill : BaseObject + { + private readonly IDbConnection db; + + public string Name { get; set; } + + public Waybill(IDbConnection db) + { + this.db = db; + } + + public void TestMethod1() + { + var localIdentity = this.Identity; + + var q = this.db.From() + .Where(s => Sql.In(s.Identity, + this.db.From() + .Where(b => b.WaybillId == localIdentity) + .Select(b => b.MarginItemId))); + + q.ToSelectStatement().PrintDump(); + Assert.That(q.ToSelectStatement().NormalizeSql(), Does.Contain("@")); + } + + public void TestMethod2() + { + var q = db.From() + .Where(s => Sql.In(s.Identity, + db.From() + .Where(b => b.WaybillId == this.Identity) + .Select(b => b.MarginItemId))); + + q.ToSelectStatement().PrintDump(); + Assert.That(q.ToSelectStatement().NormalizeSql(), Does.Contain("@")); + } + + public void TestMethod3() + { + var q = db.From() + .Where(s => Sql.In(s.Identity, + db.From() + .LeftJoin((wi, mi) => wi.MarginItemId == mi.Identity) + .Where(b => b.WaybillId == this.Identity) + .And(b => b.MarginName == this.Name) + .Select(b => b.MarginItemId))); + + q.ToSelectStatement().PrintDump(); + Assert.That(q.ToSelectStatement().NormalizeSql(), Does.Contain("@")); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Issues/UtcDateTimeIssueTests.cs b/tests/ServiceStack.OrmLite.Tests/Issues/UtcDateTimeIssueTests.cs new file mode 100644 index 000000000..61c9094fc --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Issues/UtcDateTimeIssueTests.cs @@ -0,0 +1,110 @@ +using System; +using System.Linq; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.Issues +{ + public class TestDate + { + public string Name { get; set; } + public DateTime ExpiryDate { get; set; } + } + + [TestFixtureOrmLite] + public class UtcDateTimeIssueTests : OrmLiteProvidersTestBase + { + public UtcDateTimeIssueTests(DialectContext context) : base(context) {} + + [Test] + public void Test_DateTime_Select() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + DateTime.UtcNow.ToJson().Print(); + + db.Insert(new TestDate { + Name = "Test name", + ExpiryDate = DateTime.UtcNow.AddHours(1) + }); + + //db.GetLastSql().Print(); + + var result = db.Select(q => q.ExpiryDate > DateTime.UtcNow); + db.GetLastSql().Print(); + + Assert.That(result.Count, Is.EqualTo(1)); + + //db.Select(q => q.ExpiryDate > DateTime.Now); + //db.GetLastSql().Print(); + + //db.Select().PrintDump(); + } + } + + [Test] + public void Can_select_DateTime_by_Range() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new TestDate { + Name = "Now", + ExpiryDate = DateTime.Now, + }); + db.Insert(new TestDate { + Name = "Today", + ExpiryDate = DateTime.Now.Date, + }); + db.Insert(new TestDate { + Name = "Tomorrow", + ExpiryDate = DateTime.Now.Date.AddDays(1), + }); + + var results = db.Select() + .Where(x => x.ExpiryDate >= DateTime.Now.Date && + x.ExpiryDate < DateTime.Now.Date.AddDays(1)); + + Assert.That(results.Map(x => x.Name), Is.EquivalentTo(new[]{"Now","Today"})); + } + } + + [Test] + public void Can_Select_DateTime_with_SelectFmt() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new TestDate + { + Name = "1999", + ExpiryDate = new DateTime(1999, 01, 01) + }); + db.Insert(new TestDate + { + Name = "2000", + ExpiryDate = new DateTime(2000, 01, 01) + }); + db.Insert(new TestDate + { + Name = "Test name", + ExpiryDate = DateTime.UtcNow.AddHours(1) + }); + + var result = db.Select("ExpiryDate".SqlColumn(DialectProvider) + " > @theDate".PreNormalizeSql(db), + new { theDate = DateTime.UtcNow }); + db.GetLastSql().Print(); + Assert.That(result.Count, Is.EqualTo(1)); + + result = db.Select("ExpiryDate".SqlColumn(DialectProvider) + " > @theDate".PreNormalizeSql(db), + new { theDate = new DateTime(1999, 01, 02) }); + db.GetLastSql().Print(); + Assert.That(result.Count, Is.EqualTo(2)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/JoinSqlBuilderTests.cs b/tests/ServiceStack.OrmLite.Tests/JoinSqlBuilderTests.cs deleted file mode 100644 index a07c1a2e8..000000000 --- a/tests/ServiceStack.OrmLite.Tests/JoinSqlBuilderTests.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System.Text.RegularExpressions; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Logging; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class JoinSqlBuilderTests : OrmLiteTestBase - { - [Alias("Users")] - public class WithAliasUser - { - [AutoIncrement] - public int Id { get; set; } - - [Alias("Nickname")] - public string Name { get; set; } - - [Alias("Agealias")] - public int Age { get; set; } - } - - [Alias("Addresses")] - public class WithAliasAddress - { - [AutoIncrement] - public int Id { get; set; } - public int UserId { get; set; } - public string City { get; set; } - - [Alias("Countryalias")] - public string Country { get; set; } - } - - public class User - { - [AutoIncrement] - public int Id { get; set; } - public string Name { get; set; } - public int Age { get; set; } - } - - public class Address - { - [AutoIncrement] - public int Id { get; set; } - public int UserId { get; set; } - public string City { get; set; } - public string Country { get; set; } - } - - - [Test] - public void FieldNameLeftJoinTest () - { - var joinQuery = new JoinSqlBuilder ().LeftJoin (x => x.Id, x => x.UserId).ToSql (); - var expected = "SELECT \"User\".\"Id\",\"User\".\"Name\",\"User\".\"Age\" \nFROM \"User\" \n LEFT OUTER JOIN \"Address\" ON \"User\".\"Id\" = \"Address\".\"UserId\" \n".NormalizeSql(); - var expectedNq = "SELECT \"User\".Id,\"User\".Name,\"User\".Age \nFROM \"User\" \n LEFT OUTER JOIN Address ON \"User\".Id = Address.UserId \n".NormalizeSql(); - - Assert.That(joinQuery.NormalizeSql(), Is.EqualTo(expected).Or.EqualTo(expectedNq)); - - joinQuery = new JoinSqlBuilder ().LeftJoin (x => x.Id, x => x.UserId).ToSql (); - expected = "SELECT \"Users\".\"Id\",\"Users\".\"Nickname\",\"Users\".\"Agealias\" \nFROM \"Users\" \n LEFT OUTER JOIN \"Addresses\" ON \"Users\".\"Id\" = \"Addresses\".\"UserId\" \n".NormalizeSql(); - expectedNq = "SELECT Users.Id,Users.Nickname,Users.Agealias \nFROM Users \n LEFT OUTER JOIN Addresses ON Users.Id = Addresses.UserId \n".NormalizeSql(); - - Assert.That(joinQuery.NormalizeSql(), Is.EqualTo(expected).Or.EqualTo(expectedNq)); - - joinQuery = new JoinSqlBuilder ().LeftJoin (x => x.Id, x => x.UserId).ToSql (); - expected = "SELECT \"User\".\"Id\",\"User\".\"Name\",\"User\".\"Age\" \nFROM \"User\" \n LEFT OUTER JOIN \"Addresses\" ON \"User\".\"Id\" = \"Addresses\".\"UserId\" \n".NormalizeSql(); - expectedNq = "SELECT \"User\".Id,\"User\".Name,\"User\".Age \nFROM \"User\" \n LEFT OUTER JOIN Addresses ON \"User\".Id = Addresses.UserId \n".NormalizeSql(); - - Assert.That(joinQuery.NormalizeSql(), Is.EqualTo(expected).Or.EqualTo(expectedNq)); - } - - [Test] - public void DoubleWhereLeftJoinTest () - { - var joinQuery = new JoinSqlBuilder().LeftJoin(x => x.Id, x => x.UserId - , sourceWhere: x => x.Age > 18 - , destinationWhere: x => x.Country == "Italy").ToSql (); - var expected = "SELECT \"User\".\"Id\",\"User\".\"Name\",\"User\".\"Age\" \nFROM \"User\" \n LEFT OUTER JOIN \"Addresses\" ON \"User\".\"Id\" = \"Addresses\".\"UserId\" \nWHERE (\"User\".\"Age\" > 18) AND (\"Addresses\".\"Countryalias\" = 'Italy') \n".NormalizeSql(); - var expectedNq = "SELECT \"User\".Id,\"User\".Name,\"User\".Age \nFROM \"User\" \n LEFT OUTER JOIN Addresses ON \"User\".Id = Addresses.UserId \nWHERE (\"User\".Age > 18) AND (Addresses.Countryalias = 'Italy') \n".NormalizeSql(); - - Assert.That(joinQuery.NormalizeSql(), Is.EqualTo(expected).Or.EqualTo(expectedNq)); - - var stmt = OrmLiteConfig.DialectProvider.ToSelectStatement(typeof(User), joinQuery); - Assert.That(Regex.Matches(stmt, @"(\b|\n)FROM(\b|\n)", RegexOptions.IgnoreCase).Count, Is.EqualTo(1)); - } - - [Test] - public void Can_execute_JoinSqlBuilder_as_SqlExpression() - { - var joinQuery = new JoinSqlBuilder() - .LeftJoin(x => x.Id, x => x.UserId - , sourceWhere: x => x.Age > 18 - , destinationWhere: x => x.Country == "Italy"); - - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - var userId = db.Insert(new User { Age = 27, Name = "Foo" }, selectIdentity:true); - db.Insert(new WithAliasAddress { City = "Rome", Country = "Italy", UserId = (int)userId }); - - var results = db.Select(joinQuery); - Assert.That(results.Count, Is.EqualTo(1)); - } - } - - [Test] - public void Can_execute_SqlBuilder_templates_as_SqlExpression() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - var sb = new SqlBuilder(); - - var tmpl = sb.AddTemplate("SELECT * FROM {0} u INNER JOIN {1} a on a.{2} = u.Id /**where**/" - .Fmt("User".SqlTable(), "Addresses".SqlTable(), "UserId".SqlColumn())); - - var paramString = OrmLiteConfig.DialectProvider.ParamString; - sb.Where("Age > " + paramString + "age", new { age = 18 }); - sb.Where("Countryalias = " + paramString + "country", new { country = "Italy" }); - - var userId = db.Insert(new User { Age = 27, Name = "Foo" }, selectIdentity: true); - db.Insert(new WithAliasAddress { City = "Rome", Country = "Italy", UserId = (int)userId }); - - var results = db.Select(tmpl, tmpl.Parameters); - - Assert.That(results.Count, Is.EqualTo(1)); - } - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqlServerLegacyTests.cs b/tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqlServerLegacyTests.cs new file mode 100644 index 000000000..0781c0adf --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqlServerLegacyTests.cs @@ -0,0 +1,129 @@ +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.OrmLite.Legacy; + +namespace ServiceStack.OrmLite.Tests.Legacy +{ + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class ApiSqlServerLegacyTests : OrmLiteProvidersTestBase + { + public ApiSqlServerLegacyTests(DialectContext context) : base(context) {} + + private IDbConnection db; + + [SetUp] + public void SetUp() + { + db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + } + + [TearDown] + public void TearDown() + { + db.Dispose(); + } + +#pragma warning disable 618 + [Test] + public void API_SqlServer_Legacy_Examples() + { + db.Select(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); + + db.Select(q => q.Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + db.Single(q => q.Where(x => x.Age == 42)); + if (DialectFeatures.RowOffset) + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0) ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + } + else + { + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)")); + } + + db.SelectFmt("Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + db.SelectFmt("SELECT * FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + db.Select(typeof(Person)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\"")); + + db.SelectFmt(typeof(Person), "Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); + + db.SelectLazyFmt("Age > {0}", 40).ToList(); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + db.SingleFmt("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + + db.ScalarFmt("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); + + db.ColumnFmt("SELECT LastName FROM Person WHERE Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); + + db.ColumnDistinctFmt("SELECT Age FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); + + db.LookupFmt("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); + + db.DictionaryFmt("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); + + db.ExistsFmt("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + db.ExistsFmt("SELECT * FROM Person WHERE Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); + + var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, db.From().Insert(x => new { x.FirstName, x.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(x => x.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + db.UpdateOnly(new Person { FirstName = "JJ" }, q => q.Update(x => x.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); + + db.UpdateFmt(set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + db.DeleteFmt("Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.DeleteFmt(typeof(Person), "Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.Delete(q => q.Where(x => x.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + db.DeleteFmt(where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + } +#pragma warning restore 618 + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqliteLegacyTests.cs b/tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqliteLegacyTests.cs new file mode 100644 index 000000000..978d5dbec --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Legacy/ApiSqliteLegacyTests.cs @@ -0,0 +1,121 @@ +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.OrmLite.Legacy; + +namespace ServiceStack.OrmLite.Tests.Legacy +{ + [TestFixtureOrmLiteDialects(Dialect.Sqlite)] + public class ApiSqliteLegacyTests : OrmLiteProvidersTestBase + { + public ApiSqliteLegacyTests(DialectContext context) : base(context) {} + + private IDbConnection db; + + [SetUp] + public void SetUp() + { + db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + } + + [TearDown] + public void TearDown() + { + db.Dispose(); + } + +#pragma warning disable 618 + [Test] + public void API_Sqlite_Legacy_Examples() + { + db.Insert(Person.Rockstars); + + db.Select(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)\nORDER BY \"Id\"")); + + db.Select(q => q.Where(x => x.Age > 40)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > @0)")); + + db.Single(q => q.Where(x => x.Age == 42)); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = @0)\nLIMIT 1")); + + db.SelectFmt("Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + db.SelectFmt("SELECT * FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); + + db.SelectFmt(typeof(Person), "Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); + + db.SelectLazyFmt("Age > {0}", 40).ToList(); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); + + db.SingleFmt("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + + db.ScalarFmt("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); + + db.ColumnFmt("SELECT LastName FROM Person WHERE Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); + + db.ColumnDistinctFmt("SELECT Age FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); + + db.LookupFmt("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); + + db.DictionaryFmt("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); + + db.ExistsFmt("Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); + db.ExistsFmt("SELECT * FROM Person WHERE Age = {0}", 42); + Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); + + var rowsAffected = db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, db.From().Insert(x => new { x.FirstName, x.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(x => new { x.FirstName, x.Age })); + Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES (@FirstName,@Age)")); + + db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName")); + + db.UpdateOnly(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName WHERE (\"FirstName\" = @0)")); + + db.UpdateFmt(set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt(DialectProvider, "JJ"), where: "LastName = {0}".SqlFmt(DialectProvider, "Hendrix")); + Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); + + db.DeleteFmt("Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.DeleteFmt(typeof(Person), "Age = {0}", 27); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.Delete(ev => ev.Where(p => p.Age == 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = @0)")); + + db.DeleteFmt(where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + + db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(DialectProvider, 27)); + Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); + } +#pragma warning restore 618 + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/LicenseUsageTests.cs b/tests/ServiceStack.OrmLite.Tests/LicenseUsageTests.cs index 8d45e823e..b9e8069ac 100644 --- a/tests/ServiceStack.OrmLite.Tests/LicenseUsageTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/LicenseUsageTests.cs @@ -1,7 +1,7 @@ -// Copyright (c) Service Stack LLC. All Rights Reserved. +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt - +using System; using System.Data; using NUnit.Framework; using ServiceStack.Configuration; @@ -9,9 +9,12 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] + [Ignore("Run manually")] + [TestFixtureOrmLite] public class FreeLicenseUsageTests : LicenseUsageTests { + public FreeLicenseUsageTests(DialectContext context) : base(context) {} + [SetUp] public void SetUp() { @@ -23,17 +26,21 @@ public void SetUp() [TearDown] public void TearDown() { +#if NETCORE + Licensing.RegisterLicense(Environment.GetEnvironmentVariable("SERVICESTACK_LICENSE")); +#else Licensing.RegisterLicense(new AppSettings().GetString("servicestack:license")); +#endif } - [Test] + [Ignore(""), Test] public void Allows_creation_of_10_tables() { Create10Tables(); Create10Tables(); } - [Test] + [Ignore(""), Test] public void Throws_on_creation_of_11_tables() { Create10Tables(); @@ -43,15 +50,21 @@ public void Throws_on_creation_of_11_tables() db.DropAndCreateTable()); } } - - [TestFixture] + + [Ignore("Run manually")] + [TestFixtureOrmLite] public class RegisteredLicenseUsageTests : LicenseUsageTests { + public RegisteredLicenseUsageTests(DialectContext context) : base(context) {} + [Test] public void Allows_creation_of_11_tables() { +#if NETCORE + Licensing.RegisterLicense(Environment.GetEnvironmentVariable("SERVICESTACK_LICENSE")); +#else Licensing.RegisterLicense(new AppSettings().GetString("servicestack:license")); - +#endif Create10Tables(); Create10Tables(); @@ -71,19 +84,20 @@ class T09 { public int Id { get; set; } } class T10 { public int Id { get; set; } } class T11 { public int Id { get; set; } } - public class LicenseUsageTests - : OrmLiteTestBase + public abstract class LicenseUsageTests : OrmLiteProvidersTestBase { + protected LicenseUsageTests(DialectContext context) : base(context) {} + protected IDbConnection db; - [TestFixtureSetUp] - public void TestFixtureSetUp() + [OneTimeSetUp] + public new void TestFixtureSetUp() { db = base.OpenDbConnection(); } - [TestFixtureTearDown] - public void TestFixtureTearDown() + [OneTimeTearDown] + public new void TestFixtureTearDown() { db.Dispose(); } diff --git a/tests/ServiceStack.OrmLite.Tests/LoadReferencesJoinTests.cs b/tests/ServiceStack.OrmLite.Tests/LoadReferencesJoinTests.cs index 76b037ef0..f427a3d2a 100644 --- a/tests/ServiceStack.OrmLite.Tests/LoadReferencesJoinTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/LoadReferencesJoinTests.cs @@ -1,25 +1,38 @@ using System; using System.Data; using System.Linq; +using System.Text; using NUnit.Framework; using ServiceStack.DataAnnotations; using ServiceStack.Model; +using ServiceStack.OrmLite.Dapper; using ServiceStack.OrmLite.Tests.UseCase; using ServiceStack.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; namespace ServiceStack.OrmLite.Tests { - public class LoadReferencesJoinTests - : OrmLiteTestBase + [TestFixtureOrmLite] + [NonParallelizable] + public class LoadReferencesJoinTests : OrmLiteProvidersTestBase { + public LoadReferencesJoinTests(DialectContext context) : base(context) {} + private IDbConnection db; - [TestFixtureSetUp] - public new void TestFixtureSetUp() + [OneTimeSetUp] + public void TestFixtureSetUp() { db = base.OpenDbConnection(); + ResetTables(); + } + + private void ResetTables() + { CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table + if(DialectFeatures.SchemaSupport) db.CreateSchema(); db.DropAndCreateTable(); db.DropAndCreateTable(); db.DropAndCreateTable(); @@ -35,8 +48,8 @@ public void SetUp() db.DeleteAll(); } - [TestFixtureTearDown] - public void TestFixtureTearDown() + [OneTimeTearDown] + public new void TestFixtureTearDown() { db.Dispose(); } @@ -63,6 +76,20 @@ private Customer AddCustomerWithOrders() return customer; } + [Test] + public async Task Can_execute_LoadSelectAsync_with_OrderBy() + { + var customers = AddCustomersWithOrders(); + + var q = db.From() + .OrderByFields("Id"); + + string[] include = null; + var results = await db.LoadSelectAsync(q); + + Assert.That(results.Count, Is.GreaterThan(1)); + } + public class FullCustomerInfo { public int Id { get; set; } @@ -95,7 +122,7 @@ public void Can_do_multiple_joins_with_SqlExpression() { AddCustomerWithOrders(); - var results = db.Select(q => q + var results = db.Select(db.From() .Join() .Join()); @@ -117,14 +144,14 @@ public void Can_do_joins_with_wheres_using_SqlExpression() { AddCustomerWithOrders(); - var results = db.Select(q => q + var results = db.Select(db.From() .Join() .Join((c, o) => c.Id == o.CustomerId && o.Cost < 2)); var costs = results.ConvertAll(x => x.Cost); Assert.That(costs, Is.EquivalentTo(new[] { 1.99m })); - var orders = db.Select(q => q + var orders = db.Select(db.From() .Join() .Join() .Where(o => o.Cost < 2) @@ -133,7 +160,7 @@ public void Can_do_joins_with_wheres_using_SqlExpression() costs = orders.ConvertAll(x => x.Cost); Assert.That(costs, Is.EquivalentTo(new[] { 1.99m })); - results = db.Select(q => q + results = db.Select(db.From() .Join() .Join() .Where(o => o.Cost < 2)); @@ -141,7 +168,7 @@ public void Can_do_joins_with_wheres_using_SqlExpression() costs = results.ConvertAll(x => x.Cost); Assert.That(costs, Is.EquivalentTo(new[] { 1.99m })); - results = db.Select(q => q + results = db.Select(db.From() .Join() .Join() .Where(o => o.Cost < 2 || o.LineItem == "Line 2")); @@ -168,7 +195,7 @@ public void Can_do_joins_with_complex_wheres_using_SqlExpression() new Country { CountryName = "Australia", CountryCode = "AU" }, new Country { CountryName = "USA", CountryCode = "US" }); - var results = db.Select(q => q + var results = db.Select(db.From() .Join() //implicit .Join() //explicit .Where(c => c.Name == "Customer 1") @@ -192,7 +219,7 @@ public void Can_do_joins_with_complex_wheres_using_SqlExpression() costs = results.ConvertAll(x => x.Cost); Assert.That(costs, Is.EquivalentTo(new[] { 1.99m, 1.49m, 9.99m })); - results = db.Select(q => q + results = db.Select(db.From() .Join() .Join() .Where(c => c.Name == "Customer 2") @@ -267,27 +294,27 @@ public void Can_do_LeftJoins_using_SqlExpression() new Country { CountryName = "Spain", CountryCode = "ED" }); //Normal Join - var dbCustomers = db.Select(q => q + var dbCustomers = db.Select(db.From() .Join() .Join((ca, c) => ca.Country == c.CountryName)); Assert.That(dbCustomers.Count, Is.EqualTo(2)); //Left Join - dbCustomers = db.Select(q => q + dbCustomers = db.Select(db.From() .Join() .LeftJoin((ca, c) => ca.Country == c.CountryName)); Assert.That(dbCustomers.Count, Is.EqualTo(3)); //Warning: Right and Full Joins are not implemented by Sqlite3. Avoid if possible. - var dbCountries = db.Select(q => q + var dbCountries = db.Select(db.From() .LeftJoin((c, ca) => ca.Country == c.CountryName) .LeftJoin()); Assert.That(dbCountries.Count, Is.EqualTo(4)); - var dbAddresses = db.Select(q => q + var dbAddresses = db.Select(db.From() .LeftJoin((ca, c) => ca.Country == c.CountryName) .LeftJoin()); @@ -338,27 +365,27 @@ public void Can_Join_on_matching_Alias_convention() AddAliasedCustomers(out countries); //Normal Join - var dbCustomers = db.Select(q => q + var dbCustomers = db.Select(db.From() .Join() .Join((ca, c) => ca.Country == c.CountryName)); Assert.That(dbCustomers.Count, Is.EqualTo(2)); //Left Join - dbCustomers = db.Select(q => q + dbCustomers = db.Select(db.From() .Join() .LeftJoin((ca, c) => ca.Country == c.CountryName)); Assert.That(dbCustomers.Count, Is.EqualTo(3)); //Warning: Right and Full Joins are not implemented by Sqlite3. Avoid if possible. - var dbCountries = db.Select(q => q + var dbCountries = db.Select(db.From() .LeftJoin((c, ca) => ca.Country == c.CountryName) .LeftJoin()); Assert.That(dbCountries.Count, Is.EqualTo(4)); - var dbAddresses = db.Select(q => q + var dbAddresses = db.Select(db.From() .LeftJoin((ca, c) => ca.Country == c.CountryName) .LeftJoin()); @@ -427,7 +454,7 @@ public void Does_populate_custom_columns_based_on_property_convention() var customer = AddCustomerWithOrders(); - var results = db.Select(q => q + var results = db.Select(db.From() .Join() .Join()); @@ -472,7 +499,7 @@ public void Does_populate_custom_mixed_columns() var customers = AddAliasedCustomers(out countries); //Normal Join - var results = db.Select(q => q + var results = db.Select(db.From() .Join() .Join((ca, c) => ca.Country == c.CountryName)); @@ -515,9 +542,11 @@ public void Can_LeftJoin_and_select_empty_relation() db.Save(customer, references: true); +#pragma warning disable 472 var q = db.From(); q.LeftJoin() .Where(o => o.Id == null); +#pragma warning restore 472 var customers = db.Select(q); @@ -551,6 +580,30 @@ public void Can_load_list_of_references() Is.EquivalentTo(new[] { 1.99m, 3.98m, 1.49m, 2.98m, 9.99m })); } + [Test] + public void Can_load_list_of_references_using_subselect() + { + AddCustomersWithOrders(); + + var customers = db.Select(db.From() + .Join() + .Where(o => o.Qty == 1) + .OrderBy(x => x.Id) + .SelectDistinct()); + + var orders = db.Select(o => o.Qty == 1); + + customers.Merge(orders); + + customers.PrintDump(); + + Assert.That(customers.Count, Is.EqualTo(2)); + Assert.That(customers[0].Orders.Count, Is.EqualTo(3)); + Assert.That(customers[0].Orders.All(x => x.Qty == 1)); + Assert.That(customers[1].Orders.Count, Is.EqualTo(1)); + Assert.That(customers[1].Orders.All(x => x.Qty == 1)); + } + [Test] public void Can_join_on_references_attribute() { @@ -565,7 +618,7 @@ public void Can_join_on_references_attribute() var id1 = db.Insert(new TABLE_1 { One = "A" }, selectIdentity: true); var id2 = db.Insert(new TABLE_1 { One = "B" }, selectIdentity: true); - db.Insert(new TABLE_2 { Three = "C", TableOneKey = (int) id1 }); + db.Insert(new TABLE_2 { Three = "C", TableOneKey = (int)id1 }); var q = db.From() .Join(); @@ -574,15 +627,16 @@ public void Can_join_on_references_attribute() Assert.That(results.Count, Is.EqualTo(1)); Assert.That(results[0].One, Is.EqualTo("A")); - var row3 = new TABLE_3 { + var row3 = new TABLE_3 + { Three = "3a", - TableTwo = new TABLE_2 + TableTwo = new TABLE_2 { Three = "3b", TableOneKey = (int)id1, } }; - db.Save(row3, references:true); + db.Save(row3, references: true); Assert.That(row3.TableTwoKey, Is.EqualTo(row3.TableTwo.Id)); @@ -595,7 +649,7 @@ public void Can_load_references_with_OrderBy() { AddCustomersWithOrders(); - var customers = db.LoadSelect(q => q.OrderBy(x => x.Name)); + var customers = db.LoadSelect(db.From().OrderBy(x => x.Name)); var addresses = customers.Select(x => x.PrimaryAddress).ToList(); var orders = customers.SelectMany(x => x.Orders).ToList(); @@ -605,24 +659,87 @@ public void Can_load_references_with_OrderBy() } [Test] + public void Can_load_select_with_join() + { + // Drop tables in order that FK allows + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + + var id1 = db.Insert(new TABLE_1 { One = "A" }, selectIdentity: true); + var id2 = db.Insert(new TABLE_1 { One = "B" }, selectIdentity: true); + + db.Insert(new TABLE_2 { Three = "C", TableOneKey = (int)id1 }); + + var q = db.From() + .Join(); + var results = db.LoadSelect(q); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].One, Is.EqualTo("A")); + + var row3 = new TABLE_3 + { + Three = "3a", + TableTwo = new TABLE_2 + { + Three = "3b", + TableOneKey = (int)id1, + } + }; + db.Save(row3, references: true); + + Assert.That(row3.TableTwoKey, Is.EqualTo(row3.TableTwo.Id)); + + row3 = db.LoadSingleById(row3.Id); + Assert.That(row3.TableTwoKey, Is.EqualTo(row3.TableTwo.Id)); + } + + [Test] + public void Can_load_select_with_join_and_same_name_columns() + { + // Drop tables in order that FK allows + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.Insert(new Project { Val = "test" }); + db.Insert(new ProjectTask { Val = "testTask", ProjectId = 1 }); + + var query = db.From() + .Join((pt, p) => pt.ProjectId == p.Id); + + var selectResults = db.Select(query); + + var results = db.LoadSelect(query); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Val, Is.EqualTo("testTask")); + } + + [Test] + [IgnoreDialect(Dialect.AnyMySql, "doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery")] + [IgnoreDialect(Dialect.AnySqlServer, "Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.")] public void Can_load_references_with_OrderBy_and_Paging() { - //This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' - if (Dialect == Dialect.MySql) return; + db.DropTable(); + db.DropTable(); - db.DropTable(); - db.DropTable(); - db.CreateTable(); - db.CreateTable(); + db.CreateTable(); + db.CreateTable(); - db.Save(new Child { Id = 1, Value = "Lolz" }); - db.Insert(new Parent { Id = 1, ChildId = null }); - db.Insert(new Parent { Id = 2, ChildId = 1 }); + db.Save(new ChildSelf { Id = 1, Value = "Lolz" }); + db.Insert(new ParentSelf { Id = 1, ChildId = null }); + db.Insert(new ParentSelf { Id = 2, ChildId = 1 }); // Select the Parent.Id == 2. LoadSelect should populate the child, but doesn't. - var q = db.From() + var q = db.From() .Take(1) - .OrderByDescending(p => p.Id); + .OrderByDescending(p => p.Id); var results = db.LoadSelect(q); @@ -630,9 +747,9 @@ public void Can_load_references_with_OrderBy_and_Paging() Assert.That(results[0].Child, Is.Not.Null); Assert.That(results[0].Child.Value, Is.EqualTo("Lolz")); - q = db.From() + q = db.From() .Skip(1) - .OrderBy(p => p.Id); + .OrderBy(p => p.Id); results = db.LoadSelect(q); @@ -641,21 +758,229 @@ public void Can_load_references_with_OrderBy_and_Paging() Assert.That(results[0].Child.Value, Is.EqualTo("Lolz")); results.PrintDump(); } + + [Test] + [IgnoreDialect(Tests.Dialect.AnyPostgreSql, "Dapper doesn't know about pgsql naming conventions")] + public void Can_populate_multiple_POCOs_using_Dappers_QueryMultiple() + { + ResetTables(); + AddCustomerWithOrders(); + + var q = db.From() + .Join() + .Join() + .OrderBy(x => x.Id) + .Select("*"); + + using (var multi = db.QueryMultiple(q.ToSelectStatement())) + { + var tuples = multi.Read>( + Tuple.Create).ToList(); + + var sb = new StringBuilder(); + foreach (var tuple in tuples) + { + sb.AppendLine("Customer:"); + sb.AppendLine(tuple.Item1.Dump()); + sb.AppendLine("Customer Address:"); + sb.AppendLine(tuple.Item2.Dump()); + sb.AppendLine("Order:"); + sb.AppendLine(tuple.Item3.Dump()); + } + + AssertMultiCustomerOrderResults(sb); + } + } + + [Test] + public void Can_populate_multiple_POCOs_using_SelectMulti2() + { + ResetTables(); + AddCustomerWithOrders(); + + var q = db.From() + .Join(); + + var tuples = db.SelectMulti(q); + + var sb = new StringBuilder(); + foreach (var tuple in tuples) + { + sb.AppendLine("Customer:"); + sb.AppendLine(tuple.Item1.Dump()); + sb.AppendLine("Customer Address:"); + sb.AppendLine(tuple.Item2.Dump()); + } + + Assert.That(sb.ToString().NormalizeNewLines().Trim(), Is.EqualTo( +@"Customer: +{ + Id: 1, + Name: Customer 1 +} +Customer Address: +{ + Id: 1, + CustomerId: 1, + AddressLine1: 1 Australia Street, + Country: Australia +}".NormalizeNewLines())); + } + + [Test] + public void Can_populate_multiple_POCOs_using_SelectMulti2_Distinct() + { + ResetTables(); + AddCustomerWithOrders(); + + var q = db.From() + .Join(); + + var tuples = db.SelectMulti(q.SelectDistinct()); + + var sb = new StringBuilder(); + foreach (var tuple in tuples) + { + sb.AppendLine("Customer:"); + sb.AppendLine(tuple.Item1.Dump()); + sb.AppendLine("Customer Address:"); + sb.AppendLine(tuple.Item2.Dump()); + } + + var sql = db.GetLastSql(); + Assert.That(sql, Does.Contain("SELECT DISTINCT")); + + Assert.That(sb.ToString().NormalizeNewLines().Trim(), Is.EqualTo( + @"Customer: +{ + Id: 1, + Name: Customer 1 +} +Customer Address: +{ + Id: 1, + CustomerId: 1, + AddressLine1: 1 Australia Street, + Country: Australia +}".NormalizeNewLines())); + } + + [Test] + public void Can_populate_multiple_POCOs_using_SelectMulti3() + { + ResetTables(); + AddCustomerWithOrders(); + + var q = db.From() + .Join() + .Join() + .Where(x => x.Id == 1) + .And(x => x.Country == "Australia") + .OrderBy(x => x.Id); + + var tuples = db.SelectMulti(q); + + var sb = new StringBuilder(); + foreach (var tuple in tuples) + { + sb.AppendLine("Customer:"); + sb.AppendLine(tuple.Item1.Dump()); + sb.AppendLine("Customer Address:"); + sb.AppendLine(tuple.Item2.Dump()); + sb.AppendLine("Order:"); + sb.AppendLine(tuple.Item3.Dump()); + } + sb.ToString().Print(); + AssertMultiCustomerOrderResults(sb); + } + + [Test] + public void Can_custom_select_from_multiple_joined_tables() + { + ResetTables(); + AddCustomerWithOrders(); + + var q = db.From() + .Join() + .Join() + .Where(x => x.Id == 1) + .And(x => x.Country == "Australia") + .OrderByDescending(x => x.Id) + .Take(1) + .Select((c,a,o) => new { + o.Id, + c.Name, + CustomerId = c.Id, + AddressId = a.Id, + }); + + var result = db.Select<(int id, string name, int customerId, int addressId)>(q)[0]; + + Assert.That(result.id, Is.EqualTo(2)); + Assert.That(result.name, Is.EqualTo("Customer 1")); + Assert.That(result.customerId, Is.EqualTo(1)); + Assert.That(result.addressId, Is.EqualTo(1)); + } + + private static void AssertMultiCustomerOrderResults(StringBuilder sb) + { + Assert.That(Regex.Replace(sb.ToString(), @"\.99[0]+",".99").NormalizeNewLines().Trim(), Is.EqualTo( + @"Customer: +{ + Id: 1, + Name: Customer 1 +} +Customer Address: +{ + Id: 1, + CustomerId: 1, + AddressLine1: 1 Australia Street, + Country: Australia +} +Order: +{ + Id: 1, + CustomerId: 1, + LineItem: Line 1, + Qty: 1, + Cost: 1.99 +} +Customer: +{ + Id: 1, + Name: Customer 1 +} +Customer Address: +{ + Id: 1, + CustomerId: 1, + AddressLine1: 1 Australia Street, + Country: Australia +} +Order: +{ + Id: 2, + CustomerId: 1, + LineItem: Line 2, + Qty: 2, + Cost: 2.99 +}".NormalizeNewLines())); + } } - public class Parent + public class ParentSelf { [PrimaryKey] public int Id { get; set; } - [References(typeof(Child))] + [References(typeof(ChildSelf))] public int? ChildId { get; set; } [Reference] - public Child Child { get; set; } + public ChildSelf Child { get; set; } } - public class Child + public class ChildSelf { [PrimaryKey] public int Id { get; set; } @@ -704,4 +1029,35 @@ public class TABLE_3 : IHasId [Reference] public TABLE_2 TableTwo { get; set; } } + + [Schema("Schema")] + [Alias("ProjectTask")] + public class ProjectTask : IHasId + { + [Alias("ProjectTaskId")] + [Index(Unique = true)] + [AutoIncrement] + public int Id { get; set; } + + [References(typeof(Project))] + public int ProjectId { get; set; } + + [Reference] + public Project Project { get; set; } + + public string Val { get; set; } + } + + [Schema("Schema")] + [Alias("Project")] + public class Project : IHasId + { + [Alias("ProjectId")] + [Index(Unique = true)] + [AutoIncrement] + public int Id { get; set; } + + public string Val { get; set; } + + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs b/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs index a886d7642..b90c625e8 100644 --- a/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; -using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.DataAnnotations; using ServiceStack.OrmLite.Tests.UseCase; @@ -182,12 +181,14 @@ public class MultiSelfCustomer } - public class LoadReferencesTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class LoadReferencesTests : OrmLiteProvidersTestBase { + public LoadReferencesTests(DialectContext context) : base(context) {} + private IDbConnection db; - [TestFixtureSetUp] + [OneTimeSetUp] public new void TestFixtureSetUp() { db = base.OpenDbConnection(); @@ -219,10 +220,13 @@ public void SetUp() db.DeleteAll(); db.DeleteAll(); db.DeleteAll(); + db.DeleteAll(); + db.DeleteAll(); + db.DeleteAll(); } - [TestFixtureTearDown] - public void TestFixtureTearDown() + [OneTimeTearDown] + public new void TestFixtureTearDown() { db.Dispose(); } @@ -248,7 +252,7 @@ public void Can_Save_and_Load_References() State = "Northern Territory", Country = "Australia" }, - Orders = new[] { + Orders = new[] { new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, }.ToList(), @@ -372,18 +376,18 @@ private Customer AddCustomerWithOrders() return customer; } - public static Customer GetCustomerWithOrders(string id="1") + public static Customer GetCustomerWithOrders(string id = "1") { var customer = new Customer { Name = "Customer " + id, PrimaryAddress = new CustomerAddress - { - AddressLine1 = id + " Humpty Street", - City = "Humpty Doo", - State = "Northern Territory", - Country = "Australia" - }, + { + AddressLine1 = id + " Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, Orders = new[] { new Order {LineItem = "Line 1", Qty = 1, Cost = 1.99m}, @@ -611,22 +615,136 @@ public void Can_support_multiple_self_references() db.Save(x, references: true)); var results = db.LoadSelect(q => - q.HomeAddressId != null && + q.HomeAddressId != null && q.WorkAddressId != null); results.PrintDump(); Assert.That(results.Count, Is.EqualTo(2)); - Assert.That(results[0].HomeAddress.AddressLine1, Is.StringContaining("Home")); - Assert.That(results[0].WorkAddress.AddressLine1, Is.StringContaining("Work")); - Assert.That(results[1].HomeAddress.AddressLine1, Is.StringContaining("Home")); - Assert.That(results[1].WorkAddress.AddressLine1, Is.StringContaining("Work")); + Assert.That(results[0].HomeAddress.AddressLine1, Does.Contain("Home")); + Assert.That(results[0].WorkAddress.AddressLine1, Does.Contain("Work")); + Assert.That(results[1].HomeAddress.AddressLine1, Does.Contain("Home")); + Assert.That(results[1].WorkAddress.AddressLine1, Does.Contain("Work")); var ukAddress = db.Single(q => q.Country == "UK"); ukAddress.PrintDump(); Assert.That(ukAddress.AddressLine1, Is.EqualTo("2 Work Park")); } + [Test] + public void Can_load_only_included_references() + { + var customer = new Customer + { + Name = "Customer 1", + PrimaryAddress = new CustomerAddress + { + AddressLine1 = "1 Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, + Orders = new[] { + new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, + new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, + }.ToList(), + }; + + db.Save(customer, references: true); + Assert.That(customer.Id, Is.GreaterThan(0)); + + var dbCustomers = db.LoadSelect(x => x.Id == customer.Id, include: x => x.PrimaryAddress); + Assert.That(dbCustomers.Count, Is.EqualTo(1)); + Assert.That(dbCustomers[0].Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomers[0].Orders, Is.Null); + Assert.That(dbCustomers[0].PrimaryAddress, Is.Not.Null); + + dbCustomers = db.LoadSelect(q => q.Id == customer.Id, include: new[] { "primaryaddress" }); + Assert.That(dbCustomers.Count, Is.EqualTo(1)); + Assert.That(dbCustomers[0].Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomers[0].Orders, Is.Null); + Assert.That(dbCustomers[0].PrimaryAddress, Is.Not.Null); + + // Test LoadSingleById + var dbCustomer = db.LoadSingleById(customer.Id, include: new[] { "PrimaryAddress" }); + Assert.That(dbCustomer.Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null); + + dbCustomer = db.LoadSingleById(customer.Id, include: new[] { "primaryaddress" }); + Assert.That(dbCustomer.Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null); + + dbCustomer = db.LoadSingleById(customer.Id, include: x => new { x.PrimaryAddress }); + Assert.That(dbCustomer.Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null); + + dbCustomers = db.LoadSelect(q => q.Id == customer.Id, include: new string[0]); + Assert.That(dbCustomers.All(x => x.Orders == null)); + Assert.That(dbCustomers.All(x => x.PrimaryAddress == null)); + + dbCustomer = db.LoadSingleById(customer.Id, include: new string[0]); + Assert.That(dbCustomer.Name, Is.EqualTo("Customer 1")); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Null); + + // Invalid field name + dbCustomers = db.LoadSelect(q => q.Id == customer.Id, include: new[] { "InvalidOption1", "InvalidOption2" }); + Assert.That(dbCustomers.All(x => x.Orders == null)); + Assert.That(dbCustomers.All(x => x.PrimaryAddress == null)); + + dbCustomer = db.LoadSingleById(customer.Id, include: new[] { "InvalidOption1", "InvalidOption2" }); + Assert.That(dbCustomer.Orders, Is.Null); + Assert.That(dbCustomer.PrimaryAddress, Is.Null); + } + + [Test] + public void Can_load_included_references_via_sql_in_expression() + { + var customer = new Customer + { + Name = "Customer 1", + PrimaryAddress = new CustomerAddress + { + AddressLine1 = "1 Humpty Street", + City = "Humpty Doo", + State = "Northern Territory", + Country = "Australia" + }, + Orders = new[] { + new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, + new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, + }.ToList(), + }; + + db.Save(customer, references: true); + + var customersSubFilter = db.From().Select(c => c.Id); + var orderQuery = db.From().Where(q => Sql.In(q.CustomerId, customersSubFilter)); + var dbOrders = db.Select(orderQuery); + Assert.That(dbOrders.Count, Is.EqualTo(2)); + + // Negative case + customersSubFilter = db.From().Select(c => c.Id).Where(c => c.Id == -1); + orderQuery = db.From().Where(q => Sql.In(q.CustomerId, customersSubFilter)); + + dbOrders = db.Select(orderQuery); + Assert.That(dbOrders.Count, Is.EqualTo(0)); + + //Test merge subselect params + orderQuery = db.From().Where(q => q.CustomerId >= 1 && Sql.In(q.CustomerId, customersSubFilter)); + + Assert.That(orderQuery.Params.Count, Is.EqualTo(2)); + Assert.That(orderQuery.Params[0].Value, Is.EqualTo(1)); + Assert.That(orderQuery.Params[0].ParameterName, Does.EndWith("0")); + Assert.That(orderQuery.Params[1].Value, Is.EqualTo(-1)); + Assert.That(orderQuery.Params[1].ParameterName, Does.EndWith("1")); + + dbOrders = db.Select(orderQuery); + Assert.That(dbOrders.Count, Is.EqualTo(0)); + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/LocalizationTests.cs b/tests/ServiceStack.OrmLite.Tests/LocalizationTests.cs index ebfd49e52..04bf0aac1 100644 --- a/tests/ServiceStack.OrmLite.Tests/LocalizationTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/LocalizationTests.cs @@ -1,62 +1,43 @@ -using System; -using System.Globalization; -using System.Threading; using NUnit.Framework; using ServiceStack.DataAnnotations; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class LocalizationTests : OrmLiteTestBase - { - private readonly CultureInfo CurrentCulture = Thread.CurrentThread.CurrentCulture; - private readonly CultureInfo CurrentUICulture = Thread.CurrentThread.CurrentUICulture; - - [SetUp] - public void TestSetUp() - { - Thread.CurrentThread.CurrentCulture = new CultureInfo("vi-VN"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("vi-VN"); - } - - [TearDown] - public void TestFixtureTearDown() - { - Thread.CurrentThread.CurrentCulture = CurrentCulture; - Thread.CurrentThread.CurrentUICulture = CurrentUICulture; - } - - public class Point - { - [AutoIncrement] - public int Id { get; set; } - public short Width { get; set; } - public float Height { get; set; } - public double Top { get; set; } - public decimal Left { get; set; } - } - - [Test] - public void Can_query_using_float_in_alernate_culuture() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - db.Insert(new Point { Width = 4, Height = 1.123f, Top = 3.456d, Left = 2.345m}); - db.PrintLastSql(); - - var sql = Dialect == Dialect.PostgreSql - ? "round(cast(Height as numeric),3)={0}" - : "round(Height,3)={0}"; - var points = db.SelectFmt(sql, 1.123); - - Assert.That(points[0].Width, Is.EqualTo(4)); - Assert.That(points[0].Height, Is.EqualTo(1.123f)); - Assert.That(points[0].Top, Is.EqualTo(3.456d)); - Assert.That(points[0].Left, Is.EqualTo(2.345m)); - } - } - - } + [TestFixtureOrmLite, SetUICulture("vi-VN"), SetCulture("vi-VN")] + public class LocalizationTests : OrmLiteProvidersTestBase + { + public LocalizationTests(DialectContext context) : base(context) {} + + [Test] + public void Can_query_using_float_in_alternate_culture() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + db.Insert(new Point { Width = 4, Height = 1.123f, Top = 3.456d, Left = 2.345m }); + db.GetLastSql().Print(); + + var sql = "Height = @height".PreNormalizeSql(db); + var points = db.Select(sql, new { height = 1.123 }); + db.GetLastSql().Print(); + + Assert.That(points[0].Width, Is.EqualTo(4)); + Assert.That(points[0].Height, Is.EqualTo(1.123f)); + Assert.That(points[0].Top, Is.EqualTo(3.456d).Within(1d)); + Assert.That(points[0].Left, Is.EqualTo(2.345m).Within(1m)); + } + } + + public class Point + { + [AutoIncrement] + public int Id { get; set; } + public short Width { get; set; } + public float Height { get; set; } + public double Top { get; set; } + public decimal Left { get; set; } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/LoggingTests.cs b/tests/ServiceStack.OrmLite.Tests/LoggingTests.cs new file mode 100644 index 000000000..61c0bb88f --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/LoggingTests.cs @@ -0,0 +1,89 @@ +using System; +using System.Data; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Logging; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public class LogTest + { + [AutoIncrement] + public int Id { get; set; } + + public int CustomerId { get; set; } + + public string Name { get; set; } + } + + [TestFixtureOrmLite, NUnit.Framework.Ignore("Initializing LogFactory needs to run stand-alone")] + public class LoggingTests : OrmLiteProvidersTestBase + { + public LoggingTests(DialectContext context) : base(context) {} + + [NUnit.Framework.Ignore(""), Test] + public void Does_log_all_statements() + { + var sbLogFactory = new StringBuilderLogFactory(); + var testLogger = TestLogger.GetLogs().Count; + + using var db = OpenDbConnection(); + db.DropTable(); + db.CreateTable(); + + db.Insert(new LogTest + { + CustomerId = 2, + Name = "Foo" + }); + + var test = db.Single(x => x.CustomerId == 2); + + test.Name = "Bar"; + + db.Update(test); + + test = db.Single(x => x.CustomerId == 2); + + db.DeleteById(test.Id); + + var logs = sbLogFactory.GetLogs(); + logs.Print(); + + //var logs = TestLogger.GetLogs(); + + Assert.That(logs, Does.Contain("CREATE TABLE")); + Assert.That(logs, Does.Contain("INSERT INTO")); + Assert.That(logs, Does.Contain("SELECT")); + Assert.That(logs, Does.Contain("UPDATE")); + Assert.That(logs, Does.Contain("DELETE FROM")); + } + + [NUnit.Framework.Ignore(""), Test] + public void Can_handle_sql_exceptions() + { + string lastSql = null; + IDbDataParameter lastParam = null; + OrmLiteConfig.ExceptionFilter = (dbCmd, ex) => + { + lastSql = dbCmd.CommandText; + lastParam = (IDbDataParameter)dbCmd.Parameters[0]; + }; + + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + try + { + var results = db.Select("Unknown = @arg", new { arg = "foo" }); + Assert.Fail("Should throw"); + } + catch (Exception) + { + Assert.That(lastSql, Does.Contain("Unknown")); + Assert.That(lastParam.Value, Is.EqualTo("foo")); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/MaxDataTypeTests.cs b/tests/ServiceStack.OrmLite.Tests/MaxDataTypeTests.cs new file mode 100644 index 000000000..f1595543c --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/MaxDataTypeTests.cs @@ -0,0 +1,57 @@ +using System; +using NUnit.Framework; +using ServiceStack.Common.Tests.Models; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class MaxDataTypeTests : OrmLiteProvidersTestBase + { + public MaxDataTypeTests(DialectContext context) : base(context) {} + + [Test] + public void Can_insert_and_select_max_values() + { + OrmLiteConfig.ThrowOnError = true; + var isSqlServer = Dialect.AnySqlServer.HasFlag(Dialect); + + var model = new ModelWithFieldsOfDifferentTypes + { + Int = int.MaxValue, + Long = long.MaxValue, + Double = double.MaxValue, + Decimal = !isSqlServer && !Dialect.Sqlite.HasFlag(Dialect) && !Dialect.AnyPostgreSql.HasFlag(Dialect) + ? Decimal.MaxValue + : long.MaxValue, + DateTime = !Dialect.AnyMySql.HasFlag(Dialect) + ? DateTime.MaxValue + : DateTime.MaxValue.AddYears(-1), + TimeSpan = TimeSpan.MaxValue, + }; + + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + //db.GetLastSql().Print(); + + var id = db.Insert(model, selectIdentity: true); + + var fromDb = db.SingleById(id); + + Assert.That(fromDb.Int, Is.EqualTo(model.Int)); + Assert.That(fromDb.Long, Is.EqualTo(model.Long)); + Assert.That(fromDb.Double, Is.EqualTo(model.Double)); + Assert.That(fromDb.DateTime, Is.EqualTo(model.DateTime).Within(TimeSpan.FromSeconds(1))); + Assert.That(fromDb.TimeSpan, Is.EqualTo(model.TimeSpan)); + + if (Dialect != Dialect.Sqlite) + { + Assert.That(fromDb.Decimal, Is.EqualTo(model.Decimal)); + } + else + { + Assert.That(fromDb.Decimal / 10000, Is.EqualTo(model.Decimal / 10000).Within(1)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/MergeTests.cs b/tests/ServiceStack.OrmLite.Tests/MergeTests.cs new file mode 100644 index 000000000..4679e0c7b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/MergeTests.cs @@ -0,0 +1,48 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.UseCase; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public class TimeSheet + { + [AutoIncrement] + public int Id { get; set; } + + [Required, References(typeof(Employee))] + public int EmployeeId { get; set; } + [Reference] + public Employee Employee { get; set; } + + public bool? IsApproved { get; set; } + + [References(typeof(Employee))] + public int? ApprovedById { get; set; } + [Reference] + public Employee ApprovedBy { get; set; } + } + + public class MergeTests + { + [Test] + public void Can_merge_optional_self_references() + { + var timesheet = new TimeSheet + { + Id = 1, + EmployeeId = 2, + ApprovedById = 3 + }; + + var employees = 4.Times(i => new Employee { Id = i, Name = "Employee " + i }); + + timesheet.Merge(employees); + + timesheet.PrintDump(); + + Assert.That(timesheet.Employee.Id, Is.EqualTo(2)); + Assert.That(timesheet.ApprovedBy.Id, Is.EqualTo(3)); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/MetaDataTests.cs b/tests/ServiceStack.OrmLite.Tests/MetaDataTests.cs new file mode 100644 index 000000000..ad31c4443 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/MetaDataTests.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.OrmLite.Tests.UseCase; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class MetaDataTests : OrmLiteProvidersTestBase + { + public MetaDataTests(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void OneTimeSetup() + { + if (DialectFeatures.SchemaSupport) + { + using var db = OpenDbConnection(); + db.CreateSchema(); + } + } + + [Test] + public void Can_get_TableNames() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new TableMetadata1 {Id = i + 1, Field1 = $"Field{i+1}"}) ); + 1.Times(i => db.Insert(new TableMetadata2 {Id = i + 1, Field2 = $"Field{i+1}"}) ); + + var tableNames = db.GetTableNames(); + tableNames.TextDump().Print(); + Assert.That(tableNames.Count, Is.GreaterThan(0)); + var table1Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata1).GetModelMetadata()); + Assert.That(tableNames.Any(x => x.EqualsIgnoreCase(table1Name))); + var table2Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata2).GetModelMetadata()); + Assert.That(tableNames.Any(x => x.EqualsIgnoreCase(table2Name))); + } + + [Test] + public async Task Can_get_TableNames_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new TableMetadata1 {Id = i + 1, Field1 = $"Field{i+1}"}) ); + 1.Times(i => db.Insert(new TableMetadata2 {Id = i + 1, Field2 = $"Field{i+1}"}) ); + + var tableNames = await db.GetTableNamesAsync(); + tableNames.TextDump().Print(); + Assert.That(tableNames.Count, Is.GreaterThan(0)); + var table1Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata1).GetModelMetadata()); + Assert.That(tableNames.Any(x => x.EqualsIgnoreCase(table1Name))); + var table2Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata2).GetModelMetadata()); + Assert.That(tableNames.Any(x => x.EqualsIgnoreCase(table2Name))); + } + + [Test] + public void Can_get_TableNames_in_Schema() + { + var schema = "Schema"; + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new Schematable1 {Id = i + 1, Field1 = $"Field{i+1}"}) ); + 1.Times(i => db.Insert(new Schematable2 {Id = i + 1, Field2 = $"Field{i+1}"}) ); + + var tableNames = db.GetTableNames(schema); + tableNames.TextDump().Print(); + Assert.That(tableNames.Count, Is.GreaterThan(0)); + Assert.That(tableNames.Any(x => x.IndexOf(nameof(Schematable1), StringComparison.OrdinalIgnoreCase) >= 0)); + Assert.That(tableNames.Any(x => x.IndexOf(nameof(Schematable2), StringComparison.OrdinalIgnoreCase) >= 0)); + } + + int IndexOf(List> tableResults, Func, bool> fn) + { + for (int i = 0; i < tableResults.Count; i++) + { + if (fn(tableResults[i])) + return i; + } + return -1; + } + + [Test] + public void Can_get_GetTableNamesWithRowCounts() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new TableMetadata1 {Id = i + 1, Field1 = $"Field{i+1}"}) ); + 1.Times(i => db.Insert(new TableMetadata2 {Id = i + 1, Field2 = $"Field{i+1}"}) ); + + var tableNames = db.GetTableNamesWithRowCounts(live:true); + tableNames.TextDump().Print(); + Assert.That(tableNames.Count, Is.GreaterThan(0)); + + var table1Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata1).GetModelMetadata()); + var table2Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata2).GetModelMetadata()); + + var table1Pos = IndexOf(tableNames, x => x.Key.EqualsIgnoreCase(table1Name) && x.Value == 3); + Assert.That(table1Pos, Is.GreaterThanOrEqualTo(0)); + + var table2Pos = IndexOf(tableNames, x => x.Key.EqualsIgnoreCase(table2Name) && x.Value == 1); + Assert.That(table2Pos, Is.GreaterThanOrEqualTo(0)); + + Assert.That(table1Pos < table2Pos); //is sorted desc + + tableNames = db.GetTableNamesWithRowCounts(live:false); + Assert.That(tableNames.Any(x => x.Key.EqualsIgnoreCase(table1Name))); + Assert.That(tableNames.Any(x => x.Key.EqualsIgnoreCase(table2Name))); + } + + [Test] + public void Can_get_GetTableNamesWithRowCounts_of_keyword_table() + { + using var db = OpenDbConnection(); + CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table + db.CreateTable(); + + 3.Times(i => db.Insert(new Order { CustomerId = i + 1, LineItem = $"Field{i+1}"}) ); + + var tableNames = db.GetTableNamesWithRowCounts(live:true); + Assert.That(tableNames.Count, Is.GreaterThan(0)); + + var table1Name = db.GetDialectProvider().GetTableName(typeof(Order).GetModelMetadata()).StripDbQuotes(); + + var table1Pos = IndexOf(tableNames, x => x.Key.EqualsIgnoreCase(table1Name) && x.Value == 3); + Assert.That(table1Pos, Is.GreaterThanOrEqualTo(0)); + + tableNames = db.GetTableNamesWithRowCounts(live:false); + Assert.That(tableNames.Any(x => x.Key.EqualsIgnoreCase(table1Name))); + } + + [Test] + public async Task Can_get_GetTableNamesWithRowCounts_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new TableMetadata1 {Id = i + 1, Field1 = $"Field{i+1}"}) ); + 1.Times(i => db.Insert(new TableMetadata2 {Id = i + 1, Field2 = $"Field{i+1}"}) ); + + var tableNames = await db.GetTableNamesWithRowCountsAsync(live:true); + tableNames.TextDump().Print(); + Assert.That(tableNames.Count, Is.GreaterThan(0)); + + var table1Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata1).GetModelMetadata()); + var table2Name = db.GetDialectProvider().GetTableName(typeof(TableMetadata2).GetModelMetadata()); + + var table1Pos = IndexOf(tableNames, x => x.Key.EqualsIgnoreCase(table1Name) && x.Value == 3); + Assert.That(table1Pos, Is.GreaterThanOrEqualTo(0)); + + var table2Pos = IndexOf(tableNames, x => x.Key.EqualsIgnoreCase(table2Name) && x.Value == 1); + Assert.That(table2Pos, Is.GreaterThanOrEqualTo(0)); + + Assert.That(table1Pos < table2Pos); //is sorted desc + + tableNames = await db.GetTableNamesWithRowCountsAsync(live:false); + Assert.That(tableNames.Any(x => x.Key.EqualsIgnoreCase(table1Name))); + Assert.That(tableNames.Any(x => x.Key.EqualsIgnoreCase(table2Name))); + } + + [Test] + public void Can_get_GetTableNamesWithRowCounts_in_Schema() + { + var schema = "Schema"; + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + 3.Times(i => db.Insert(new Schematable1 {Id = i + 1, Field1 = $"Field{i+1}"}) ); + 1.Times(i => db.Insert(new Schematable2 {Id = i + 1, Field2 = $"Field{i+1}"}) ); + + var tableNames = db.GetTableNamesWithRowCounts(live:true,schema:schema); + tableNames.TextDump().Print(); + Assert.That(tableNames.Count, Is.GreaterThan(0)); + + var table1Name = db.GetDialectProvider().GetTableName(typeof(Schematable1).GetModelMetadata()).LastRightPart('.').StripDbQuotes(); + var table2Name = db.GetDialectProvider().GetTableName(typeof(Schematable2).GetModelMetadata()).LastRightPart('.').StripDbQuotes(); + + var table1Pos = IndexOf(tableNames, x => x.Key.IndexOf(table1Name, StringComparison.OrdinalIgnoreCase) >=0 && x.Value == 3); + Assert.That(table1Pos, Is.GreaterThanOrEqualTo(0)); + + var table2Pos = IndexOf(tableNames, x => x.Key.IndexOf(table2Name, StringComparison.OrdinalIgnoreCase) >=0 && x.Value == 1); + Assert.That(table2Pos, Is.GreaterThanOrEqualTo(0)); + + Assert.That(table1Pos < table2Pos); //is sorted desc + + tableNames = db.GetTableNamesWithRowCounts(live:true,schema:schema); + Assert.That(tableNames.Any(x => x.Key.IndexOf(table1Name, StringComparison.OrdinalIgnoreCase) >= 0)); + Assert.That(tableNames.Any(x => x.Key.IndexOf(table2Name, StringComparison.OrdinalIgnoreCase) >= 0)); + } + } + + public class TableMetadata1 + { + public int Id { get; set; } + public string String { get; set; } + public string Field1 { get; set; } + } + public class TableMetadata2 + { + public int Id { get; set; } + public string String { get; set; } + public string Field2 { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/MockAllApiTests.cs b/tests/ServiceStack.OrmLite.Tests/MockAllApiTests.cs index f2e607ecd..36e4a49b6 100644 --- a/tests/ServiceStack.OrmLite.Tests/MockAllApiTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/MockAllApiTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Service Stack LLC. All Rights Reserved. +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt @@ -11,13 +11,14 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class MockAllApiTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class MockAllApiTests : OrmLiteProvidersTestBase { + public MockAllApiTests(DialectContext context) : base(context) {} + private IDbConnection db; - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { db = base.OpenDbConnection(); @@ -26,8 +27,8 @@ public void TestFixtureSetUp() db.InsertAll(Person.Rockstars); } - [TestFixtureTearDown] - public void TestFixtureTearDown() + [OneTimeTearDown] + public new void TestFixtureTearDown() { db.Dispose(); } @@ -43,7 +44,6 @@ public void Can_mock_all_Select_Apis() }) { Assert.That(db.Select(x => x.Age > 40)[0].FirstName, Is.EqualTo("Mocked")); - Assert.That(db.Select(q => q.Where(x => x.Age > 40))[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.Select(db.From().Where(x => x.Age > 40))[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.Select("Age > 40")[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.Select("SELECT * FROM Person WHERE Age > 40")[0].FirstName, Is.EqualTo("Mocked")); @@ -51,8 +51,6 @@ public void Can_mock_all_Select_Apis() Assert.That(db.Select("SELECT * FROM Person WHERE Age > @age", new { age = 40 })[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.Select("Age > @age", new Dictionary { { "age", 40 } })[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.Select("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } })[0].FirstName, Is.EqualTo("Mocked")); - Assert.That(db.SelectFmt("Age > {0}", 40)[0].FirstName, Is.EqualTo("Mocked")); - Assert.That(db.SelectFmt("SELECT * FROM Person WHERE Age > {0}", 40)[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.Where("Age", 27)[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.Where(new { Age = 27 })[0].FirstName, Is.EqualTo("Mocked")); Assert.That(db.SelectByIds(new[] { 1, 2, 3 })[0].FirstName, Is.EqualTo("Mocked")); @@ -66,14 +64,11 @@ public void Can_mock_all_Select_Apis() Assert.That(db.Single(db.From().Where(x => x.Age == 42)).FirstName, Is.EqualTo("Mocked")); Assert.That(db.Single(new { Age = 42 }).FirstName, Is.EqualTo("Mocked")); Assert.That(db.Single("Age = @age", new { age = 42 }).FirstName, Is.EqualTo("Mocked")); - Assert.That(db.SingleFmt("Age = {0}", 42).FirstName, Is.EqualTo("Mocked")); Assert.That(db.SingleById(1).FirstName, Is.EqualTo("Mocked")); Assert.That(db.SingleWhere("Age", 42).FirstName, Is.EqualTo("Mocked")); Assert.That(db.Exists(new { Age = 42 }), Is.True); Assert.That(db.Exists("SELECT * FROM Person WHERE Age = @age", new { age = 42 }), Is.True); - Assert.That(db.ExistsFmt("Age = {0}", 42), Is.True); - Assert.That(db.ExistsFmt("SELECT * FROM Person WHERE Age = {0}", 42), Is.True); } } @@ -132,9 +127,11 @@ public void Can_mock_Apis_with_FilterFns() public void Can_trace_all_generated_sql() { var sqlStatements = new List(); + var sqlCommandStatements = new List(); using (new OrmLiteResultsFilter { SqlFilter = sql => sqlStatements.Add(sql), + SqlCommandFilter = sql => sqlCommandStatements.Add(new SqlCommandDetails(sql)), ResultsFn = (dbCmd, type) => new[] { new Person { Id = 1, FirstName = "Mocked", LastName = "Person", Age = 100 } }, SingleResultFn = (dbCmd, type) => new Person { Id = 1, FirstName = "MockedSingle", LastName = "Person", Age = 100 }, ScalarResultFn = (dbCmd, type) => 1000, @@ -145,9 +142,12 @@ public void Can_trace_all_generated_sql() Assert.That(db.Single(x => x.Age == 42).FirstName, Is.EqualTo("MockedSingle")); Assert.That(db.Scalar(x => Sql.Max(x.Age)), Is.EqualTo(1000)); + + Assert.That(sqlStatements.Count, Is.EqualTo(3)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(3)); sqlStatements.Each(x => x.Print()); - Assert.That(sqlStatements.Count, Is.EqualTo(3)); + sqlCommandStatements.Each(x => x.PrintDump()); } } @@ -164,7 +164,6 @@ public void Can_mock_all_Single_Apis() Assert.That(db.Single(db.From().Where(x => x.Age == 42)).FirstName, Is.EqualTo("Mocked")); Assert.That(db.Single(new { Age = 42 }).FirstName, Is.EqualTo("Mocked")); Assert.That(db.Single("Age = @age", new { age = 42 }).FirstName, Is.EqualTo("Mocked")); - Assert.That(db.SingleFmt("Age = {0}", 42).FirstName, Is.EqualTo("Mocked")); Assert.That(db.SingleById(1).FirstName, Is.EqualTo("Mocked")); Assert.That(db.SingleWhere("Age", 42).FirstName, Is.EqualTo("Mocked")); } @@ -182,7 +181,6 @@ public void Can_mock_all_Scalar_Apis() Assert.That(db.Scalar(x => Sql.Max(x.Age)), Is.EqualTo(1000)); Assert.That(db.Scalar(x => Sql.Max(x.Age), x => x.Age < 50), Is.EqualTo(1000)); Assert.That(db.Scalar("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }), Is.EqualTo(1000)); - Assert.That(db.ScalarFmt("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40), Is.EqualTo(1000)); Assert.That(db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }), Is.EqualTo(1000)); Assert.That(db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }), Is.EqualTo(1000)); @@ -199,7 +197,6 @@ public void Can_mock_all_Column_Apis() }) { Assert.That(db.Column("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 })[0], Is.EqualTo("Mock1")); - Assert.That(db.ColumnFmt("SELECT LastName FROM Person WHERE Age = {0}", 27)[0], Is.EqualTo("Mock1")); Assert.That(db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 })[0], Is.EqualTo("Mock1")); Assert.That(db.SqlColumn("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } })[0], Is.EqualTo("Mock1")); } @@ -215,7 +212,6 @@ public void Can_mock_all_ColumnDistinct_Apis() }) { Assert.That(db.ColumnDistinct("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }).Count, Is.EqualTo(3)); - Assert.That(db.ColumnDistinctFmt("SELECT Age FROM Person WHERE Age < {0}", 50).Count, Is.EqualTo(3)); } } @@ -229,7 +225,6 @@ public void Can_mock_all_Dictionary_Apis() }) { Assert.That(db.Dictionary("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 })[1], Is.EqualTo("MockValue")); - Assert.That(db.DictionaryFmt("SELECT Id, LastName FROM Person WHERE Age < {0}", 50)[1], Is.EqualTo("MockValue")); } } @@ -248,12 +243,10 @@ public void Can_mock_all_Update_Apis() Assert.That(db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"), Is.EqualTo(10)); Assert.That(db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"), Is.EqualTo(10)); Assert.That(db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"), Is.EqualTo(10)); - Assert.That(db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName), Is.EqualTo(10)); - Assert.That(db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"), Is.EqualTo(10)); - Assert.That(db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName)), Is.EqualTo(10)); - Assert.That(db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")), Is.EqualTo(10)); - Assert.That(db.UpdateFmt(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")), Is.EqualTo(10)); - Assert.That(db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")), Is.EqualTo(10)); + Assert.That(db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName), Is.EqualTo(10)); + Assert.That(db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"), Is.EqualTo(10)); + Assert.That(db.UpdateOnlyFields(new Person { FirstName = "JJ", LastName = "Hendo" }, db.From().Update(p => p.FirstName)), Is.EqualTo(10)); + Assert.That(db.UpdateOnlyFields(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")), Is.EqualTo(10)); } } @@ -271,13 +264,10 @@ public void Can_mock_all_Delete_Apis() Assert.That(db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 }), Is.EqualTo(10)); Assert.That(db.DeleteById(1), Is.EqualTo(10)); Assert.That(db.DeleteByIds(new[] { 1, 2, 3 }), Is.EqualTo(10)); - Assert.That(db.DeleteFmt("Age = {0}", 27), Is.EqualTo(10)); - Assert.That(db.DeleteFmt(typeof(Person), "Age = {0}", 27), Is.EqualTo(10)); + Assert.That(db.Delete("Age = @age", new { age = 27 }), Is.EqualTo(10)); + Assert.That(db.Delete(typeof(Person), "Age = @age", new { age = 27 }), Is.EqualTo(10)); Assert.That(db.Delete(p => p.Age == 27), Is.EqualTo(10)); - Assert.That(db.Delete(ev => ev.Where(p => p.Age == 27)), Is.EqualTo(10)); Assert.That(db.Delete(db.From().Where(p => p.Age == 27)), Is.EqualTo(10)); - Assert.That(db.DeleteFmt(where: "Age = {0}".SqlFmt(27)), Is.EqualTo(10)); - Assert.That(db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(27)), Is.EqualTo(10)); } } @@ -299,7 +289,7 @@ public void Can_mock_all_CustomSql_Apis() Assert.That(db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }), Is.EqualTo(1000)); Assert.That(db.SqlScalar("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }), Is.EqualTo(1000)); - Assert.That(db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7)), Is.EqualTo(10)); + Assert.That(db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt(DialectProvider, "WaterHouse", 7)), Is.EqualTo(10)); Assert.That(db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }), Is.EqualTo(10)); } } @@ -311,26 +301,30 @@ public void Can_hijack_all_Insert_Apis() //we count the number of sql statements generated instead. var sqlStatements = new List(); + var sqlCommandStatements = new List(); using (new OrmLiteResultsFilter { SqlFilter = sql => sqlStatements.Add(sql), + SqlCommandFilter = sql => sqlCommandStatements.Add(new SqlCommandDetails(sql)), }) { int i = 0; i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); - i++; db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); - Assert.That(sqlStatements.Count, Is.EqualTo(i)); - i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => ev.Insert(p => new { p.FirstName, p.Age })); + i++; db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); - i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => db.From().Insert(p => new { p.FirstName, p.Age })); + i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, p => new { p.FirstName, p.Age }); Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); sqlStatements.Each(x => x.Print()); + sqlCommandStatements.Each(x => x.PrintDump()); } } @@ -342,32 +336,41 @@ public void Can_hijack_Save_Apis() //we count the number of sql statements generated instead. var sqlStatements = new List(); + var sqlCommandStatements = new List(); using (new OrmLiteResultsFilter { SingleResult = new Person { Id = 1, FirstName = "Mocked", LastName = "Person", Age = 100 }, SqlFilter = sql => sqlStatements.Add(sql), + SqlCommandFilter = sql => sqlCommandStatements.Add(new SqlCommandDetails(sql)), }) { int i = 0; //Force Insert by returning null for existingRow - using (new OrmLiteResultsFilter { SqlFilter = sql => sqlStatements.Add(sql) }) + using (new OrmLiteResultsFilter { + SqlFilter = sql => sqlStatements.Add(sql), + SqlCommandFilter = sql => sqlCommandStatements.Add(new SqlCommandDetails(sql)) + }) { i += 2; db.Save(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); //1 Read + 1 Insert } i += 2; db.Save(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); //1 Read + 1 Update Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); i += 3; db.SaveAll(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); //1 Read + 2 Update Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); sqlStatements.Each(x => x.Print()); + sqlCommandStatements.Each(x => x.PrintDump()); } } [Test] + [IgnoreDialect(Tests.Dialect.AnyOracle, "This seems wrong here as the save actually goes through to the database in Oracle to get the next number from the sequence")] public void Can_hijack_References_Apis() { var customer = new Customer @@ -388,9 +391,11 @@ public void Can_hijack_References_Apis() }; var sqlStatements = new List(); + var sqlCommandStatements = new List(); using (new OrmLiteResultsFilter - { + { SqlFilter = sql => sqlStatements.Add(sql), + SqlCommandFilter = sql => sqlCommandStatements.Add(new SqlCommandDetails(sql)), SingleResult = customer, RefSingleResultFn = (dbCmd, refType) => customer.PrimaryAddress, RefResultsFn = (dbCmd, refType) => customer.Orders, @@ -401,18 +406,20 @@ public void Can_hijack_References_Apis() i += 2; db.Save(customer); Assert.That(sqlStatements.Count, Is.EqualTo(i)); - SuppressIfOracle("This seems wrong here as the save actually goes through to the database in Oracle to get the next number from the sequence"); - i += 1; db.SaveReferences(customer, customer.PrimaryAddress); Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); i += 2; db.SaveReferences(customer, customer.Orders); Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); i += 3; var dbCustomer = db.LoadSingleById(customer.Id); Assert.That(sqlStatements.Count, Is.EqualTo(i)); + Assert.That(sqlCommandStatements.Count, Is.EqualTo(i)); sqlStatements.Each(x => x.Print()); + sqlCommandStatements.Each(x => x.PrintDump()); } } diff --git a/tests/ServiceStack.OrmLite.Tests/MultipleConnectionIdTests.cs b/tests/ServiceStack.OrmLite.Tests/MultipleConnectionIdTests.cs index 40104b11b..438eb167a 100644 --- a/tests/ServiceStack.OrmLite.Tests/MultipleConnectionIdTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/MultipleConnectionIdTests.cs @@ -8,14 +8,16 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class MultipleConnectionIdTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class MultipleConnectionIdTests : OrmLiteProvidersTestBase { + public MultipleConnectionIdTests(DialectContext context) : base(context) {} + private int _waitingThreadCount; private int _waitingThreadsReleasedCounter; - [SetUp] - public void SetUp() + [OneTimeSetUp] + public void OneTimeSetUp() { using (var db = OpenDbConnection()) { @@ -24,10 +26,9 @@ public void SetUp() } [Test] + [IgnoreDialect(Dialect.Sqlite, "doesn't support concurrent writers")] public void TwoSimultaneousInsertsGetDifferentIds() { - if (Dialect == Dialect.Sqlite) return; // Sqlite doesn't support concurrent writers - var dataArray = new[] { new MultipleConnection {Data = "one"}, @@ -37,10 +38,12 @@ public void TwoSimultaneousInsertsGetDifferentIds() var originalExecFilter = OrmLiteConfig.ExecFilter; try { - OrmLiteConfig.ExecFilter = new PostExecuteActionExecFilter(originalExecFilter, cmd => PauseForOtherThreadsAfterInserts(cmd, 2)); - - Parallel.ForEach(dataArray, data => - { + OrmLiteConfig.ExecFilter = new PostExecuteActionExecFilter( + originalExecFilter, + cmd => PauseForOtherThreadsAfterInserts(cmd, 2), + DialectProvider); + + Parallel.ForEach(dataArray, data => { using (var db = OpenDbConnection()) { data.Id = db.Insert(new MultipleConnection {Data = data.Data}, selectIdentity: true); @@ -59,7 +62,7 @@ public void TwoSimultaneousInsertsGetDifferentIds() private void PauseForOtherThreadsAfterInserts(IDbCommand cmd, int numberOfThreads) { - if (!cmd.CommandText.StartsWith("INSERT ", StringComparison.InvariantCultureIgnoreCase)) + if (!cmd.CommandText.StartsWith("INSERT ", StringComparison.OrdinalIgnoreCase)) return; var initialReleasedCounter = _waitingThreadsReleasedCounter; @@ -83,10 +86,9 @@ private void PauseForOtherThreadsAfterInserts(IDbCommand cmd, int numberOfThread } [Test] + [IgnoreDialect(Dialect.Sqlite, "doesn't support concurrent writers")] public void TwoSimultaneousSavesGetDifferentIds() { - if (Dialect == Dialect.Sqlite) return; // Sqlite doesn't support concurrent writers - var dataArray = new[] { new MultipleConnection {Data = "one"}, @@ -96,7 +98,10 @@ public void TwoSimultaneousSavesGetDifferentIds() var originalExecFilter = OrmLiteConfig.ExecFilter; try { - OrmLiteConfig.ExecFilter = new PostExecuteActionExecFilter(originalExecFilter, cmd => PauseForOtherThreadsAfterInserts(cmd, 2)); + OrmLiteConfig.ExecFilter = new PostExecuteActionExecFilter( + originalExecFilter, + cmd => PauseForOtherThreadsAfterInserts(cmd, 2), + DialectProvider); Parallel.ForEach(dataArray, data => { @@ -116,31 +121,33 @@ public void TwoSimultaneousSavesGetDifferentIds() Assert.That(dataArray[1].Id, Is.Not.EqualTo(dataArray[0].Id)); } - private class PostExecuteActionExecFilter : IOrmLiteExecFilter + private class PostExecuteActionExecFilter : IOrmLiteExecFilter, IHasDialectProvider { - private readonly IOrmLiteExecFilter _inner; - private readonly Action _postExecuteAction; + private readonly IOrmLiteExecFilter inner; + private readonly Action postExecuteAction; + public IOrmLiteDialectProvider DialectProvider { get; } - public PostExecuteActionExecFilter(IOrmLiteExecFilter inner, Action postExecuteAction) + public PostExecuteActionExecFilter(IOrmLiteExecFilter inner, Action postExecuteAction, IOrmLiteDialectProvider dialectProvider) { - _inner = inner; - _postExecuteAction = postExecuteAction; + this.inner = inner; + this.postExecuteAction = postExecuteAction; + this.DialectProvider = dialectProvider; } public SqlExpression SqlExpression(IDbConnection dbConn) { - return _inner.SqlExpression(dbConn); + return inner.SqlExpression(dbConn); } public IDbCommand CreateCommand(IDbConnection dbConn) { - var innerCommand = _inner.CreateCommand(dbConn); - return new PostExcuteActionCommand(innerCommand, _postExecuteAction); + var innerCommand = inner.CreateCommand(dbConn); + return new PostExecuteActionCommand(innerCommand, postExecuteAction, DialectProvider); } public void DisposeCommand(IDbCommand dbCmd, IDbConnection dbConn) { - _inner.DisposeCommand(dbCmd, dbConn); + inner.DisposeCommand(dbCmd, dbConn); } public T Exec(IDbConnection dbConn, Func filter) @@ -226,104 +233,103 @@ public IEnumerable ExecLazy(IDbConnection dbConn, Func _postExecuteAction; + private readonly IDbCommand inner; + private readonly Action postExecuteAction; + public IOrmLiteDialectProvider DialectProvider { get; } - public PostExcuteActionCommand(IDbCommand inner, Action postExecuteAction) + public PostExecuteActionCommand(IDbCommand inner, Action postExecuteAction, IOrmLiteDialectProvider dialectProvider) { - _inner = inner; - _postExecuteAction = postExecuteAction; + this.inner = inner; + this.postExecuteAction = postExecuteAction; + this.DialectProvider = dialectProvider; } public void Dispose() { - _inner.Dispose(); + inner.Dispose(); } public void Prepare() { - _inner.Prepare(); + inner.Prepare(); } public void Cancel() { - _inner.Cancel(); + inner.Cancel(); } public IDbDataParameter CreateParameter() { - return _inner.CreateParameter(); + return inner.CreateParameter(); } public int ExecuteNonQuery() { - var result = _inner.ExecuteNonQuery(); - _postExecuteAction(this); + var result = inner.ExecuteNonQuery(); + postExecuteAction(this); return result; } public IDataReader ExecuteReader() { - var result = _inner.ExecuteReader(); - _postExecuteAction(this); + var result = inner.ExecuteReader(); + postExecuteAction(this); return result; } public IDataReader ExecuteReader(CommandBehavior behavior) { - var result = _inner.ExecuteReader(behavior); - _postExecuteAction(this); + var result = inner.ExecuteReader(behavior); + postExecuteAction(this); return result; } public object ExecuteScalar() { - var result = _inner.ExecuteScalar(); - _postExecuteAction(this); + var result = inner.ExecuteScalar(); + postExecuteAction(this); return result; } public IDbConnection Connection { - get { return _inner.Connection; } - set { _inner.Connection = value; } + get => inner.Connection; + set => inner.Connection = value; } public IDbTransaction Transaction { - get { return _inner.Transaction; } - set { _inner.Transaction = value; } + get => inner.Transaction; + set => inner.Transaction = value; } public string CommandText { - get { return _inner.CommandText; } - set { _inner.CommandText = value; } + get => inner.CommandText; + set => inner.CommandText = value; } public int CommandTimeout { - get { return _inner.CommandTimeout; } - set { _inner.CommandTimeout = value; } + get => inner.CommandTimeout; + set => inner.CommandTimeout = value; } public CommandType CommandType { - get { return _inner.CommandType; } - set { _inner.CommandType = value; } + get => inner.CommandType; + set => inner.CommandType = value; } - public IDataParameterCollection Parameters - { - get { return _inner.Parameters; } - } + public IDataParameterCollection Parameters => inner.Parameters; public UpdateRowSource UpdatedRowSource { - get { return _inner.UpdatedRowSource; } - set { _inner.UpdatedRowSource = value; } + get => inner.UpdatedRowSource; + set => inner.UpdatedRowSource = value; } } } diff --git a/tests/ServiceStack.OrmLite.Tests/Net6TypeTests.cs b/tests/ServiceStack.OrmLite.Tests/Net6TypeTests.cs new file mode 100644 index 000000000..5af10a3bb --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Net6TypeTests.cs @@ -0,0 +1,78 @@ +using System; +using System.Data; +using System.Linq; +using NUnit.Framework; + +#if NET6_0 +namespace ServiceStack.OrmLite.Tests +{ + + public class Net6TypeTests : OrmLiteTestBase + { + private class DateOnlyObject + { + public DateOnly Test { get; set; } + public DateOnly? TestNullable { get; set; } + } + + private static DateOnlyObject InsertAndSelectDateOnly(IDbConnection db, DateOnly dateTime) + { + db.DeleteAll(); + db.Insert(new DateOnlyObject { Test = dateTime, TestNullable = dateTime }); + var x = db.Select().First(); + return x; + } + + [Test] + public void Can_insert_and_query_DateOnly() + { + // OrmLiteUtils.PrintSql(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + DateOnly dateTime; + DateOnlyObject x; + + dateTime = new DateOnly(2013, 1, 13); + x = InsertAndSelectDateOnly(db, dateTime); + Assert.That(x.Test, Is.EqualTo(dateTime)); + Assert.That(x.TestNullable!.Value, Is.EqualTo(x.Test)); + x = db.Select(d => d.Test == dateTime).FirstOrDefault(); + Assert.That(x, Is.Not.Null); + } + + private class TimeOnlyObject + { + public TimeOnly Test { get; set; } + public TimeOnly? TestNullable { get; set; } + } + + private static TimeOnlyObject InsertAndSelectTimeOnly(IDbConnection db, TimeOnly timeOnly) + { + db.DeleteAll(); + db.Insert(new TimeOnlyObject { Test = timeOnly, TestNullable = timeOnly }); + var x = db.Select().First(); + return x; + } + + [Test] + public void Can_insert_and_query_TimeOnly() + { + OrmLiteUtils.PrintSql(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + TimeOnly timeOnly; + TimeOnlyObject x; + + timeOnly = new TimeOnly(13, 14, 15); + x = InsertAndSelectTimeOnly(db, timeOnly); + Assert.That(x.Test, Is.EqualTo(timeOnly)); + Assert.That(x.TestNullable!.Value, Is.EqualTo(x.Test)); + x = db.Select(d => d.Test == timeOnly).FirstOrDefault(); + Assert.That(x, Is.Not.Null); + } + + } +} +#endif \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/NetCoreTestsRunner.cs b/tests/ServiceStack.OrmLite.Tests/NetCoreTestsRunner.cs new file mode 100644 index 000000000..bacfc348c --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/NetCoreTestsRunner.cs @@ -0,0 +1,68 @@ +//NUnitLite isn't recognized in VS2017 - shouldn't need NUnitLite with NUnit 3.5+ https://github.com/nunit/dotnet-test-nunit +#if NUNITLITE +using NUnitLite; +using NUnit.Common; +using System.Reflection; +using ServiceStack; +using ServiceStack.Text; +using System; +using System.Globalization; +using System.Threading; + +namespace ServiceStack.OrmLite.Tests +{ + public class NetCoreTestsRunner + { + /// + /// The main program executes the tests. Output may be routed to + /// various locations, depending on the arguments passed. + /// + /// Run with --help for a full list of arguments supported + /// + public static int Main(string[] args) + { + var licenseKey = Environment.GetEnvironmentVariable("SERVICESTACK_LICENSE"); + if (licenseKey.IsNullOrEmpty()) + throw new ArgumentNullException("SERVICESTACK_LICENSE", "Add Environment variable for SERVICESTACK_LICENSE"); + + Licensing.RegisterLicense(licenseKey); + //"ActivatedLicenseFeatures: ".Print(LicenseUtils.ActivatedLicenseFeatures()); + + var sqlServerBuildDb = Environment.GetEnvironmentVariable("SQL_SERVER_BUILD_DB"); + + if (!String.IsNullOrEmpty(sqlServerBuildDb)) + { + TestConfig.SqlServerBuildDb = sqlServerBuildDb; + TestConfig.DefaultConnection = TestConfig.SqlServerBuildDb; + } + + var postgreSqlDb = Environment.GetEnvironmentVariable("POSTGRESQL_DB"); + + if (!String.IsNullOrEmpty(postgreSqlDb)) + { + TestConfig.PostgreSqlDb = postgreSqlDb; + } + + var dialect = Environment.GetEnvironmentVariable("ORMLITE_DIALECT"); + + if (!String.IsNullOrEmpty(dialect)) + { + Dialect defaultDialect; + + if (Enum.TryParse(dialect, out defaultDialect)) + TestConfig.DefaultDialect = defaultDialect; + + } + + Console.WriteLine($"Dialect: {TestConfig.DefaultDialect}"); + + CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); + JsConfig.InitStatics(); + + //JsonServiceClient client = new JsonServiceClient(); + var writer = new ExtendedTextWrapper(Console.Out); + return new AutoRun(((IReflectableType)typeof(NetCoreTestsRunner)).GetTypeInfo().Assembly).Execute(args, writer, Console.In); + } + } +} +#endif diff --git a/tests/ServiceStack.OrmLite.Tests/OrderByTests.cs b/tests/ServiceStack.OrmLite.Tests/OrderByTests.cs new file mode 100644 index 000000000..a9466c774 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/OrderByTests.cs @@ -0,0 +1,108 @@ +using System; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.Expression; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class OrderByTests : OrmLiteProvidersTestBase + { + public OrderByTests(DialectContext context) : base(context) {} + + [Test] + public void Can_order_by_random() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + 10.Times(i => db.Insert(new LetterFrequency { Letter = ('A' + i).ToString() })); + + var rowIds1 = db.Select(db.From().OrderBy(x => x.Id)).Map(x => x.Id); + var rowIds2 = db.Select(db.From().OrderBy(x => x.Id)).Map(x => x.Id); + + Assert.That(rowIds1.SequenceEqual(rowIds2)); + + rowIds1 = db.Select(db.From().OrderByRandom()).Map(x => x.Id); + rowIds2 = db.Select(db.From().OrderByRandom()).Map(x => x.Id); + + Assert.That(!rowIds1.SequenceEqual(rowIds2)); + } + + [Test] + public void Can_OrderBy_and_ThenBy() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new LetterFrequency {Letter = "C" }); + db.Insert(new LetterFrequency {Letter = "C" }); + db.Insert(new LetterFrequency {Letter = "B" }); + db.Insert(new LetterFrequency {Letter = "A" }); + + var q = db.From(); + q.OrderBy(nameof(LetterFrequency.Letter)) + .ThenBy(nameof(LetterFrequency.Id)); + + var tracks = db.Select(q); + + Assert.That(tracks.First().Letter, Is.EqualTo("A")); + Assert.That(tracks.Last().Letter, Is.EqualTo("C")); + } + + [Test] + public void Can_OrderBy_multi_table_expression() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var letters = "A,B,C,D,E".Split(','); + var i = 0; + letters.Each(letter => { + var id = db.Insert(new LetterFrequency {Letter = letter}, selectIdentity: true); + db.Insert(new LetterWeighting {LetterFrequencyId = id, Weighting = ++i * 10}); + }); + + var q = db.From() + .Join() + .OrderBy((f, w) => f.Id > w.Weighting ? f.Id : w.Weighting); + + var results = db.Select(q); + } + + [Test] + public void Can_OrderByFields() + { + using var db = OpenDbConnection(); + var d = db.GetDialectProvider(); + Assert.That(OrmLiteUtils.OrderByFields(d,"a").NormalizeQuotes(), Is.EqualTo("'a'")); + Assert.That(OrmLiteUtils.OrderByFields(d,"a,b").NormalizeQuotes(), Is.EqualTo("'a', 'b'")); + Assert.That(OrmLiteUtils.OrderByFields(d,"-a,b").NormalizeQuotes(), Is.EqualTo("'a' desc, 'b'")); + Assert.That(OrmLiteUtils.OrderByFields(d,"a,-b").NormalizeQuotes(), Is.EqualTo("'a', 'b' desc")); + } + + [Test] + public void Can_Multi_OrderBy_AliasValue() + { + using var db = OpenDbConnection(); + + db.DropAndCreateTable(); + var items = 5.Times(x => new LetterFrequency { + Letter = $"{'A' + x}", + Value = x + 1 + }); + db.InsertAll(items); + + OrmLiteUtils.PrintSql(); + var q = db.From(); + q.OrderBy(x => new { x.Value }); + // q.OrderBy(x => x.Value); + var results = db.Select(q); + + Assert.That(results.Map(x => x.Value), Is.EqualTo(new[]{ 1, 2, 3, 4, 5})); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteBasicPersistenceProviderTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteBasicPersistenceProviderTests.cs index 75b120e2d..066494cd9 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteBasicPersistenceProviderTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteBasicPersistenceProviderTests.cs @@ -5,104 +5,105 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteBasicPersistenceProviderTests - : OrmLiteTestBase - { - [Test] - public void Can_GetById_from_basic_persistence_provider() - { + [TestFixtureOrmLite] + public class OrmLiteBasicPersistenceProviderTests : OrmLiteProvidersTestBase + { + public OrmLiteBasicPersistenceProviderTests(DialectContext context) : base(context) {} + + [Test] + public void Can_GetById_from_basic_persistence_provider() + { using (var db = OpenDbConnection()) - { - db.CreateTable(true); + { + db.CreateTable(true); - var basicProvider = new OrmLitePersistenceProvider(db); + var basicProvider = new OrmLitePersistenceProvider(db); - var row = ModelWithFieldsOfDifferentTypes.Create(1); + var row = ModelWithFieldsOfDifferentTypes.Create(1); - row.Id = (int)db.Insert(row, selectIdentity: true); + row.Id = (int)db.Insert(row, selectIdentity: true); - var providerRow = basicProvider.GetById(row.Id); + var providerRow = basicProvider.GetById(row.Id); - ModelWithFieldsOfDifferentTypes.AssertIsEqual(providerRow, row); - } - } + ModelWithFieldsOfDifferentTypes.AssertIsEqual(providerRow, row); + } + } - [Test] - public void Can_GetByIds_from_basic_persistence_provider() - { + [Test] + public void Can_GetByIds_from_basic_persistence_provider() + { using (var db = OpenDbConnection()) - { - db.CreateTable(true); + { + db.CreateTable(true); - var basicProvider = new OrmLitePersistenceProvider(db); + var basicProvider = new OrmLitePersistenceProvider(db); - var rowIds = new List { 1, 2, 3, 4, 5 }; + var rowIds = new List { 1, 2, 3, 4, 5 }; - var rows = rowIds.ConvertAll(ModelWithFieldsOfDifferentTypes.Create); + var rows = rowIds.ConvertAll(ModelWithFieldsOfDifferentTypes.Create); rows.ForEach(x => { x.Id = (int)db.Insert(x, selectIdentity: true); }); - var getRowIds = new[] { rows[1].Id, rows[3].Id }; - var providerRows = basicProvider.GetByIds(getRowIds).ToList(); - var providerRowIds = providerRows.ConvertAll(x => x.Id); + var getRowIds = new[] { rows[1].Id, rows[3].Id }; + var providerRows = basicProvider.GetByIds(getRowIds).ToList(); + var providerRowIds = providerRows.ConvertAll(x => x.Id); - Assert.That(providerRowIds, Is.EquivalentTo(getRowIds)); - } - } + Assert.That(providerRowIds, Is.EquivalentTo(getRowIds)); + } + } - [Test] - public void Can_Store_from_basic_persistence_provider() - { + [Test] + public void Can_Store_from_basic_persistence_provider() + { using (var db = OpenDbConnection()) - { - db.CreateTable(true); + { + db.CreateTable(true); - var basicProvider = new OrmLitePersistenceProvider(db); + var basicProvider = new OrmLitePersistenceProvider(db); - var rowIds = new List { 1, 2, 3, 4, 5 }; + var rowIds = new List { 1, 2, 3, 4, 5 }; - var rows = rowIds.ConvertAll(ModelWithFieldsOfDifferentTypes.Create); + var rows = rowIds.ConvertAll(ModelWithFieldsOfDifferentTypes.Create); - rows.ForEach(x => basicProvider.Store(x)); + rows.ForEach(x => basicProvider.Store(x)); - var getRowIds = new[] { rows[1].Id, rows[3].Id }; - var providerRows = db.SelectByIds(getRowIds).ToList(); - var providerRowIds = providerRows.ConvertAll(x => x.Id); + var getRowIds = new[] { rows[1].Id, rows[3].Id }; + var providerRows = db.SelectByIds(getRowIds).ToList(); + var providerRowIds = providerRows.ConvertAll(x => x.Id); - Assert.That(providerRowIds, Is.EquivalentTo(getRowIds)); - } - } + Assert.That(providerRowIds, Is.EquivalentTo(getRowIds)); + } + } - [Test] - public void Can_Delete_from_basic_persistence_provider() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + [Test] + public void Can_Delete_from_basic_persistence_provider() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); - var basicProvider = new OrmLitePersistenceProvider(db); + var basicProvider = new OrmLitePersistenceProvider(db); - var rowIds = new List { 1, 2, 3, 4, 5 }; + var rowIds = new List { 1, 2, 3, 4, 5 }; - var rows = rowIds.ConvertAll(ModelWithFieldsOfDifferentTypes.Create); + var rows = rowIds.ConvertAll(ModelWithFieldsOfDifferentTypes.Create); rows.ForEach(x => { x.Id = (int)db.Insert(x, selectIdentity: true); }); - var deleteRowIds = new List { rows[1].Id, rows[3].Id }; - var getRowIds = rows.ConvertAll(x => x.Id); + var deleteRowIds = new List { rows[1].Id, rows[3].Id }; + var getRowIds = rows.ConvertAll(x => x.Id); rows.Where(row => deleteRowIds.Contains(row.Id)).ToList().ForEach(basicProvider.Delete); - var providerRows = basicProvider.GetByIds(getRowIds).ToList(); - var providerRowIds = providerRows.ConvertAll(x => x.Id); + var providerRows = basicProvider.GetByIds(getRowIds).ToList(); + var providerRowIds = providerRows.ConvertAll(x => x.Id); - var remainingIds = rows.ConvertAll(x => x.Id); - deleteRowIds.ForEach(x => remainingIds.Remove(x)); + var remainingIds = rows.ConvertAll(x => x.Id); + deleteRowIds.ForEach(x => remainingIds.Remove(x)); - Assert.That(providerRowIds, Is.EquivalentTo(remainingIds)); - } - } + Assert.That(providerRowIds, Is.EquivalentTo(remainingIds)); + } + } - } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteComplexTypesTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteComplexTypesTests.cs index e776c6fcf..4fb245152 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteComplexTypesTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteComplexTypesTests.cs @@ -3,75 +3,79 @@ using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.DataAnnotations; +using ServiceStack.Logging; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { using System.Collections.Generic; - [TestFixture] - public class OrmLiteComplexTypesTests - : OrmLiteTestBase - { - [Test] - public void Can_insert_into_ModelWithComplexTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var row = ModelWithComplexTypes.Create(1); - - db.Insert(row); - } - } - - [Test] - public void Can_insert_and_select_from_ModelWithComplexTypes_table() - { + [TestFixtureOrmLite] + public class OrmLiteComplexTypesTests : OrmLiteProvidersTestBase + { + public OrmLiteComplexTypesTests(DialectContext context) : base(context) {} + + [Test] + public void Can_insert_into_ModelWithComplexTypes_table() + { using (var db = OpenDbConnection()) - { - db.CreateTable(true); + { + db.CreateTable(true); + + var row = ModelWithComplexTypes.Create(1); - var row = ModelWithComplexTypes.Create(1); + db.Insert(row); + } + } + + [Test] + public void Can_insert_and_select_from_ModelWithComplexTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); - db.Insert(row); + var row = ModelWithComplexTypes.Create(1); - var rows = db.Select(); + db.Insert(row); - Assert.That(rows, Has.Count.EqualTo(1)); + var rows = db.Select(); - ModelWithComplexTypes.AssertIsEqual(rows[0], row); - } - } + Assert.That(rows, Has.Count.EqualTo(1)); - [Test] - public void Can_insert_and_select_from_OrderLineData() - { + ModelWithComplexTypes.AssertIsEqual(rows[0], row); + } + } + + [Test] + public void Can_insert_and_select_from_OrderLineData() + { using (var db = OpenDbConnection()) - { - db.CreateTable(true); + { + db.CreateTable(true); - var orderIds = new[] { 1, 2, 3, 4, 5 }.ToList(); + var orderIds = new[] { 1, 2, 3, 4, 5 }.ToList(); - orderIds.ForEach(x => db.Insert( - SampleOrderLine.Create(Guid.NewGuid(), x, 1))); + orderIds.ForEach(x => db.Insert( + SampleOrderLine.Create(Guid.NewGuid(), x, 1))); - var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(orderIds.Count)); - } - } + var rows = db.Select(); + Assert.That(rows, Has.Count.EqualTo(orderIds.Count)); + } + } - [Test] - public void Lists_Of_Guids_Are_Formatted_Correctly() - { + [Test] + public void Lists_Of_Guids_Are_Formatted_Correctly() + { + LogManager.LogFactory = new ConsoleLogFactory(); using (var db = OpenDbConnection()) { db.DropAndCreateTable(); JsConfig.RawSerializeFn = x => x.ToString(); - var item = new WithAListOfGuids { + var item = new WithAListOfGuids + { GuidOne = new Guid("32cb0acb-db43-4061-a6aa-7f4902a7002a"), GuidTwo = new Guid("13083231-b005-4ff4-ab62-41bdc7f50a4d"), TheGuids = new[] { new Guid("18176030-7a1c-4288-82df-a52f71832381"), new Guid("017f986b-f7be-4b6f-b978-ff05fba3b0aa") }, @@ -79,19 +83,19 @@ public void Lists_Of_Guids_Are_Formatted_Correctly() db.Insert(item); - var tbl = "WithAListOfGuids".SqlTable(); - var savedGuidOne = db.Select("SELECT {0} FROM {1}".Fmt("GuidOne".SqlColumn(), tbl)).First(); + var tbl = "WithAListOfGuids".SqlTable(DialectProvider); + var savedGuidOne = db.Select("SELECT {0} FROM {1}".Fmt("GuidOne".SqlColumn(DialectProvider), tbl)).First(); Assert.That(savedGuidOne, Is.EqualTo(new Guid("32cb0acb-db43-4061-a6aa-7f4902a7002a"))); - var savedGuidTwo = db.Select("SELECT {0} FROM {1}".Fmt("GuidTwo".SqlColumn(), tbl)).First(); + var savedGuidTwo = db.Select("SELECT {0} FROM {1}".Fmt("GuidTwo".SqlColumn(DialectProvider), tbl)).First(); Assert.That(savedGuidTwo, Is.EqualTo(new Guid("13083231-b005-4ff4-ab62-41bdc7f50a4d"))); - var savedGuidList = db.Select("SELECT {0} FROM {1}".Fmt("TheGuids".SqlColumn(), tbl)).First(); + var savedGuidList = db.Select("SELECT {0} FROM {1}".Fmt("TheGuids".SqlColumn(DialectProvider), tbl)).First(); Assert.That(savedGuidList, Is.EqualTo("[18176030-7a1c-4288-82df-a52f71832381,017f986b-f7be-4b6f-b978-ff05fba3b0aa]")); JsConfig.Reset(); } - } + } [Test] public void Can_insert_Contact_with_Complex_NameDetail() @@ -102,8 +106,8 @@ public void Can_insert_Contact_with_Complex_NameDetail() var contact = new Contact { - FullName = new NameDetail("Sinad", "O'Connor"), - Email = "Sinad@O'Connor.com", + FullName = new NameDetail("Sinéad", "O'Connor"), + Email = "Sinéad@O'Connor.com", Age = 10 }; db.Save(contact); diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteConnectionFactoryTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteConnectionFactoryTests.cs index c7c2bb294..61756f094 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteConnectionFactoryTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteConnectionFactoryTests.cs @@ -34,8 +34,7 @@ public void AutoDispose_ConnectionFactory_disposes_connection() [Test] public void NonAutoDispose_ConnectionFactory_reuses_connection() { - OrmLiteConfig.DialectProvider = SqliteDialect.Provider; - var factory = new OrmLiteConnectionFactory(":memory:") + var factory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider) { AutoDisposeConnection = false, }; @@ -81,9 +80,9 @@ public class Person [Test] public void Can_open_multiple_nested_connections() { - var factory = new OrmLiteConnectionFactory(Config.SqliteMemoryDb, SqliteDialect.Provider); - factory.RegisterConnection("sqlserver", Config.SqlServerBuildDb, SqlServerDialect.Provider); - factory.RegisterConnection("sqlite-file", Config.SqliteFileDb, SqliteDialect.Provider); + var factory = new OrmLiteConnectionFactory(SqliteDb.MemoryConnection, SqliteDialect.Provider); + factory.RegisterConnection("sqlserver", $"{SqlServerDb.DefaultConnection};Connection Timeout=1", SqlServerDialect.Provider); + factory.RegisterConnection("sqlite-file", SqliteDb.FileConnection, SqliteDialect.Provider); var results = new List(); using (var db = factory.OpenDbConnection()) @@ -119,9 +118,9 @@ public void Can_open_multiple_nested_connections() [Test] public void Can_open_multiple_nested_connections_in_any_order() { - var factory = new OrmLiteConnectionFactory(Config.SqliteMemoryDb, SqliteDialect.Provider); - factory.RegisterConnection("sqlserver", Config.SqlServerBuildDb, SqlServerDialect.Provider); - factory.RegisterConnection("sqlite-file", Config.SqliteFileDb, SqliteDialect.Provider); + var factory = new OrmLiteConnectionFactory(SqliteDb.MemoryConnection, SqliteDialect.Provider); + factory.RegisterConnection("sqlserver", $"{SqlServerDb.DefaultConnection};Connection Timeout=1", SqlServerDialect.Provider); + factory.RegisterConnection("sqlite-file", SqliteDb.FileConnection, SqliteDialect.Provider); var results = new List(); using (var db = factory.OpenDbConnection()) @@ -155,7 +154,6 @@ public void Can_open_multiple_nested_connections_in_any_order() Assert.AreEqual(new[] { 3, 4, 5, 6, 1, 2 }, ids); } - [Test] public void Can_open_after_close_connection() { @@ -175,19 +173,58 @@ public void Can_open_after_close_connection() public void Can_open_different_ConnectionString_with_DbFactory() { var factory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider); + using var db = factory.OpenDbConnection(); + Assert.That(db.State, Is.EqualTo(ConnectionState.Open)); + Assert.That(db.ConnectionString, Is.EqualTo(":memory:")); + + var dbFilePath = "~/db.sqlite".MapAbsolutePath(); + using var dbFile = factory.OpenDbConnectionString(dbFilePath); + Assert.That(dbFile.State, Is.EqualTo(ConnectionState.Open)); + Assert.That(dbFile.ConnectionString, Is.EqualTo(dbFilePath)); + } + + [Test] + public void Can_open_different_ConnectionString_with_DbFactory_DataSource() + { + var factory = new OrmLiteConnectionFactory("DataSource=:memory:", SqliteDialect.Provider); + using var db = factory.OpenDbConnection(); + Assert.That(db.State, Is.EqualTo(ConnectionState.Open)); + Assert.That(db.ConnectionString, Is.EqualTo(":memory:")); + + var dbFilePath = "~/db.sqlite".MapAbsolutePath(); + using var dbFile = factory.OpenDbConnectionString(dbFilePath); + Assert.That(dbFile.State, Is.EqualTo(ConnectionState.Open)); + Assert.That(dbFile.ConnectionString, Is.EqualTo(dbFilePath)); + } + + [Test] + public void Can_register_ConnectionFilter_on_named_connections() + { + var factory = new OrmLiteConnectionFactory(SqliteDb.MemoryConnection, SqliteDialect.Provider); + factory.RegisterConnection("sqlserver", $"{SqlServerDb.DefaultConnection};Connection Timeout=1", SqlServerDialect.Provider); + factory.RegisterConnection("sqlite-file", SqliteDb.FileConnection, SqliteDialect.Provider); + + int filterCount = 0; + + factory.ConnectionFilter = db => { filterCount++; return db; }; + using (var db = factory.OpenDbConnection()) { - Assert.That(db.State, Is.EqualTo(ConnectionState.Open)); - Assert.That(db.ConnectionString, Is.EqualTo(":memory:")); + Assert.That(filterCount, Is.EqualTo(1)); + + using (var db2 = factory.OpenDbConnection("sqlserver")) {} - var dbFilePath = "~/db.sqlite".MapAbsolutePath(); - using (var dbFile = factory.OpenDbConnectionString(dbFilePath)) + Assert.That(filterCount, Is.EqualTo(1)); + + OrmLiteConnectionFactory.NamedConnections.Values.Each(f => f.ConnectionFilter = x => { filterCount++; return x; }); + + using (var db2 = factory.OpenDbConnection("sqlserver")) { - Assert.That(dbFile.State, Is.EqualTo(ConnectionState.Open)); - Assert.That(dbFile.ConnectionString, Is.EqualTo(dbFilePath)); + using (var db3 = factory.OpenDbConnection("sqlite-file")) {} } } - } + Assert.That(filterCount, Is.EqualTo(3)); + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteContextTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteContextTests.cs index 62b87a302..eba2436b6 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteContextTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteContextTests.cs @@ -1,14 +1,16 @@ using System.Threading; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteContextTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteContextTests : OrmLiteProvidersTestBase { + public OrmLiteContextTests(DialectContext context) : base(context) {} + [Test] public void Can_set_and_get_TS_ContextItems() { @@ -19,8 +21,7 @@ public void Can_set_and_get_TS_ContextItems() [Test] public void Can_override_timeout_for_specific_command() { - base.DbFactory.AutoDisposeConnection = true; //Turn off :memory: re-use of dbConn - + DbFactory.AutoDisposeConnection = true; //Turn off :memory: re-use of dbConn OrmLiteConfig.CommandTimeout = 100; using (var db = OpenDbConnection()) @@ -28,7 +29,7 @@ public void Can_override_timeout_for_specific_command() db.DropAndCreateTable(); db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); - db.SetCommandTimeout(666); + db.SetCommandTimeout(200); "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); @@ -45,7 +46,7 @@ public void Can_override_timeout_for_specific_command() "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); db.Insert(new Poco { Name = "Foo" }); - db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(666))); + db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(200))); } using (var db = OpenDbConnection()) @@ -55,6 +56,39 @@ public void Can_override_timeout_for_specific_command() db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); } } - } + [Test] + public async Task Can_override_timeout_for_specific_command_Async() + { + DbFactory.AutoDisposeConnection = true; //Turn off :memory: re-use of dbConn + + OrmLiteConfig.CommandTimeout = 100; + + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); + + db.SetCommandTimeout(666); + + "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); + + ThreadPool.QueueUserWorkItem(_ => { + using var dbInner = OpenDbConnection(); + "inner {0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); + dbInner.SetCommandTimeout(1); + }); + Thread.Sleep(10); + + "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); + + await db.InsertAsync(new Poco { Name = "Foo" }); + db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(666))); + + using var db2 = await OpenDbConnectionAsync(); + db2.CreateTableIfNotExists(); //Sqlite :memory: AutoDisposeConnection = true + (await db2.SelectAsync()).PrintDump(); + db2.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); + } + + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableTests.cs index 135bf95a1..11295eaa9 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableTests.cs @@ -9,10 +9,11 @@ namespace ServiceStack.OrmLite.Tests { using ServiceStack.DataAnnotations; - [TestFixture] - public class OrmLiteCreateTableTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteCreateTableTests : OrmLiteProvidersTestBase { + public OrmLiteCreateTableTests(DialectContext context) : base(context) {} + [Test] public void Does_table_Exists() { @@ -21,13 +22,13 @@ public void Does_table_Exists() db.DropTable(); Assert.That( - db.TableExists(typeof(ModelWithIdOnly).Name.SqlTableRaw()), + db.TableExists(nameof(ModelWithIdOnly).SqlTableRaw(DialectProvider)), Is.False); db.CreateTable(true); Assert.That( - db.TableExists(typeof(ModelWithIdOnly).Name.SqlTableRaw()), + db.TableExists(nameof(ModelWithIdOnly).SqlTableRaw(DialectProvider)), Is.True); } } @@ -143,21 +144,59 @@ public void Can_create_multiple_tables() } } + [Test] + public void Can_change_schema_definitions() + { + using (var db = OpenDbConnection()) + { + var insertDate = new DateTime(2014, 1, 1); + + db.DropAndCreateTable(); + var before = db.GetLastSql(); + + var idA = db.Insert(new AuditTableA { CreatedDate = insertDate }, selectIdentity: true); + var insertRowA = db.SingleById(idA); + Assert.That(insertRowA.CreatedDate, Is.EqualTo(insertDate)); + + var stringConverter = DialectProvider.GetStringConverter(); + var hold = stringConverter.UseUnicode; + stringConverter.UseUnicode = true; + + db.DropAndCreateTable(); + db.GetLastSql().Print(); + + stringConverter.UseUnicode = hold; + + db.DropAndCreateTable(); + var after = db.GetLastSql(); + + Assert.That(after, Is.EqualTo(before)); + + idA = db.Insert(new AuditTableA { CreatedDate = insertDate }, selectIdentity: true); + insertRowA = db.SingleById(idA); + Assert.That(insertRowA.CreatedDate, Is.EqualTo(insertDate)); + } + } + [Test] public void Can_create_ModelWithIdAndName_table_with_specified_DefaultStringLength() { - OrmLiteConfig.DialectProvider.DefaultStringLength = 255; - var createTableSql = OrmLiteConfig.DialectProvider.ToCreateTableStatement(typeof(ModelWithIdAndName)); + var converter = DialectProvider.GetStringConverter(); + var hold = converter.StringLength; + converter.StringLength = 255; + var createTableSql = DialectProvider.ToCreateTableStatement(typeof(ModelWithIdAndName)); Console.WriteLine("createTableSql: " + createTableSql); - if (Dialect != Dialect.PostgreSql) + if ((Dialect & Dialect.AnyPostgreSql) != Dialect) { - Assert.That(createTableSql, Is.StringContaining("VARCHAR(255)").Or.StringContaining("VARCHAR2(255)")); + Assert.That(createTableSql, Does.Contain("VARCHAR(255)"). + Or.Contain("VARCHAR2(255)")); } else { - Assert.That(createTableSql, Is.StringContaining("text")); + Assert.That(createTableSql, Does.Contain("TEXT")); } + converter.StringLength = hold; } public class ModelWithGuid @@ -175,9 +214,9 @@ public void Can_handle_table_with_Guid() db.GetLastSql().Print(); - var models = new[] { - new ModelWithGuid { Id = 1, Guid = Guid.NewGuid() }, - new ModelWithGuid { Id = 2, Guid = Guid.NewGuid() } + var models = new[] { + new ModelWithGuid { Id = 1, Guid = Guid.NewGuid() }, + new ModelWithGuid { Id = 2, Guid = Guid.NewGuid() } }; db.SaveAll(models); @@ -189,6 +228,12 @@ public void Can_handle_table_with_Guid() newModel = db.Single(q => q.Guid == models[0].Guid); Assert.That(newModel.Guid, Is.EqualTo(models[0].Guid)); + + var newGuid = Guid.NewGuid(); + db.Update(new ModelWithGuid {Id = models[0].Id, Guid = newGuid}); + db.GetLastSql().Print(); + newModel = db.Single(q => q.Id == models[0].Id); + Assert.That(newModel.Guid, Is.EqualTo(newGuid)); } } @@ -210,12 +255,16 @@ public void Can_handle_table_with_non_conventional_id() db.GetLastSql().Print(); - db.Insert(new ModelWithOddIds { Id = 1, Guid = Guid.NewGuid() }); + var guid1 = Guid.NewGuid(); + db.Insert(new ModelWithOddIds { Id = 1, Guid = guid1 }); db.Insert(new ModelWithOddIds { Id = 1, Guid = Guid.NewGuid() }); var rows = db.Select(q => q.Id == 1); Assert.That(rows.Count, Is.EqualTo(2)); + + rows = db.Select(q => q.Guid == guid1); + Assert.That(rows, Has.Count.EqualTo(1)); } } @@ -277,14 +326,8 @@ public ModelWithIndexer() public Object this[string attributeName] { - get - { - return Attributes[attributeName]; - } - set - { - Attributes[attributeName] = value; - } + get => Attributes[attributeName]; + set => Attributes[attributeName] = value; } Dictionary Attributes { get; set; } @@ -371,5 +414,75 @@ public void Can_create_and_join_on_Tables_with_Base_classes() Assert.That(results.Count, Is.EqualTo(1)); } } + + [Test] + public void Does_CreateTableIfNotExists() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + + if (db.CreateTableIfNotExists()) + { + db.Insert(new ModelWithIdOnly(1)); + } + if (db.CreateTableIfNotExists()) + { + db.Insert(new ModelWithIdOnly(2)); + } + var rows = db.Select(); + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].Id, Is.EqualTo(1)); + } + } + + public class TableWithIgnoredFields + { + public int Id { get; set; } + + public string FirstName { get; set; } + + public string LastName { get; set; } + + public string DisplayName + { + get { return FirstName + " " + LastName; } + } + + [DataAnnotations.Ignore] + public int IsIgnored { get; set; } + + public Nested Nested { get; set; } + } + + public class Nested + { + public string Name { get { return "Foo"; } } + } + + [Test] + public void Does_not_create_table_with_ignored_field() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + Assert.That(db.GetLastSql(), Does.Contain("DisplayName".SqlColumnRaw(DialectProvider))); + Assert.That(db.GetLastSql(), Does.Not.Contain("IsIgnored".SqlColumnRaw(DialectProvider))); + + db.Insert(new TableWithIgnoredFields + { + Id = 1, + FirstName = "Foo", + LastName = "Bar", + IsIgnored = 10, + }); + + var row = db.Select()[0]; + + Assert.That(row.DisplayName, Is.EqualTo("Foo Bar")); + Assert.That(row.IsIgnored, Is.EqualTo(0)); + } + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithIndexesTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithIndexesTests.cs index bbf1db3b9..06e2ec0a0 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithIndexesTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithIndexesTests.cs @@ -4,84 +4,133 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteCreateTableWithIndexesTests - : OrmLiteTestBase - { - - [Test] - public void Can_create_ModelWithIndexFields_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + [TestFixtureOrmLite] + public class OrmLiteCreateTableWithIndexesTests : OrmLiteProvidersTestBase + { + public OrmLiteCreateTableWithIndexesTests(DialectContext context) : base(context) {} - var sql = OrmLiteConfig.DialectProvider.ToCreateIndexStatements(typeof(ModelWithIndexFields)).Join(); + [Test] + public void Can_create_ModelWithIndexFields_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); - var indexName = "idx_modelwithindexfields_name"; - var uniqueName = "uidx_modelwithindexfields_uniquename"; + var sql = DialectProvider.ToCreateIndexStatements(typeof(ModelWithIndexFields)).Join(); - if (Dialect == Dialect.Oracle) - { - indexName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName); - uniqueName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(uniqueName); - } + var indexName = "idx_modelwithindexfields_name"; + var uniqueName = "uidx_modelwithindexfields_uniquename"; - Assert.IsTrue(sql.Contains(indexName)); - Assert.IsTrue(sql.Contains(uniqueName)); - } - } + if ((Dialect.AnyOracle | Dialect.Firebird).HasFlag(Dialect)) + { + indexName = DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName); + uniqueName = DialectProvider.NamingStrategy.ApplyNameRestrictions(uniqueName); + } - [Test] - public void Can_create_ModelWithCompositeIndexFields_table() - { - if (Dialect == Dialect.PostgreSql) return; //Incompatible ColumnName in Attribute + Assert.That(sql, Does.Contain(indexName)); + Assert.That(sql, Does.Contain(uniqueName)); + Assert.That(sql, Does.Contain("altname")); + } + } + [Test] + public void Can_create_ModelWithCompositeIndexFields_table() + { using (var db = OpenDbConnection()) - { - db.CreateTable(true); + { + db.CreateTable(true); - var sql = OrmLiteConfig.DialectProvider.ToCreateIndexStatements(typeof(ModelWithCompositeIndexFields)).Join(); + var sql = DialectProvider.ToCreateIndexStatements(typeof(ModelWithCompositeIndexFields)).Join(); var indexName = "idx_modelwithcompositeindexfields_name"; var compositeName = "idx_modelwithcompositeindexfields_composite1_composite2"; - if (Dialect == Dialect.Oracle) + if ((Dialect.AnyOracle | Dialect.Firebird).HasFlag(Dialect)) { - indexName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName); - compositeName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName); + indexName = DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName); + compositeName = DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName); } - Assert.IsTrue(sql.Contains(indexName)); - Assert.IsTrue(sql.Contains(compositeName)); - } - } + Assert.That(sql, Does.Contain(indexName)); + Assert.That(sql, Does.Contain(compositeName)); + } + } [Test] - public void Can_create_ModelWithNamedCompositeIndex_table() + public void Can_create_ModelWithCompositeIndexFieldsDesc_table() { - if (Dialect == Dialect.PostgreSql) return; //Incompatible ColumnName in Attribute + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + db.GetLastSql().Print(); + + var sql = DialectProvider.ToCreateIndexStatements(typeof(ModelWithCompositeIndexFieldsDesc)).Join(); + var indexName = "idx_modelwithcompositeindexfieldsdesc_name"; + var compositeName = "idx_modelwithcompositeindexfieldsdesc_composite1_composite2"; + + if ((Dialect.AnyOracle | Dialect.Firebird).HasFlag(Dialect)) + { + indexName = DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName).ToLower(); + compositeName = DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName).ToLower(); + } + + Assert.That(sql, Does.Contain(indexName)); + Assert.That(sql, Does.Contain(compositeName)); + } + } + + [Test] + [IgnoreDialect(Tests.Dialect.Firebird, "Too long, not supported")] + public void Can_create_ModelWithCompositeIndexOnFieldSpacesDesc_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + db.GetLastSql().Print(); + + var sql = DialectProvider.ToCreateIndexStatements(typeof(ModelWithCompositeIndexOnFieldSpacesDesc)).Join(); + + var compositeName = "idx_modelwithcompositeindexonfieldspacesdesc_field_field"; + + if ((Dialect.AnyOracle | Dialect.Firebird).HasFlag(Dialect)) + compositeName = DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName).ToLower(); + + Assert.That(sql, Does.Contain(compositeName)); + } + } + + [Test] + public void Can_create_ModelWithNamedCompositeIndex_table() + { using (var db = OpenDbConnection()) { db.CreateTable(true); - var sql = OrmLiteConfig.DialectProvider.ToCreateIndexStatements(typeof(ModelWithNamedCompositeIndex)).Join(); + var sql = DialectProvider.ToCreateIndexStatements(typeof(ModelWithNamedCompositeIndex)).Join(); var indexName = "idx_modelwithnamedcompositeindex_name"; var compositeName = "uidx_modelwithnamedcompositeindexfields_composite1_composite2"; - if (Dialect == Dialect.Oracle) + if (Dialect == Dialect.AnyOracle || Dialect == Dialect.Firebird) { - indexName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName); - compositeName = OrmLiteConfig.DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName); + indexName = DialectProvider.NamingStrategy.ApplyNameRestrictions(indexName); + compositeName = DialectProvider.NamingStrategy.ApplyNameRestrictions(compositeName); } - Assert.IsTrue(sql.Contains(indexName)); - Assert.IsTrue(sql.Contains("custom_index_name")); - Assert.IsFalse(sql.Contains(compositeName)); + Assert.That(sql, Does.Contain(indexName)); + Assert.That(sql, Does.Contain("custom_index_name")); + Assert.That(sql, Does.Not.Contain(compositeName)); } } - } + [Test] + public void Can_create_CompositeIndex_with_Enum() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithNamingStrategyTest.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithNamingStrategyTest.cs index 885b780ef..481052321 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithNamingStrategyTest.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteCreateTableWithNamingStrategyTest.cs @@ -1,91 +1,67 @@ using System.Globalization; using NUnit.Framework; using ServiceStack.Common.Tests.Models; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteCreateTableWithNamingStrategyTests - : OrmLiteTestBase - { - private INamingStrategy PreviousNamingStrategy { get; set; } + [TestFixtureOrmLite] + public class OrmLiteCreateTableWithNamingStrategyTests : OrmLiteProvidersTestBase + { + public OrmLiteCreateTableWithNamingStrategyTests(DialectContext context) : base(context) {} - [SetUp] - public void SetUp() + [Test] + public void Can_create_TableWithNamingStrategy_table_prefix() { - PreviousNamingStrategy = OrmLiteConfig.DialectProvider.NamingStrategy; + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } } - [TearDown] - public void TearDown() + [Test] + public void Can_create_TableWithNamingStrategy_table_lowered() { - OrmLiteConfig.DialectProvider.NamingStrategy = PreviousNamingStrategy; + using (new TemporaryNamingStrategy(DialectProvider, new LowercaseNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } } - [Test] - public void Can_create_TableWithNamingStrategy_table_prefix() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix ="tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - [Test] - public void Can_create_TableWithNamingStrategy_table_lowered() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new LowercaseNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } - - - [Test] - public void Can_create_TableWithNamingStrategy_table_nameUnderscoreCoumpound() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new UnderscoreSeparatedCompoundNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - } - } + + [Test] + public void Can_create_TableWithNamingStrategy_table_nameUnderscoreCompound() + { + using (new TemporaryNamingStrategy(DialectProvider, new UnderscoreSeparatedCompoundNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + } + } [Test] public void Can_create_TableWithNamingStrategy_table_aliases() { - var aliasNamingStrategy = new AliasNamingStrategy - { + var aliasNamingStrategy = new AliasNamingStrategy + { TableAliases = { { "ModelWithOnlyStringFields", "TableAlias" } }, ColumnAliases = { { "Name", "ColumnAlias" } }, }; - OrmLiteConfig.DialectProvider.NamingStrategy = aliasNamingStrategy; + using (new TemporaryNamingStrategy(DialectProvider, aliasNamingStrategy)) using (var db = OpenDbConnection()) { - db.CreateTable(true); + db.DropAndCreateTable(); var sql = db.GetLastSql().NormalizeSql(); - Assert.That(sql, Is.StringContaining("CREATE TABLE TableAlias".NormalizeSql())); - Assert.That(sql, Is.StringContaining("ColumnAlias".NormalizeSql())); + Assert.That(sql, Does.Contain("CREATE TABLE TableAlias".NormalizeSql())); + Assert.That(sql, Does.Contain("ColumnAlias".NormalizeSql())); var result = db.SqlList( - "SELECT * FROM {0} WHERE {1} = {2}" - .Fmt("ModelWithOnlyStringFields".SqlTable(), - "Name".SqlColumn(), - "foo".SqlValue())); - + $"SELECT * FROM {"ModelWithOnlyStringFields".SqlTable(DialectProvider)} WHERE {"Name".SqlColumn(DialectProvider)} = 'foo'"); + Assert.That(db.GetLastSql().NormalizeSql(), Is.EqualTo("SELECT * FROM TableAlias WHERE ColumnAlias = 'foo'".NormalizeSql())); @@ -95,211 +71,187 @@ public void Can_create_TableWithNamingStrategy_table_aliases() db.CreateTable(true); sql = db.GetLastSql().NormalizeSql(); - Assert.That(sql, Is.StringContaining("CREATE TABLE table_alias".NormalizeSql())); - Assert.That(sql, Is.StringContaining("column_alias".NormalizeSql())); + Assert.That(sql, Does.Contain("CREATE TABLE table_alias".NormalizeSql())); + Assert.That(sql, Does.Contain("column_alias".NormalizeSql())); } - - OrmLiteConfig.DialectProvider.NamingStrategy = new OrmLiteNamingStrategyBase(); } - [Test] - public void Can_get_data_from_TableWithNamingStrategy_with_GetById() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - var m = new ModelWithOnlyStringFields { Id= "999", AlbumId = "112", AlbumName="ElectroShip", Name = "MyNameIsBatman"}; - - db.Save(m); + [Test] + public void Can_get_data_from_TableWithNamingStrategy_with_GetById() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + var m = new ModelWithOnlyStringFields { Id = "999", AlbumId = "112", AlbumName = "ElectroShip", Name = "MyNameIsBatman" }; + + db.Save(m); var modelFromDb = db.SingleById("999"); - Assert.AreEqual(m.Name, modelFromDb.Name); - } - } - - - [Test] - public void Can_get_data_from_TableWithNamingStrategy_with_query_by_example() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - var m = new ModelWithOnlyStringFields { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - } - } - - [Test] - public void Can_get_data_from_TableWithUnderscoreSeparatedCompoundNamingStrategy_with_ReadConnectionExtension() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new UnderscoreSeparatedCompoundNamingStrategy(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - var m = new ModelWithOnlyStringFields - { - Id = "997", - AlbumId = "112", - AlbumName = "ElectroShip", - Name = "ReadConnectionExtensionFirst" - }; - db.Save(m); + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + + + [Test] + public void Can_get_data_from_TableWithNamingStrategy_with_query_by_example() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + var m = new ModelWithOnlyStringFields { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } + + [Test] + public void Can_get_data_from_TableWithUnderscoreSeparatedCompoundNamingStrategy_with_ReadConnectionExtension() + { + using (new TemporaryNamingStrategy(DialectProvider, new UnderscoreSeparatedCompoundNamingStrategy())) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + var m = new ModelWithOnlyStringFields + { + Id = "997", + AlbumId = "112", + AlbumName = "ElectroShip", + Name = "ReadConnectionExtensionFirst" + }; + db.Save(m); var modelFromDb = db.Single(x => x.Name == "ReadConnectionExtensionFirst"); - Assert.AreEqual(m.AlbumName, modelFromDb.AlbumName); - } + Assert.AreEqual(m.AlbumName, modelFromDb.AlbumName); + } } - - [Test] - public void Can_get_data_from_TableWithNamingStrategy_AfterChangingNamingStrategy() - { - OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - var m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); - modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - - } - - OrmLiteConfig.DialectProvider.NamingStrategy= new OrmLiteNamingStrategyBase(); - - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - var m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - - Assert.AreEqual(m.Name, modelFromDb.Name); + [Test] + public void Can_get_data_from_TableWithNamingStrategy_AfterChangingNamingStrategy() + { + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + var m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + + Assert.AreEqual(m.Name, modelFromDb.Name); modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - } - - OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_", - }; + Assert.AreEqual(m.Name, modelFromDb.Name); + } - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - var m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + var m = new ModelWithOnlyStringFields() { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - db.Save(m); - var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - Assert.AreEqual(m.Name, modelFromDb.Name); + Assert.AreEqual(m.Name, modelFromDb.Name); modelFromDb = db.SingleById("998"); - Assert.AreEqual(m.Name, modelFromDb.Name); - } - } + Assert.AreEqual(m.Name, modelFromDb.Name); + } - } + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + var m = new ModelWithOnlyStringFields { Id = "998", AlbumId = "112", AlbumName = "ElectroShip", Name = "QueryByExample" }; - public class PrefixNamingStrategy : OrmLiteNamingStrategyBase - { + db.Save(m); + var modelFromDb = db.Where(new { Name = "QueryByExample" })[0]; - public string TablePrefix { get; set; } + Assert.AreEqual(m.Name, modelFromDb.Name); - public string ColumnPrefix { get; set; } + modelFromDb = db.SingleById("998"); + Assert.AreEqual(m.Name, modelFromDb.Name); + } + } - public override string GetTableName(string name) - { - return TablePrefix + name; - } + } - public override string GetColumnName(string name) - { - return ColumnPrefix + name; - } + internal class PrefixNamingStrategy : OrmLiteNamingStrategyBase + { - } + public string TablePrefix { get; set; } - public class LowercaseNamingStrategy : OrmLiteNamingStrategyBase - { + public string ColumnPrefix { get; set; } - public override string GetTableName(string name) - { - return name.ToLower(); - } + public override string GetTableName(string name) + { + return TablePrefix + name; + } - public override string GetColumnName(string name) - { - return name.ToLower(); - } + public override string GetColumnName(string name) + { + return ColumnPrefix + name; + } + + } - } + internal class LowercaseNamingStrategy : OrmLiteNamingStrategyBase + { + + public override string GetTableName(string name) + { + return name.ToLower(); + } - public class UnderscoreSeparatedCompoundNamingStrategy : OrmLiteNamingStrategyBase - { + public override string GetColumnName(string name) + { + return name.ToLower(); + } - public override string GetTableName(string name) - { - return toUnderscoreSeparatedCompound(name); - } + } - public override string GetColumnName(string name) - { - return toUnderscoreSeparatedCompound(name); - } + internal class UnderscoreSeparatedCompoundNamingStrategy : OrmLiteNamingStrategyBase + { + public override string GetTableName(string name) + { + return toUnderscoreSeparatedCompound(name); + } - string toUnderscoreSeparatedCompound(string name) - { + public override string GetColumnName(string name) + { + return toUnderscoreSeparatedCompound(name); + } - string r = char.ToLower(name[0]).ToString(CultureInfo.InvariantCulture); - for (int i = 1; i < name.Length; i++) - { - if (char.IsUpper(name[i])) - { - r += "_"; - r += char.ToLower(name[i]); - } - else - { - r += name[i]; - } - } - return r; - } + string toUnderscoreSeparatedCompound(string name) + { +#if NETCORE + string r = char.ToLower(name[0]).ToString(); +#else + string r = char.ToLower(name[0]).ToString(CultureInfo.InvariantCulture); +#endif + for (int i = 1; i < name.Length; i++) + { + if (char.IsUpper(name[i])) + { + r += "_"; + r += char.ToLower(name[i]); + } + else + { + r += name[i]; + } + } + return r; + } - } + } - public class LowerCaseUnderscoreNamingStrategy : OrmLiteNamingStrategyBase + internal class LowerCaseUnderscoreNamingStrategy : OrmLiteNamingStrategyBase { public override string GetTableName(string name) { diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteDeleteTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteDeleteTests.cs index 9303c4378..0a7aad204 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteDeleteTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteDeleteTests.cs @@ -1,23 +1,22 @@ -using System; using System.Collections.Generic; using System.Data; using System.Linq; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.Common.Tests.Models; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteDeleteTests - : OrmLiteTestBase - { + [TestFixtureOrmLite] + public class OrmLiteDeleteTests : OrmLiteProvidersTestBase + { + public OrmLiteDeleteTests(DialectContext context) : base(context) {} + private IDbConnection db; [SetUp] public void SetUp() { - CreateNewDatabase(); db = OpenDbConnection(); db.DropAndCreateTable(); } @@ -28,9 +27,28 @@ public void TearDown() db.Dispose(); } - [Test] - public void Can_Delete_from_ModelWithFieldsOfDifferentTypes_table() - { + [Test] + public void Can_delete_all_rows() + { + var row1 = ModelWithFieldsOfDifferentTypes.Create(1); + var row2 = ModelWithFieldsOfDifferentTypes.Create(2); + var row3 = ModelWithFieldsOfDifferentTypes.Create(3); + + db.Save(row1); + db.Save(row2); + db.Save(row3); + + db.DeleteAll(new[] { row1, row3 }); + + var remaining = db.Select(); + + Assert.That(remaining.Count, Is.EqualTo(1)); + Assert.That(remaining[0].Id, Is.EqualTo(row2.Id)); + } + + [Test] + public void Can_Delete_from_ModelWithFieldsOfDifferentTypes_table() + { var rowIds = new List(new[] { 1, 2, 3 }); for (var i = 0; i < rowIds.Count; i++) @@ -48,9 +66,9 @@ public void Can_Delete_from_ModelWithFieldsOfDifferentTypes_table() Assert.That(dbRowIds, Is.EquivalentTo(new[] { rowIds[0], rowIds[2] })); } - [Test] - public void Can_DeleteById_from_ModelWithFieldsOfDifferentTypes_table() - { + [Test] + public void Can_DeleteById_from_ModelWithFieldsOfDifferentTypes_table() + { var rowIds = new List(new[] { 1, 2, 3 }); for (var i = 0; i < rowIds.Count; i++) @@ -64,9 +82,9 @@ public void Can_DeleteById_from_ModelWithFieldsOfDifferentTypes_table() Assert.That(dbRowIds, Is.EquivalentTo(new[] { rowIds[0], rowIds[2] })); } - [Test] - public void Can_DeleteByIds_from_ModelWithFieldsOfDifferentTypes_table() - { + [Test] + public void Can_DeleteByIds_from_ModelWithFieldsOfDifferentTypes_table() + { db.DropAndCreateTable(); var rowIds = new List(new[] { 1, 2, 3 }); @@ -81,43 +99,15 @@ public void Can_DeleteByIds_from_ModelWithFieldsOfDifferentTypes_table() Assert.That(dbRowIds, Is.EquivalentTo(new[] { rowIds[1] })); } - - [Test] - public void Can_delete_ModelWithFieldsOfDifferentTypes_table_with_filter() - { - var row = ModelWithFieldsOfDifferentTypes.Create(1); - - db.Insert(row); - - db.Delete(x => x.LongId <= row.LongId); - - var dbRow = db.SingleById(row.Id); - - Assert.That(dbRow, Is.Null); - } - - [Test] - public void Can_delete_with_optional_string_params() - { - var row = ModelWithFieldsOfDifferentTypes.Create(1); - - db.Insert(row); - - db.DeleteFmt(where: "LongId".SqlColumn() + " <= {0}".SqlFmt(row.LongId)); - - var dbRow = db.SingleById(row.Id); - - Assert.That(dbRow, Is.Null); - } [Test] - public void Can_delete_with_tableName_and_optional_string_params() + public void Can_delete_ModelWithFieldsOfDifferentTypes_table_with_filter() { var row = ModelWithFieldsOfDifferentTypes.Create(1); db.Insert(row); - db.DeleteFmt(table: "ModelWithFieldsOfDifferentTypes", where: "LongId".SqlColumn() + " <= {0}".SqlFmt(row.LongId)); + db.Delete(x => x.Long <= row.Long); var dbRow = db.SingleById(row.Id); @@ -206,5 +196,39 @@ public void Can_DeleteNonDefaultsAll_entity_with_nullable_DateTime() Assert.That(rows.Count, Is.EqualTo(0)); } + [Test] + public void Can_delete_from_Object_Dictionary() + { + db.DropAndCreateTable(); + db.InsertAll(AutoQueryTests.SeedRockstars); + + var club27 = db.Select(x => x.Age == 27); + Assert.That(club27.Count, Is.GreaterThan(0)); + + db.Delete(new Dictionary { + ["Age"] = 27 + }); + + club27 = db.Select(x => x.Age == 27); + Assert.That(club27.Count, Is.EqualTo(0)); + } + + [Test] + public async Task Can_delete_from_Object_Dictionary_Async() + { + db.DropAndCreateTable(); + await db.InsertAllAsync(AutoQueryTests.SeedRockstars); + + var club27 = await db.SelectAsync(x => x.Age == 27); + Assert.That(club27.Count, Is.GreaterThan(0)); + + await db.DeleteAsync(new Dictionary { + ["Age"] = 27 + }); + + club27 = await db.SelectAsync(x => x.Age == 27); + Assert.That(club27.Count, Is.EqualTo(0)); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableTests.cs index 62617f1e8..3d4d4a04d 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableTests.cs @@ -3,60 +3,57 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteDropTableTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteDropTableTests : OrmLiteProvidersTestBase { + public OrmLiteDropTableTests(DialectContext context) : base(context) {} + [Test] public void Can_drop_existing_table() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(typeof(ModelWithIdOnly)); - db.DropAndCreateTable(); - - Assert.That( - db.TableExists(typeof(ModelWithIdOnly).Name.SqlTableRaw()), - Is.True); - Assert.That( - db.TableExists(typeof(ModelWithIdAndName).Name.SqlTableRaw()), - Is.True); - - db.DropTable(); - db.DropTable(typeof(ModelWithIdAndName)); - - Assert.That( - db.TableExists(typeof(ModelWithIdOnly).Name.SqlTableRaw()), - Is.False); - Assert.That( - db.TableExists(typeof(ModelWithIdAndName).Name.SqlTableRaw()), - Is.False); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(typeof(ModelWithIdOnly)); + db.DropAndCreateTable(); + + Assert.That( + db.TableExists(nameof(ModelWithIdOnly).SqlTableRaw(DialectProvider)), + Is.True); + Assert.That( + db.TableExists(nameof(ModelWithIdAndName).SqlTableRaw(DialectProvider)), + Is.True); + + db.DropTable(); + db.DropTable(typeof(ModelWithIdAndName)); + + Assert.That( + db.TableExists(nameof(ModelWithIdOnly).SqlTableRaw(DialectProvider)), + Is.False); + Assert.That( + db.TableExists(nameof(ModelWithIdAndName).SqlTableRaw(DialectProvider)), + Is.False); } [Test] public void Can_drop_multiple_tables() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTables(typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); - - Assert.That( - db.TableExists(typeof(ModelWithIdOnly).Name.SqlTableRaw()), - Is.True); - Assert.That( - db.TableExists(typeof(ModelWithIdAndName).Name.SqlTableRaw()), - Is.True); - - db.DropTables(typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); - - Assert.That( - db.TableExists(typeof(ModelWithIdOnly).Name.SqlTableRaw()), - Is.False); - Assert.That( - db.TableExists(typeof(ModelWithIdAndName).Name.SqlTableRaw()), - Is.False); - } + using var db = OpenDbConnection(); + db.DropAndCreateTables(typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); + + Assert.That( + db.TableExists(nameof(ModelWithIdOnly).SqlTableRaw(DialectProvider)), + Is.True); + Assert.That( + db.TableExists(nameof(ModelWithIdAndName).SqlTableRaw(DialectProvider)), + Is.True); + + db.DropTables(typeof(ModelWithIdOnly), typeof(ModelWithIdAndName)); + + Assert.That( + db.TableExists(nameof(ModelWithIdOnly).SqlTableRaw(DialectProvider)), + Is.False); + Assert.That( + db.TableExists(nameof(ModelWithIdAndName).SqlTableRaw(DialectProvider)), + Is.False); } } } diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableWithNamingStrategyTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableWithNamingStrategyTests.cs index a54089cdd..f49d9eb1c 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableWithNamingStrategyTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteDropTableWithNamingStrategyTests.cs @@ -3,32 +3,15 @@ namespace ServiceStack.OrmLite.Tests { - public class OrmLiteDropTableWithNamingStrategyTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteDropTableWithNamingStrategyTests : OrmLiteProvidersTestBase { - private INamingStrategy PreviousNamingStrategy { get; set; } - - [SetUp] - public void SetUp() - { - PreviousNamingStrategy = OrmLiteConfig.DialectProvider.NamingStrategy; - } - - [TearDown] - public void TearDown() - { - OrmLiteConfig.DialectProvider.NamingStrategy = PreviousNamingStrategy; - } + public OrmLiteDropTableWithNamingStrategyTests(DialectContext context) : base(context) {} [Test] - public void Can_drop_TableWithNamigStrategy_table_prefix() + public void Can_drop_TableWithNamingStrategy_table_prefix() { - OrmLiteConfig.DialectProvider.NamingStrategy = new PrefixNamingStrategy - { - TablePrefix = "tab_", - ColumnPrefix = "col_" - }; - + using (new TemporaryNamingStrategy(DialectProvider, new PrefixNamingStrategy { TablePrefix = "tab_", ColumnPrefix = "col_" })) using (var db = OpenDbConnection()) { db.CreateTable(true); @@ -42,8 +25,7 @@ public void Can_drop_TableWithNamigStrategy_table_prefix() [Test] public void Can_drop_TableWithNamigStrategy_table_lowered() { - OrmLiteConfig.DialectProvider.NamingStrategy = new LowercaseNamingStrategy(); - + using (new TemporaryNamingStrategy(DialectProvider, new LowercaseNamingStrategy())) using (var db = OpenDbConnection()) { db.CreateTable(true); @@ -58,8 +40,7 @@ public void Can_drop_TableWithNamigStrategy_table_lowered() [Test] public void Can_drop_TableWithNamigStrategy_table_nameUnderscoreCompound() { - OrmLiteConfig.DialectProvider.NamingStrategy = new UnderscoreSeparatedCompoundNamingStrategy(); - + using (new TemporaryNamingStrategy(DialectProvider, new UnderscoreSeparatedCompoundNamingStrategy())) using (var db = OpenDbConnection()) { db.CreateTable(true); diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteExecFilterTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteExecFilterTests.cs index ebff9e070..987264db8 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteExecFilterTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteExecFilterTests.cs @@ -1,10 +1,10 @@ using System; using System.Data; using System.Linq; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.OrmLite.Tests.Shared; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { @@ -12,7 +12,7 @@ public class ReplayOrmLiteExecFilter : OrmLiteExecFilter { public int ReplayTimes { get; set; } - public override T Exec(IDbConnection dbConn, System.Func filter) + public override T Exec(IDbConnection dbConn, Func filter) { var dbCmd = CreateCommand(dbConn); try @@ -33,13 +33,30 @@ public override T Exec(IDbConnection dbConn, System.Func filte public class MockStoredProcExecFilter : OrmLiteExecFilter { - public override T Exec(IDbConnection dbConn, System.Func filter) + public override T Exec(IDbConnection dbConn, Func filter) { try { return base.Exec(dbConn, filter); } - catch (Exception ex) + catch (Exception) + { + var sql = dbConn.GetLastSql(); + if (sql == "exec sp_name @firstName, @age") + { + return (T)(object)new Person { FirstName = "Mocked" }; + } + throw; + } + } + + public override async Task Exec(IDbConnection dbConn, Func> filter) + { + try + { + return await base.Exec(dbConn, filter); + } + catch (Exception) { var sql = dbConn.GetLastSql(); if (sql == "exec sp_name @firstName, @age") @@ -51,17 +68,17 @@ public override T Exec(IDbConnection dbConn, System.Func filte } } - [TestFixture] - public class OrmLiteExecFilterTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteExecFilterTests : OrmLiteProvidersTestBase { + public OrmLiteExecFilterTests(DialectContext context) : base(context) {} + [Test] + [IgnoreDialect(Dialect.AnyOracle, "Can't run this with Oracle until use trigger for AutoIncrement primary key insertion")] public void Can_add_replay_logic() { - SuppressIfOracle("Can't run this with Oracle until use trigger for AutoIncrement primary key insertion"); - - var holdExecFilter = OrmLiteConfig.DialectProvider.ExecFilter; - OrmLiteConfig.DialectProvider.ExecFilter = new ReplayOrmLiteExecFilter { ReplayTimes = 3 }; + var holdExecFilter = DialectProvider.ExecFilter; + DialectProvider.ExecFilter = new ReplayOrmLiteExecFilter { ReplayTimes = 3 }; using (var db = OpenDbConnection()) { @@ -72,24 +89,41 @@ public void Can_add_replay_logic() Assert.That(rowsInserted, Is.EqualTo(3)); } - OrmLiteConfig.DialectProvider.ExecFilter = holdExecFilter; + DialectProvider.ExecFilter = holdExecFilter; } [Test] public void Can_mock_store_procedure() { - var holdExecFilter = OrmLiteConfig.DialectProvider.ExecFilter; - OrmLiteConfig.DialectProvider.ExecFilter = new MockStoredProcExecFilter(); + var holdExecFilter = DialectProvider.ExecFilter; + DialectProvider.ExecFilter = new MockStoredProcExecFilter(); using (var db = OpenDbConnection()) { var person = db.SqlScalar("exec sp_name @firstName, @age", - new {firstName = "aName", age = 1}); + new { firstName = "aName", age = 1 }); Assert.That(person.FirstName, Is.EqualTo("Mocked")); } - OrmLiteConfig.DialectProvider.ExecFilter = holdExecFilter; + DialectProvider.ExecFilter = holdExecFilter; + } + + [Test] + public async Task Can_mock_store_procedure_Async() + { + var holdExecFilter = DialectProvider.ExecFilter; + DialectProvider.ExecFilter = new MockStoredProcExecFilter(); + + using (var db = OpenDbConnection()) + { + var person = await db.SqlScalarAsync("exec sp_name @firstName, @age", + new { firstName = "aName", age = 1 }); + + Assert.That(person.FirstName, Is.EqualTo("Mocked")); + } + + DialectProvider.ExecFilter = holdExecFilter; } [Test] @@ -109,5 +143,26 @@ public void Does_use_StringFilter() OrmLiteConfig.StringFilter = null; } + + [Test] + public void Does_use_StringFilter_on_null_strings() + { + OrmLiteConfig.OnDbNullFilter = fieldDef => + fieldDef.FieldType == typeof(string) + ? "NULL" + : null; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithIdAndName { Name = null }); + var row = db.Select().First(); + + Assert.That(row.Name, Is.EqualTo("NULL")); + } + + OrmLiteConfig.OnDbNullFilter = null; + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteExecuteNonQueryTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteExecuteNonQueryTests.cs index fbb121e84..1d17f7fe2 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteExecuteNonQueryTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteExecuteNonQueryTests.cs @@ -8,11 +8,13 @@ #endregion using - [TestFixture] public class OrmLiteExecuteNonQueryTests { - public class UsingAnonType : OrmLiteTestBase + [TestFixtureOrmLite] + public class WithDbCmdFilter : OrmLiteProvidersTestBase { + public WithDbCmdFilter(DialectContext context) : base(context) {} + [Test] public void Can_insert_one_row_and_get_one_affected_row() { @@ -22,9 +24,12 @@ public void Can_insert_one_row_and_get_one_affected_row() var name = "Jane Doe"; - var affectedRows = db.ExecuteNonQuery("insert into Person (Name) Values (@name);", new { - name - }); + var affectedRows = db.ExecuteNonQuery(Dialect != Dialect.Firebird + ? "insert into Person (Name) Values (@name);" + : "insert into Person (Id, Name) Values (1, @name);", cmd => + { + cmd.AddParam("name", name); + }); var personId = db.Single(q => q.Name == name).Id; @@ -45,16 +50,170 @@ public void Can_insert_multiple_rows_and_get_matching_number_of_affected_rows() var name1 = "Jane Doe"; var name2 = "john Smith"; - var affectedRows = db.ExecuteNonQuery(@" - insert into Person (Name) - Select @name1 - Union - Select @name2", new + int affectedRows = 0; + if (Dialect != Dialect.Firebird) + { + affectedRows = db.ExecuteNonQuery(@" + INSERT INTO Person (Name) + SELECT @name1 + UNION + SELECT @name2", cmd => + { + cmd.AddParam("name1", name1); + cmd.AddParam("name2", name2); + }); + } + else + { + affectedRows = db.ExecuteNonQuery(@" + INSERT INTO Person (Id, Name) + SELECT 1, CAST(@name1 as VARCHAR(128)) FROM RDB$DATABASE + UNION + SELECT 2, CAST(@name2 as VARCHAR(128)) FROM RDB$DATABASE", cmd => + { + cmd.AddParam("name1", name1); + cmd.AddParam("name2", name2); + }); + } + + var rows = db.SqlColumn("select * from Person order by name"); + + Assert.That(affectedRows, Is.EqualTo(2)); + Assert.That(rows[0].Name, Is.EqualTo(name1)); + Assert.That(rows[1].Name, Is.EqualTo(name2)); + + var ids = db.SqlColumn("select Id from Person order by Id"); + Assert.That(ids, Is.EquivalentTo(new[] { 1, 2 })); + } + } + + [Test] + public void Can_update_and_returns_appropriate_number_of_affected_rows() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var person = new Person + { + Name = "Jane Doe" + }; + + var personId = db.Insert(person, selectIdentity: true); + + var newName = "John Smith"; + + var affectedRows = db.ExecuteNonQuery("Update Person Set Name = @newName where Id = @personId", cmd => + { + cmd.AddParam("personId", personId); + cmd.AddParam("newName", newName); + }); + + var updatedPerson = db.SingleById(personId); + + Assert.That(affectedRows, Is.EqualTo(1)); + Assert.That(updatedPerson.Name, Is.EqualTo(newName)); + } + } + + [Test] + public void Can_delete_and_returns_appropriate_number_of_affected_rows() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var person = new Person { - name1, - name2 + Name = "Jane Doe" + }; + + var personId = db.Insert(person, selectIdentity: true); + + var affectedRows = db.ExecuteNonQuery("Delete From Person where Id = @personId", cmd => + { + cmd.AddParam("personId", personId); }); + var count = db.Count(); + + Assert.That(affectedRows, Is.EqualTo(1)); + Assert.That(count, Is.EqualTo(0)); + } + } + + [Test] + public void Can_exec_statement_which_performs_no_changes_and_returns_no_affected_rows() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var affectedRows = db.ExecuteNonQuery(@"Delete From Person Where Id = @nonExistingId", cmd => + { + cmd.AddParam("nonExistingId", -1); + }); + + Assert.That(affectedRows, Is.EqualTo(0)); + } + } + } + + [TestFixtureOrmLite] + public class UsingAnonType : OrmLiteProvidersTestBase + { + public UsingAnonType(DialectContext context) : base(context) {} + + [Test] + public void Can_insert_one_row_and_get_one_affected_row() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var name = "Jane Doe"; + + var affectedRows = db.ExecuteNonQuery(Dialect != Dialect.Firebird + ? "insert into Person (Name) Values (@name);" + : "insert into Person (Id, Name) Values (1, @name);", new { name }); + + var personId = db.Single(q => q.Name == name).Id; + + var insertedRow = db.SingleById(personId); + + Assert.That(affectedRows, Is.EqualTo(1)); + Assert.That(insertedRow.Name, Is.EqualTo(name)); + } + } + + [Test] + public void Can_insert_multiple_rows_and_get_matching_number_of_affected_rows() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var name1 = "Jane Doe"; + var name2 = "john Smith"; + + int affectedRows = 0; + if (Dialect != Dialect.Firebird) + { + affectedRows = db.ExecuteNonQuery(@" + INSERT INTO Person (Name) + SELECT @name1 + UNION + SELECT @name2", new { name1, name2 }); + } + else + { + affectedRows = db.ExecuteNonQuery(@" + INSERT INTO Person (Id, Name) + SELECT 1, CAST(@name1 as VARCHAR(128)) FROM RDB$DATABASE + UNION + SELECT 2, CAST(@name2 as VARCHAR(128)) FROM RDB$DATABASE", new { name1, name2 }); + } + var rows = db.SqlColumn("select * from Person order by name"); Assert.That(affectedRows, Is.EqualTo(2)); @@ -136,8 +295,11 @@ public void Can_exec_statement_which_performs_no_changes_and_returns_no_affected } } - public class UsingDictionary : OrmLiteTestBase + [TestFixtureOrmLite] + public class UsingDictionary : OrmLiteProvidersTestBase { + public UsingDictionary(DialectContext context) : base(context) {} + [Test] public void Can_insert_one_row_and_get_one_affected_row() { @@ -147,10 +309,11 @@ public void Can_insert_one_row_and_get_one_affected_row() var name = "Jane Doe"; - var affectedRows = db.ExecuteNonQuery("insert into Person (Name) Values (@name);", new Dictionary - { - { "name", name } - }); + var affectedRows = db.ExecuteNonQuery(Dialect != Dialect.Firebird + ? "insert into Person (Name) Values (@name);" + : "insert into Person (Id, Name) Values (1, @name);", new Dictionary { + { "name", name } + }); var personId = db.Single(q => q.Name == name).Id; @@ -171,15 +334,30 @@ public void Can_insert_multiple_rows_and_get_matching_number_of_affected_rows() var name1 = "Jane Doe"; var name2 = "john Smith"; - var affectedRows = db.ExecuteNonQuery(@" - insert into Person (Name) - Select @name1 - Union - Select @name2", new Dictionary + int affectedRows; + if (Dialect != Dialect.Firebird) { - { "name1", name1 }, - { "name2", name2 } - }); + affectedRows = db.ExecuteNonQuery(@" + INSERT INTO Person (Name) + SELECT @name1 + UNION + SELECT @name2", new Dictionary { + { "name1", name1 }, + { "name2", name2 } + }); + } + else + { + affectedRows = db.ExecuteNonQuery(@" + INSERT INTO Person (Id, Name) + SELECT 1, CAST(@name1 as VARCHAR(128)) FROM RDB$DATABASE + UNION + SELECT 2, CAST(@name2 as VARCHAR(128)) FROM RDB$DATABASE", + new Dictionary { + { "name1", name1 }, + { "name2", name2 } + }); + } var rows = db.SqlColumn("select * from Person order by name"); @@ -264,8 +442,11 @@ public void Can_exec_statement_which_performs_no_changes_and_returns_no_affected } } - public class WithoutParams : OrmLiteTestBase + [TestFixtureOrmLite] + public class WithoutParams : OrmLiteProvidersTestBase { + public WithoutParams(DialectContext context) : base(context) {} + [Test] public void Can_insert_one_row_and_get_one_affected_row() { @@ -275,11 +456,13 @@ public void Can_insert_one_row_and_get_one_affected_row() var name = "Jane Doe"; - var sql = string.Format("insert into Person (Name) Values ('{0}');", name); + var affectedRows = db.ExecuteNonQuery(Dialect != Dialect.Firebird + ? "insert into Person (Name) Values ('{0}');".Fmt(name) + : "insert into Person (Id, Name) Values (1, '{0}');".Fmt(name)); - var affectedRows = db.ExecuteNonQuery(sql); - - var personId = db.LastInsertId(); + var personId = Dialect != Dialect.Firebird + ? db.LastInsertId() + : 1; var insertedRow = db.SingleById(personId); @@ -298,14 +481,17 @@ public void Can_insert_multiple_rows_and_get_matching_number_of_affected_rows() var name1 = "Jane Doe"; var name2 = "john Smith"; - var sql = string.Format(@"insert into Person (Name) Select '{0}' Union Select '{1}'", name1, name2); + var sql = Dialect != Dialect.Firebird + ? "insert into Person (Name) Select '{0}' Union Select '{1}'".Fmt(name1, name2) + : "insert into Person (Id, Name) Select 1, '{0}' FROM RDB$DATABASE Union Select 2, '{1}' FROM RDB$DATABASE" + .Fmt(name1, name2); var affectedRows = db.ExecuteNonQuery(sql); var rows = db.SqlColumn("select * from Person order by name"); Assert.That(affectedRows, Is.EqualTo(2)); - Assert.That(rows[0].Name, Is.EqualTo(name1)); + Assert.That(rows[0].Name.TrimEnd(), Is.EqualTo(name1)); Assert.That(rows[1].Name, Is.EqualTo(name2)); var ids = db.SqlColumn("select Id from Person order by Id"); diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteFiltersTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteFiltersTests.cs index bb21b66eb..74e857851 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteFiltersTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteFiltersTests.cs @@ -1,6 +1,9 @@ using System; +using System.Collections.Generic; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.DataAnnotations; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { @@ -34,10 +37,11 @@ public class AuditTableB : IAudit public string ModifiedBy { get; set; } } - [TestFixture] - public class OrmLiteFiltersTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteFiltersTests : OrmLiteProvidersTestBase { + public OrmLiteFiltersTests(DialectContext context) : base(context) {} + [Test] public void Does_call_Filters_on_insert_and_update() { @@ -46,8 +50,7 @@ public void Does_call_Filters_on_insert_and_update() OrmLiteConfig.InsertFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null) + if (row is IAudit auditRow) { auditRow.CreatedDate = auditRow.ModifiedDate = insertDate; } @@ -55,8 +58,7 @@ public void Does_call_Filters_on_insert_and_update() OrmLiteConfig.UpdateFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null) + if (row is IAudit auditRow) { auditRow.ModifiedDate = updateDate; } @@ -89,6 +91,33 @@ public void Does_call_Filters_on_insert_and_update() OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = null; } + [Test] + public async Task Does_fire_filters_for_SaveAll() + { + var sbInsert = new List(); + var sbUpdate = new List(); + OrmLiteConfig.InsertFilter = (cmd, o) => sbInsert.Add(cmd.CommandText); + OrmLiteConfig.UpdateFilter = (cmd, o) => sbUpdate.Add(cmd.CommandText); + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + await db.SaveAllAsync(new[] { + new AuditTableA {Id = 1, ModifiedBy = "A1"}, + new AuditTableA {Id = 2, ModifiedBy = "B1"}, + }); + + Assert.That(sbInsert.Count, Is.EqualTo(2)); + + await db.SaveAllAsync(new[] { + new AuditTableA {Id = 1, ModifiedBy = "A2"}, + new AuditTableA {Id = 2, ModifiedBy = "B2"}, + }); + + Assert.That(sbUpdate.Count, Is.EqualTo(2)); + } + } + [Test] public void Does_call_Filters_on_Save() { @@ -97,8 +126,7 @@ public void Does_call_Filters_on_Save() OrmLiteConfig.InsertFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null) + if (row is IAudit auditRow) { auditRow.CreatedDate = auditRow.ModifiedDate = insertDate; } @@ -106,8 +134,7 @@ public void Does_call_Filters_on_Save() OrmLiteConfig.UpdateFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null) + if (row is IAudit auditRow) { auditRow.ModifiedDate = updateDate; } @@ -147,8 +174,7 @@ public void Exceptions_in_filters_prevents_insert_and_update() { OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = (dbCmd, row) => { - var auditRow = row as IAudit; - if (auditRow != null) + if (row is IAudit auditRow) { if (auditRow.ModifiedBy == null) throw new ArgumentNullException("ModifiedBy"); @@ -186,5 +212,28 @@ public void Exceptions_in_filters_prevents_insert_and_update() OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = null; } + [Test] + public void Does_call_UpdateFilter_on_anonymous_Type() + { + var called = false; + OrmLiteConfig.UpdateFilter = (dbCmd, row) => { called = true; }; + + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var a = new AuditTableA(); + var id = db.Insert(a, selectIdentity:true); + + db.Update(new { ModifiedBy = "Updated" }, where: x => x.Id == id); + + Assert.That(db.SingleById(id).ModifiedBy, Is.EqualTo("Updated")); + + Assert.That(called); + } + + OrmLiteConfig.UpdateFilter = null; + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteGetScalarTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteGetScalarTests.cs index 1b27dd719..f045ec7b4 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteGetScalarTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteGetScalarTests.cs @@ -6,9 +6,10 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteGetScalarTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteGetScalarTests : OrmLiteProvidersTestBase { + public OrmLiteGetScalarTests(DialectContext context) : base(context) {} [Test] public void Can_get_scalar_value() @@ -71,7 +72,7 @@ public void Can_get_scalar_value() r2 = db.Scalar( e => Sql.Max(e.LastActivity), e => e.City == "Bogota"); - Assert.That(expectedNullableDate, Is.EqualTo(r2)); + Assert.That(r2, Is.EqualTo(expectedNullableDate)); r2 = db.Scalar(e => Sql.Max(e.LastActivity), e => e.City == "SinCity"); Assert.That(default(DateTime?), Is.EqualTo(r2)); @@ -103,11 +104,11 @@ public void Can_get_scalar_value() var expectedDouble = authors.Max(e => e.DoubleProperty); double r5 = db.Scalar(e => Sql.Max(e.DoubleProperty)); - Assert.That(expectedDouble, Is.EqualTo(r5)); + Assert.That(expectedDouble, Is.EqualTo(r5).Within(.1d)); expectedDouble = authors.Where(e => e.City == "London").Max(e => e.DoubleProperty); r5 = db.Scalar(e => Sql.Max(e.DoubleProperty), e => e.City == "London"); - Assert.That(expectedDouble, Is.EqualTo(r5)); + Assert.That(expectedDouble, Is.EqualTo(r5).Within(.1d)); r5 = db.Scalar(e => Sql.Max(e.DoubleProperty), e => e.City == "SinCity"); Assert.That(default(double), Is.EqualTo(r5)); @@ -160,7 +161,7 @@ public void Can_get_scalar_value() Assert.That(expectedString, Is.EqualTo(r9)); r9 = db.Scalar(e => Sql.Max(e.Name), e => e.City == "SinCity"); - Assert.IsNullOrEmpty(r9); + Assert.That(string.IsNullOrEmpty(r9)); //Can't MIN(bit)/MAX(bit) in SQL Server if (Dialect == Dialect.SqlServer) @@ -207,7 +208,7 @@ public void Can_get_scalar_value() } - public class Author + internal class Author { public Author() { } diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteInsertImageBlobTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteInsertImageBlobTests.cs deleted file mode 100644 index ec24808c8..000000000 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteInsertImageBlobTests.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using NUnit.Framework; -using ServiceStack.OrmLite.SqlServer; -using ServiceStack.OrmLite.Tests.App_Data; -using ServiceStack.OrmLite.Tests.UseCase; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class OrmLiteInsertImageBlobTests - { - private const string ConnectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=BpnCache_Spike;Integrated Security=SSPI;Connect Timeout=120;MultipleActiveResultSets=True"; - - [Test] - public void test_if_ormlite_sql_text_insert_works_for_image_blobs() - { - var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServerOrmLiteDialectProvider.Instance); - - using (var db = dbFactory.OpenDbConnection()) - using (var dbConn = db.CreateCommand()) - { - dbConn.CreateTable(true); - - var dto = new ImageBlobDto() - { - Image1 = ImageToBytes(ImageBlobResource.Bild), - Image2 = ImageToBytes(ImageBlobResource.Bild2), - Image3 = ImageToBytes(ImageBlobResource.Bild3) - }; - - dbConn.Insert(dto); - Assert.Greater(0, dbConn.GetLastInsertId()); - } - } - - [Test] - public void test_if_ormlite_sql_prepare_insert_works_for_image_blobs() - { - var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServerOrmLiteDialectProvider.Instance); - - using (var db = dbFactory.OpenDbConnection()) - using (var dbConn = db.CreateCommand()) - { - dbConn.CreateTable(true); - - var dto = new ImageBlobDto() - { - Image1 = ImageToBytes(ImageBlobResource.Bild), - Image2 = ImageToBytes(ImageBlobResource.Bild2), - Image3 = ImageToBytes(ImageBlobResource.Bild3), - Complex = new object[] { "Foo", "Bar", "Baz", 1 } - }; - - var provider = OrmLiteConfig.DialectProvider as OrmLiteDialectProviderBase; - Assert.NotNull(provider); - - using (var insertCmd = db.CreateInsertStatement(dto)) - { - var nInserted = insertCmd.ExecuteNonQuery(); - Assert.Greater(nInserted, 0); - - for (int i = 2; i < 101; i++) - { - dto.Complex = new object[] { "Foo", "Bar", "Baz", i }; - insertCmd.ReparameterizeInsert(dto); - Assert.Greater(insertCmd.ExecuteNonQuery(), 0); - } - } - } - } - - [Test] - public void test_if_ormlite_sql_prepare_update_works_for_image_blobs() - { - var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServerOrmLiteDialectProvider.Instance); - - using (var db = dbFactory.OpenDbConnection()) - using (var dbConn = db.CreateCommand()) - { - dbConn.CreateTable(true); - - var dto = new ImageBlobDto() - { - Image1 = ImageToBytes(ImageBlobResource.Bild), - Image2 = ImageToBytes(ImageBlobResource.Bild2), - Image3 = ImageToBytes(ImageBlobResource.Bild3), - Complex = new object[] { "Foo", "Bar", "Baz", 1 } - }; - - var provider = OrmLiteConfig.DialectProvider as OrmLiteDialectProviderBase; - Assert.NotNull(provider); - - using (var insertCmd = db.CreateInsertStatement(dto)) - { - var nInserted = insertCmd.ExecuteNonQuery(); - Assert.Greater(nInserted, 0); - } - - dto.Id = 1; - dto.Complex = new object[] { "Baz", "Bar", "Foo", 2 }; - using (var updateCmd = db.CreateUpdateStatement(dto)) - { - var nUpdated = updateCmd.ExecuteNonQuery(); - Assert.Greater(nUpdated, 0); - } - } - } - - protected byte[] ImageToBytes(Image i) - { - using (var s = new MemoryStream()) - { - i.Save(s, ImageFormat.Png); - return s.GetBuffer(); - } - } - } -} diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteInsertTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteInsertTests.cs index 475c2c52a..e563d4a27 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteInsertTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteInsertTests.cs @@ -1,231 +1,331 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.Versioning; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.Expression; +using ServiceStack.OrmLite.Tests.Shared; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteInsertTests - : OrmLiteTestBase - { + internal class CustomerWithAutoIncrementPrimaryKey + { + [PrimaryKey, AutoIncrement] + public int Id { get; set; } + public string Name { get; set; } + } + + [TestFixtureOrmLite] + public class OrmLiteInsertTests : OrmLiteProvidersTestBase + { + public OrmLiteInsertTests(DialectContext context) : base(context) {} + + [Test] + public void Can_insert_into_CustomerWithAutoIncrementPrimaryKey_table() + { + var id = (int)DateTime.Now.ToOADate(); + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var row = new CustomerWithAutoIncrementPrimaryKey() + { + Id = id, + Name = Guid.NewGuid().ToString() + }; + + var ret = db.Insert(row, true, true); + Debug.Assert(ret == id); + } + } + + [Test] + public async Task Can_insert_async_into_CustomerWithAutoIncrementPrimaryKey_table() + { + var id = (int)DateTime.Now.ToOADate(); + using (var db =await OpenDbConnectionAsync()) + { + db.CreateTable(true); + + var row = new CustomerWithAutoIncrementPrimaryKey() + { + Id = id, + Name = Guid.NewGuid().ToString() + }; + + var ret =await db.InsertAsync(row, true, true); + Debug.Assert(ret == id); + } + } + + [Test] + public void Can_insert_into_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var row = ModelWithFieldsOfDifferentTypes.Create(1); + + db.Insert(row); + } + } + + [Test] + public void Can_InsertOnly_aliased_fields() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); - [Test] - public void Can_insert_into_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + db.InsertOnly(() => new PersonWithAliasedAge { Name = "Bob", Age = 30 }); + } + } - var row = ModelWithFieldsOfDifferentTypes.Create(1); + [Test] + public void Can_InsertOnly_fields_using_EnumAsInt() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); - db.Insert(row); - } - } + db.InsertOnly(() => new PersonUsingEnumAsInt { Name = "Sarah", Gender = Gender.Female }); - [Test] - public void Can_insert_and_select_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + var saved = db.Single(p => p.Name == "Sarah"); + Assert.That(saved.Name, Is.EqualTo("Sarah")); + Assert.That(saved.Gender, Is.EqualTo(Gender.Female)); + } + } - var row = ModelWithFieldsOfDifferentTypes.Create(1); + [Test] + public void Can_insert_and_select_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var row = ModelWithFieldsOfDifferentTypes.Create(1); - db.Insert(row); + db.Insert(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithFieldsOfDifferentTypes.AssertIsEqual(rows[0], row); - } - } + ModelWithFieldsOfDifferentTypes.AssertIsEqual(rows[0], row); + } + } - [Test] - public void Can_insert_and_select_from_ModelWithFieldsOfNullableTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + [Test] + public void Can_insert_and_select_from_ModelWithFieldsOfNullableTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); - var row = ModelWithFieldsOfNullableTypes.Create(1); + var row = ModelWithFieldsOfNullableTypes.Create(1); - db.Insert(row); + db.Insert(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithFieldsOfNullableTypes.AssertIsEqual(rows[0], row); - } - } + ModelWithFieldsOfNullableTypes.AssertIsEqual(rows[0], row); + } + } - [Test] - public void Can_insert_and_select_from_ModelWithFieldsOfDifferentAndNullableTypes_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + [Test] + public void Can_insert_and_select_from_ModelWithFieldsOfDifferentAndNullableTypes_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); - var row = ModelWithFieldsOfDifferentAndNullableTypes.Create(1); + var row = ModelWithFieldsOfDifferentAndNullableTypes.Create(1); - db.Insert(row); + db.Insert(row); - var rows = db.Select(); + var rows = db.Select(); rows.PrintDump(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithFieldsOfDifferentAndNullableTypes.AssertIsEqual(rows[0], row); - } - } + ModelWithFieldsOfDifferentAndNullableTypes.AssertIsEqual(rows[0], row); + } + } - [Test] - public void Can_insert_table_with_null_fields() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + [Test] + public void Can_insert_table_with_null_fields() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); - var row = ModelWithIdAndName.Create(1); - row.Name = null; + var row = ModelWithIdAndName.Create(1); + row.Name = null; - db.Insert(row); + db.Insert(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithIdAndName.AssertIsEqual(rows[0], row); - } - } + ModelWithIdAndName.AssertIsEqual(rows[0], row); + } + } - [Test] - public void Can_retrieve_LastInsertId_from_inserted_table() - { - using (var db = OpenDbConnection()) - { + [Test] + public void Can_retrieve_LastInsertId_from_inserted_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var row1 = ModelWithIdAndName.Create(5); - var row2 = ModelWithIdAndName.Create(6); + var row1 = ModelWithIdAndName.Create(5); + var row2 = ModelWithIdAndName.Create(6); - var row1LastInsertId = db.Insert(row1, selectIdentity:true); + var row1LastInsertId = db.Insert(row1, selectIdentity: true); - var row2LastInsertId = db.Insert(row2, selectIdentity:true); + var row2LastInsertId = db.Insert(row2, selectIdentity: true); var insertedRow1 = db.SingleById(row1LastInsertId); var insertedRow2 = db.SingleById(row2LastInsertId); - Assert.That(insertedRow1.Name, Is.EqualTo(row1.Name)); - Assert.That(insertedRow2.Name, Is.EqualTo(row2.Name)); - } - } - - [Test] - public void Can_insert_TaskQueue_table() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - var row = TaskQueue.Create(1); - - db.Insert(row); - - var rows = db.Select(); - - Assert.That(rows, Has.Count.EqualTo(1)); - - //Update the auto-increment id - row.Id = rows[0].Id; - - TaskQueue.AssertIsEqual(rows[0], row); - } - } - - public class UserAuth - { - public UserAuth() - { - this.Roles = new List(); - this.Permissions = new List(); - } - - [AutoIncrement] - public virtual int Id { get; set; } - public virtual string UserName { get; set; } - public virtual string Email { get; set; } - public virtual string PrimaryEmail { get; set; } - public virtual string FirstName { get; set; } - public virtual string LastName { get; set; } - public virtual string DisplayName { get; set; } - public virtual string Salt { get; set; } - public virtual string PasswordHash { get; set; } - public virtual List Roles { get; set; } - public virtual List Permissions { get; set; } - public virtual DateTime CreatedDate { get; set; } - public virtual DateTime ModifiedDate { get; set; } - public virtual Dictionary Meta { get; set; } - } - - [Test] - public void Can_insert_table_with_UserAuth() - { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); - - //var userAuth = new UserAuth { - // Id = 1, - // UserName = "UserName", - // Email = "a@b.com", - // PrimaryEmail = "c@d.com", - // FirstName = "FirstName", - // LastName = "LastName", - // DisplayName = "DisplayName", - // Salt = "Salt", - // PasswordHash = "PasswordHash", - // CreatedDate = DateTime.Now, - // ModifiedDate = DateTime.UtcNow, - //}; - - var jsv = "{Id:0,UserName:UserName,Email:as@if.com,PrimaryEmail:as@if.com,FirstName:FirstName,LastName:LastName,DisplayName:DisplayName,Salt:WMQi/g==,PasswordHash:oGdE40yKOprIgbXQzEMSYZe3vRCRlKGuqX2i045vx50=,Roles:[],Permissions:[],CreatedDate:2012-03-20T07:53:48.8720739Z,ModifiedDate:2012-03-20T07:53:48.8720739Z}"; - var userAuth = jsv.To(); - - db.Insert(userAuth); - - var rows = db.Select(q => q.UserName == "UserName"); - - Console.WriteLine(rows[0].Dump()); - - Assert.That(rows[0].UserName, Is.EqualTo(userAuth.UserName)); - } - } + Assert.That(insertedRow1.Name, Is.EqualTo(row1.Name)); + Assert.That(insertedRow2.Name, Is.EqualTo(row2.Name)); + } + } [Test] - public void Can_GetLastInsertedId_using_Insert() + public void Can_retrieve_AutoIdentityId_with_InsertOnly_fieldNames() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var row1 = ModelWithIdAndName.Create(5); + var row2 = ModelWithIdAndName.Create(6); + + var row1LastInsertId = db.InsertOnly(row1, new[] { "Id", "Name" }, selectIdentity: true); + + var row2LastInsertId = db.InsertOnly(row2, new[] { "Id", "Name" }, selectIdentity: true); + + var insertedRow1 = db.SingleById(row1LastInsertId); + var insertedRow2 = db.SingleById(row2LastInsertId); + + Assert.That(insertedRow1.Name, Is.EqualTo(row1.Name)); + Assert.That(insertedRow2.Name, Is.EqualTo(row2.Name)); + } + } + + [Test] + public void Can_retrieve_AutoIdentityId_with_InsertOnly_expression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var row1LastInsertId = db.InsertOnly(() => new ModelWithIdAndName + { + Id = 5, + Name = "Name 5" + }, selectIdentity: true); + + var row2LastInsertId = db.InsertOnly(() => new ModelWithIdAndName + { + Id = 6, + Name = "Name 6" + }, selectIdentity: true); + + var insertedRow1 = db.SingleById(row1LastInsertId); + var insertedRow2 = db.SingleById(row2LastInsertId); + + Assert.That(insertedRow1.Name, Is.EqualTo("Name 5")); + Assert.That(insertedRow2.Name, Is.EqualTo("Name 6")); + } + } + + [Test] + public void Can_insert_TaskQueue_table() + { + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + var row = TaskQueue.Create(1); + + db.Insert(row); + + var rows = db.Select(); + + Assert.That(rows, Has.Count.EqualTo(1)); + + //Update the auto-increment id + row.Id = rows[0].Id; + + TaskQueue.AssertIsEqual(rows[0], row); + } + } + + [Test] + public void Can_insert_table_with_UserAuth() { - SuppressIfOracle("Need trigger for autoincrement keys to work in Oracle with caller supplied SQL"); + using (var db = OpenDbConnection()) + { + db.CreateTable(true); + + //var userAuth = new UserAuth { + // Id = 1, + // UserName = "UserName", + // Email = "a@b.com", + // PrimaryEmail = "c@d.com", + // FirstName = "FirstName", + // LastName = "LastName", + // DisplayName = "DisplayName", + // Salt = "Salt", + // PasswordHash = "PasswordHash", + // CreatedDate = DateTime.Now, + // ModifiedDate = DateTime.UtcNow, + //}; + + var jsv = "{Id:0,UserName:UserName,Email:as@if.com,PrimaryEmail:as@if.com,FirstName:FirstName,LastName:LastName,DisplayName:DisplayName,Salt:WMQi/g==,PasswordHash:oGdE40yKOprIgbXQzEMSYZe3vRCRlKGuqX2i045vx50=,Roles:[],Permissions:[],CreatedDate:2012-03-20T07:53:48.8720739Z,ModifiedDate:2012-03-20T07:53:48.8720739Z}"; + var userAuth = jsv.To(); + + db.Insert(userAuth); + + var rows = db.Select(q => q.UserName == "UserName"); + + Console.WriteLine(rows[0].Dump()); + Assert.That(rows[0].UserName, Is.EqualTo(userAuth.UserName)); + } + } + + [Test] + [IgnoreDialect(Tests.Dialect.AnyOracle, "Need trigger for autoincrement keys to work in Oracle with caller supplied SQL")] + public void Can_GetLastInsertedId_using_Insert() + { var date = new DateTime(2000, 1, 1); - var testObject = new UserAuth { UserName = "test", CreatedDate = date, ModifiedDate = date }; + var testObject = new UserAuth + { + UserName = "test", + CreatedDate = date, + ModifiedDate = date, + InvalidLoginAttempts = 0, + }; //verify that "normal" Insert works as expected using (var db = OpenDbConnection()) { - db.CreateTable(true); + db.DropAndCreateTable(); - db.ExecuteSql("INSERT INTO {0} ({1},{2},{3}) VALUES ({4},'2000-01-01','2000-01-01')" - .Fmt("UserAuth".SqlTable(), - "UserName".SqlColumn(), - "CreatedDate".SqlColumn(), - "ModifiedDate".SqlColumn(), - testObject.UserName.SqlValue())); + db.ExecuteSql($"INSERT INTO {"UserAuth".SqlTable(DialectProvider)} ({"UserName".SqlColumn(DialectProvider)},{"CreatedDate".SqlColumn(DialectProvider)},{"ModifiedDate".SqlColumn(DialectProvider)},{"InvalidLoginAttempts".SqlColumn(DialectProvider)}) VALUES ('{testObject.UserName}','2000-01-01','2000-01-01',0)"); var normalLastInsertedId = db.LastInsertId(); Assert.Greater(normalLastInsertedId, 0, "normal Insert"); } @@ -239,5 +339,345 @@ public void Can_GetLastInsertedId_using_Insert() Assert.Greater(lastInsertId, 0, "with InsertParam"); } } + + [Test] + [IgnoreDialect(Tests.Dialect.AnyOracle, "Need trigger for autoincrement keys to work in Oracle")] + public void Can_InsertOnly_selected_fields() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertOnly(new PersonWithAutoId { Age = 27 }, x => x.Age); + var row = db.Select()[0]; + Assert.That(row.Age, Is.EqualTo(27)); + Assert.That(row.FirstName, Is.Null); + Assert.That(row.LastName, Is.Null); + + db.DeleteAll(); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, x => new { x.FirstName, x.Age }); + row = db.Select()[0]; + Assert.That(row.FirstName, Is.EqualTo("Amy")); + Assert.That(row.Age, Is.EqualTo(27)); + Assert.That(row.LastName, Is.Null); + + db.DeleteAll(); + + db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, new[] { "FirstName", "Age" }); + row = db.Select()[0]; + Assert.That(row.FirstName, Is.EqualTo("Amy")); + Assert.That(row.Age, Is.EqualTo(27)); + Assert.That(row.LastName, Is.Null); + } + } + + [Test] + [IgnoreDialect(Tests.Dialect.AnyOracle, "Need trigger for autoincrement keys to work in Oracle")] + public void Can_InsertOnly_selected_fields_using_AssignmentExpression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.InsertOnly(() => new PersonWithAutoId { FirstName = "Amy", Age = 27 }); + Assert.That(db.GetLastSql().NormalizeSql(), Is.EqualTo("insert into personwithautoid (firstname,age) values (@firstname,@age)")); + + var row = db.Select()[0]; + Assert.That(row.FirstName, Is.EqualTo("Amy")); + Assert.That(row.Age, Is.EqualTo(27)); + Assert.That(row.LastName, Is.Null); + } + } + + [Test] + public void Can_insert_record_with_Computed_column() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var market = new Market + { + Available = 10, + AvailableTotal = 0, + AvailableSalesEvent = 2, + MinCustomerBuy = 10 + }; + + db.Insert(market); + } + } + + [Test] + public void Can_InsertIntoSelect_using_Custom_Select() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var userAuth = new UserAuth { + Id = 1, + UserName = "UserName", + Email = "a@b.com", + PrimaryEmail = "c@d.com", + FirstName = "FirstName", + LastName = "LastName", + DisplayName = "DisplayName", + Salt = "Salt", + PasswordHash = "PasswordHash", + CreatedDate = DateTime.Now, + ModifiedDate = DateTime.UtcNow, + }; + db.Insert(userAuth); + +// OrmLiteUtils.PrintSql(); + + var q = db.From() + .Where(x => x.UserName == "UserName") + .Select(x => new { + FullName = x.FirstName + " " + x.LastName, + GivenName = x.FirstName, + Surname = x.LastName, + x.Email, + x.UserName, + }); + + var rowsInserted = db.InsertIntoSelect(q); + Assert.That(rowsInserted, Is.EqualTo(1)); + + var result = db.Select()[0]; + + Assert.That(result.Id, Is.GreaterThan(0)); + Assert.That(result.UserName, Is.EqualTo(userAuth.UserName)); + Assert.That(result.Email, Is.EqualTo(userAuth.Email)); + Assert.That(result.GivenName, Is.EqualTo(userAuth.FirstName)); + Assert.That(result.Surname, Is.EqualTo(userAuth.LastName)); + Assert.That(result.FullName, Is.EqualTo(userAuth.FirstName + " " + userAuth.LastName)); + } + } + + [Test] + public async Task Can_InsertIntoSelect_using_Custom_Select_Async() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var userAuth = new UserAuth { + Id = 1, + UserName = "UserName", + Email = "a@b.com", + PrimaryEmail = "c@d.com", + FirstName = "FirstName", + LastName = "LastName", + DisplayName = "DisplayName", + Salt = "Salt", + PasswordHash = "PasswordHash", + CreatedDate = DateTime.Now, + ModifiedDate = DateTime.UtcNow, + }; + await db.InsertAsync(userAuth); + +// OrmLiteUtils.PrintSql(); + + var q = db.From() + .Where(x => x.UserName == "UserName") + .Select(x => new { + FullName = x.FirstName + " " + x.LastName, + GivenName = x.FirstName, + Surname = x.LastName, + x.Email, + x.UserName, + }); + + var rowsInserted = await db.InsertIntoSelectAsync(q); + Assert.That(rowsInserted, Is.EqualTo(1)); + + var result = (await db.SelectAsync())[0]; + + Assert.That(result.Id, Is.GreaterThan(0)); + Assert.That(result.UserName, Is.EqualTo(userAuth.UserName)); + Assert.That(result.Email, Is.EqualTo(userAuth.Email)); + Assert.That(result.GivenName, Is.EqualTo(userAuth.FirstName)); + Assert.That(result.Surname, Is.EqualTo(userAuth.LastName)); + Assert.That(result.FullName, Is.EqualTo(userAuth.FirstName + " " + userAuth.LastName)); + } + } + + [Test] + public void Can_Insert_ObjectDictionary() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var row = ModelWithFieldsOfDifferentTypes.Create(0); + var obj = row.ToObjectDictionary(); + obj.Remove(nameof(row.Id)); + + row.Id = (int) db.Insert(obj, selectIdentity:true); + Assert.That(row.Id, Is.Not.EqualTo(0)); + + var fromDb = db.SingleById(row.Id); + + ModelWithFieldsOfDifferentTypes.AssertIsEqual(fromDb, row); + } + } + + [Test] + public async Task Can_Insert_ObjectDictionary_Async() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var row = ModelWithFieldsOfDifferentTypes.Create(0); + var obj = row.ToObjectDictionary(); + obj.Remove(nameof(row.Id)); + + row.Id = (int) await db.InsertAsync(obj, selectIdentity:true); + Assert.That(row.Id, Is.Not.EqualTo(0)); + + var fromDb = await db.SingleByIdAsync(row.Id); + + ModelWithFieldsOfDifferentTypes.AssertIsEqual(fromDb, row); + } + } + + [Test] + public void Can_Insert_ObjectDictionary_and_override_PrimaryKey() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var row = ModelWithFieldsOfDifferentTypes.Create(0); + row.Id = 100; + var obj = row.ToObjectDictionary(); + + var retId = (int) db.Insert(obj, selectIdentity:true); + Assert.That(retId, Is.EqualTo(row.Id)); + + var fromDb = db.SingleById(row.Id); + + ModelWithFieldsOfDifferentTypes.AssertIsEqual(fromDb, row); + } + } + + [Test] + public async Task Can_Insert_ObjectDictionary_and_override_PrimaryKey_Async() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var row = ModelWithFieldsOfDifferentTypes.Create(0); + row.Id = 100; + var obj = row.ToObjectDictionary(); + + var retId = (int) await db.InsertAsync(obj, selectIdentity:true); + Assert.That(retId, Is.EqualTo(row.Id)); + + var fromDb = await db.SingleByIdAsync(row.Id); + + ModelWithFieldsOfDifferentTypes.AssertIsEqual(fromDb, row); + } + } + + } + + public class Market + { + [AutoIncrement] + public int Id { get; set; } + [Required] + public int Available { get; set; } + [Required] + public int AvailableSalesEvent { get; set; } + [Compute, Persisted] + [Required] + public int AvailableTotal { get; set; } + [Required] + public int? MinCustomerBuy { get; set; } + } + + public class UserAuth + { + public UserAuth() + { + Roles = new List(); + Permissions = new List(); + } + + [AutoIncrement] + public virtual int Id { get; set; } + + public virtual string UserName { get; set; } + public virtual string Email { get; set; } + public virtual string PrimaryEmail { get; set; } + public virtual string PhoneNumber { get; set; } + public virtual string FirstName { get; set; } + public virtual string LastName { get; set; } + public virtual string DisplayName { get; set; } + public virtual string Company { get; set; } + public virtual DateTime? BirthDate { get; set; } + public virtual string BirthDateRaw { get; set; } + public virtual string Address { get; set; } + public virtual string Address2 { get; set; } + public virtual string City { get; set; } + public virtual string State { get; set; } + public virtual string Country { get; set; } + public virtual string Culture { get; set; } + public virtual string FullName { get; set; } + public virtual string Gender { get; set; } + public virtual string Language { get; set; } + public virtual string MailAddress { get; set; } + public virtual string Nickname { get; set; } + public virtual string PostalCode { get; set; } + public virtual string TimeZone { get; set; } + public virtual string Salt { get; set; } + public virtual string PasswordHash { get; set; } + public virtual string DigestHa1Hash { get; set; } + public virtual List Roles { get; set; } + public virtual List Permissions { get; set; } + public virtual DateTime CreatedDate { get; set; } + public virtual DateTime ModifiedDate { get; set; } + public virtual int InvalidLoginAttempts { get; set; } + public virtual DateTime? LastLoginAttempt { get; set; } + public virtual DateTime? LockedDate { get; set; } + public virtual string RecoveryToken { get; set; } + + //Custom Reference Data + public virtual int? RefId { get; set; } + public virtual string RefIdStr { get; set; } + public virtual Dictionary Meta { get; set; } + } + public class UserAuthRole + { + [AutoIncrement] + public virtual int Id { get; set; } + public virtual int UserAuthId { get; set; } + public virtual string Role { get; set; } + public virtual string Permission { get; set; } + public virtual DateTime CreatedDate { get; set; } + public virtual DateTime ModifiedDate { get; set; } + + //Custom Reference Data + public virtual int? RefId { get; set; } + public virtual string RefIdStr { get; set; } + public virtual Dictionary Meta { get; set; } + } + + public class SubUserAuth + { + [AutoIncrement] + public virtual int Id { get; set; } + public virtual string UserName { get; set; } + public string Email { get; set; } + public string GivenName { get; set; } + public string Surname { get; set; } + public string FullName { get; set; } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteMultipleDialectProviderTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteMultipleDialectProviderTests.cs index 458ab6523..910abb967 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteMultipleDialectProviderTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteMultipleDialectProviderTests.cs @@ -9,6 +9,7 @@ namespace ServiceStack.OrmLite.Tests { [TestFixture] + [NonParallelizable] public class OrmLiteMultipleDialectProviderTests { public class Person @@ -22,52 +23,67 @@ public class Person public void Can_open_multiple_dialectprovider_with_execfilter() { //global OrmLiteConfig.DialectProvider = new SqliteOrmLiteDialectProvider(); - var factory = new OrmLiteConnectionFactory(Config.SqliteMemoryDb); + var factory = new OrmLiteConnectionFactory(SqliteDb.MemoryConnection); var sqlServerDialectProvider = SqlServerDialect.Provider; sqlServerDialectProvider.ExecFilter = new MockExecFilter1(); - factory.RegisterConnection("sqlserver", Config.SqlServerBuildDb, sqlServerDialectProvider); + factory.RegisterConnection("sqlserver", $"{SqlServerDb.DefaultConnection};Connection Timeout=1", sqlServerDialectProvider); var sqliteDialectProvider = SqliteDialect.Provider; sqliteDialectProvider.ExecFilter = new MockExecFilter2(); - factory.RegisterConnection("sqlite-file", Config.SqliteFileDb, sqliteDialectProvider); + factory.RegisterConnection("sqlite-file", SqliteDb.FileConnection, sqliteDialectProvider); - var results = new List(); - using (var db = factory.OpenDbConnection()) { - db.DropAndCreateTable(); - db.Insert(new Person { Id = 1, Name = "1) :memory:" }); - db.Insert(new Person { Id = 2, Name = "2) :memory:" }); + try + { + var results = new List(); + using (var db = factory.OpenDbConnection()) + { + db.DropAndCreateTable(); + db.Insert(new Person {Id = 1, Name = "1) :memory:"}); + db.Insert(new Person {Id = 2, Name = "2) :memory:"}); - using (var db2 = factory.OpenDbConnection("sqlserver")) { - db2.CreateTable(true); - db2.Insert(new Person { Id = 3, Name = "3) Database1.mdf" }); - db2.Insert(new Person { Id = 4, Name = "4) Database1.mdf" }); + using (var db2 = factory.OpenDbConnection("sqlserver")) + { + db2.CreateTable(true); + db2.Insert(new Person {Id = 3, Name = "3) Database1.mdf"}); + db2.Insert(new Person {Id = 4, Name = "4) Database1.mdf"}); - using (var db3 = factory.OpenDbConnection("sqlite-file")) { - db3.CreateTable(true); - db3.Insert(new Person { Id = 5, Name = "5) db.sqlite" }); - db3.Insert(new Person { Id = 6, Name = "6) db.sqlite" }); + using (var db3 = factory.OpenDbConnection("sqlite-file")) + { + db3.CreateTable(true); + db3.Insert(new Person {Id = 5, Name = "5) db.sqlite"}); + db3.Insert(new Person {Id = 6, Name = "6) db.sqlite"}); - results.AddRange(db.Select()); - results.AddRange(db2.Select()); - results.AddRange(db3.Select()); + results.AddRange(db.Select()); + results.AddRange(db2.Select()); + results.AddRange(db3.Select()); - Assert.AreEqual(db.GetLastSql(), "SELECT \"Id\", \"Name\" FROM \"Person\""); - Assert.AreEqual(db2.GetLastSql(), "MockExecFilter1"); - Assert.AreEqual(db3.GetLastSql(), "MockExecFilter2"); + Assert.AreEqual(db.GetLastSql(), "SELECT \"Id\", \"Name\" FROM \"Person\""); + Assert.AreEqual(db2.GetLastSql(), "MockExecFilter1"); + Assert.AreEqual(db3.GetLastSql(), "MockExecFilter2"); + } } } - } - results.PrintDump(); - var ids = results.ConvertAll(x => x.Id); - Assert.AreEqual(new[] { 1, 2, 3, 4, 5, 6 }, ids); + results.PrintDump(); + var ids = results.ConvertAll(x => x.Id); + Assert.AreEqual(new[] {1, 2, 3, 4, 5, 6}, ids); + } + finally + { + SqlServerDialect.Provider.ExecFilter = null; + SqliteDialect.Provider.ExecFilter = null; + } } public class MockExecFilter1 : OrmLiteExecFilter { public override T Exec(IDbConnection dbConn, Func filter) { +#if NETCORE + var isCmd = System.Reflection.TypeExtensions.IsAssignableFrom(typeof(IDbCommand), typeof(T)); +#else var isCmd = typeof(IDbCommand).IsAssignableFrom(typeof(T)); +#endif var dbCmd = CreateCommand(dbConn); Stopwatch watch = Stopwatch.StartNew(); try { @@ -86,7 +102,11 @@ public override T Exec(IDbConnection dbConn, Func filter) { public class MockExecFilter2 : OrmLiteExecFilter { public override T Exec(IDbConnection dbConn, Func filter) { +#if NETCORE + var isCmd = System.Reflection.TypeExtensions.IsAssignableFrom(typeof(IDbCommand), typeof(T)); +#else var isCmd = typeof(IDbCommand).IsAssignableFrom(typeof(T)); +#endif var dbCmd = CreateCommand(dbConn); Stopwatch watch = Stopwatch.StartNew(); try { diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteProvidersTestBase.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteProvidersTestBase.cs new file mode 100644 index 000000000..34d359437 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteProvidersTestBase.cs @@ -0,0 +1,275 @@ +using System; +using System.Collections.Generic; +using System.Data; +#if !NETCORE +using System.Data.Common; +using System.IO; +#endif +using System.Data.SqlClient; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using NUnit.Framework.Interfaces; +using NUnit.Framework.Internal; +using NUnit.Framework.Internal.Builders; +using ServiceStack.Logging; + +namespace ServiceStack.OrmLite.Tests +{ + /// + /// Use this base class in conjunction with one or more + /// attributes to repeat tests for each db dialect. + /// Alternatively, specify + /// to repeat tests for each flag of + /// + /// + /// + /// // example + /// [TestFixtureOrmLite] // all configured dialects + /// [TestFixtureOrmLiteDialects(Dialect.Supported)] // all base versions of supported dialects + /// public TestClass : OrmLiteProvidersTestBase { + /// public TestClass(DialectContext context) : base(context) {} + /// + /// // Test runs once per specified providers + /// [Test] + /// public void SomeTestMethod() { + /// // current dialect + /// var dialect = Dialect; + /// // current dialect provider instance + /// var dp = DialectProvider; + /// // get connection for provider and dialect + /// using(var db = OpenDbConnection()) { + /// // your db agnostic test code + /// } + /// } + /// } + /// + /// + public abstract class OrmLiteProvidersTestBase + { + /// + /// The current db dialect + /// + public readonly Dialect Dialect; + + public readonly DialectFeatures DialectFeatures; + + /// + /// The current DialogProvider instance + /// + protected IOrmLiteDialectProvider DialectProvider; + + // The Database Factory + protected OrmLiteConnectionFactory DbFactory { get; set; } + + protected TestLogFactory Log => OrmLiteFixtureSetup.LogFactoryInstance; + + /// + /// The test logs + /// TODO can scoped logs be created per provider? + /// + public IList> Logs => TestLogger.GetLogs(); + + public OrmLiteProvidersTestBase(DialectContext context) + { + Dialect = context.Dialect; + DialectFeatures = new DialectFeatures(Dialect); + DbFactory = context.NamedConnection.CreateCopy(); + DialectProvider = DbFactory.DialectProvider; + + if (OrmLiteConfig.DialectProvider == null) + OrmLiteConfig.DialectProvider = DialectProvider; + } + + public virtual IDbConnection OpenDbConnection() => DbFactory.OpenDbConnection(); + public virtual Task OpenDbConnectionAsync() => DbFactory.OpenDbConnectionAsync(); + } + + /// + /// Holds dialect flags applicable to specific SQL language features + /// + public class DialectFeatures + { + public readonly bool RowOffset; + public readonly bool SchemaSupport; + + public DialectFeatures(Dialect dialect) + { + // Tag dialects with supported features and use to toggle in tests + RowOffset = (Dialect.SqlServer2012 | Dialect.SqlServer2014 | Dialect.SqlServer2016 | Dialect.SqlServer2017).HasFlag(dialect); + SchemaSupport = !(Dialect.Sqlite | Dialect.AnyPostgreSql).HasFlag(dialect); + } + } + + [SetUpFixture] + public class OrmLiteFixtureSetup + { + public static TestLogFactory LogFactoryInstance => new TestLogFactory(); + + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + // init logging, for use in tests, filter by type? + LogManager.LogFactory = LogFactoryInstance; + + // setup db factories + var dbFactory = TestConfig.InitDbFactory(); + } + + } + + /// + /// Repeats tests for all dialect versions from + /// To restrict tests to specific dialects use + /// To filter tests for specific dialects use + /// + /// + public class TestFixtureOrmLiteAttribute : TestFixtureOrmLiteDialectsAttribute + { + public TestFixtureOrmLiteAttribute() : base(TestConfig.Dialects) + { + // loads the dialects from TestConfig.DefaultDialects + // which can be overridden using an environment variable + } + } + + /// + /// Repeats tests for all Dialect flags specified. + /// Also sets NUnit categories for each dialect flag which + /// enables adhoc filtering of tests by using Dialect enum flag values + /// as category names in the test runner + /// + /// + /// Use Dialect flags enum values to filter out one or more dialects from test runs + /// + /// dotnet test --filter TestCategory=SqlServer // filters SqlServer tests for all dialects/db versions + /// dotnet test --filter TestCategory=MySql5_5 // filters MySql tests for db version v5.5 + /// + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class TestFixtureOrmLiteDialectsAttribute : NUnitAttribute, IFixtureBuilder2 + { + private readonly Dialect dialect; + private readonly NUnitTestFixtureBuilder _builder = new NUnitTestFixtureBuilder(); + private readonly string reason; + private readonly int[] versions; + + public TestFixtureOrmLiteDialectsAttribute(Dialect dialect) + { + this.dialect = dialect; + reason = $"Dialect not included in TestConfig.Dialect value {TestConfig.Dialects}"; + } + + public TestFixtureOrmLiteDialectsAttribute(Dialect dialect, int version) : this(dialect, new []{ version }) {} + public TestFixtureOrmLiteDialectsAttribute(Dialect dialect, int[] versions) : this(dialect) => this.versions = versions; + + public IEnumerable BuildFrom(ITypeInfo typeInfo) + { + return BuildFrom(typeInfo, null); + } + + public IEnumerable BuildFrom(ITypeInfo typeInfo, IPreFilter filter) + { + var fixtureData = new List(); + + void AddTestDataVersions(Dialect matchesDialect, int[] dialectVersions) + { + if ((matchesDialect & dialect) != matchesDialect) + return; + + fixtureData.AddRange(this.versions == null + ? dialectVersions.Map(v => new TestFixtureData(new DialectContext(matchesDialect, v))) + : this.versions.Map(v => new TestFixtureData(new DialectContext(matchesDialect, v)))); + } + + AddTestDataVersions(Dialect.Sqlite, SqliteDb.Versions); + AddTestDataVersions(Dialect.SqlServer, SqlServerDb.V2012Versions); + AddTestDataVersions(Dialect.SqlServer2012, SqlServerDb.V2012Versions); + AddTestDataVersions(Dialect.SqlServer2014, SqlServerDb.V2014Versions); + AddTestDataVersions(Dialect.SqlServer2016, SqlServerDb.V2016Versions); + AddTestDataVersions(Dialect.SqlServer2017, SqlServerDb.V2017Versions); + AddTestDataVersions(Dialect.PostgreSql9, PostgreSqlDb.V9Versions); + AddTestDataVersions(Dialect.PostgreSql10, PostgreSqlDb.V10Versions); + AddTestDataVersions(Dialect.PostgreSql11, PostgreSqlDb.V11Versions); + AddTestDataVersions(Dialect.MySql, MySqlDb.Versions); + AddTestDataVersions(Dialect.MySqlConnector, MySqlDb.MySqlConnectorVersions); + AddTestDataVersions(Dialect.Oracle, OracleDb.Versions); + AddTestDataVersions(Dialect.Firebird, FirebirdDb.Versions); + + foreach (var data in fixtureData) + { + // ignore test if not in TestConfig but add as ignored to explain why + var dialectContext = ((DialectContext)data.Arguments[0]); + if (!TestConfig.Dialects.HasFlag(dialectContext.Dialect)) + data.Ignore(reason); + + data.Properties.Add(PropertyNames.Category, dialectContext.ToString()); + yield return _builder.BuildFrom(typeInfo, filter, data); + } + } + } + + /// + /// Can be applied to a test to skip for specific dialects + /// + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)] + public class IgnoreDialectAttribute : NUnitAttribute, ITestAction + { + private readonly Dialect dialect; + private readonly string reason; + private readonly int[] versions; + + /// + /// Ignore one or more specific dialects from testing + /// + /// The dialect flags to ignore + /// The ignore reason that will be output in test results + public IgnoreDialectAttribute(Dialect dialect, string reason) + { + this.dialect = dialect; + this.reason = reason; + } + + /// + /// Ignore one or more specific dialects from testing + /// + /// The dialect flags to ignore + /// Specific versions you want to ignore + /// The ignore reason that will be output in test results + public IgnoreDialectAttribute(Dialect dialect, int[] versions, string reason) + { + this.dialect = dialect; + this.versions = versions; + this.reason = reason; + } + + public IgnoreDialectAttribute(Dialect dialect, int version, string reason) + : this(dialect, new[] {version}, reason) {} + + public void BeforeTest(ITest test) + { + // get the dialect from either the class or method parent + // and if dialect matches, ignore test + var testContexts = test.TestType == "TestMethod" + ? test.Parent.Arguments.OfType() + : test.Arguments.OfType(); + + foreach (var testContext in testContexts) + { + if (this.dialect.HasFlag(testContext.Dialect) && test.RunState != RunState.NotRunnable) + { + if (versions == null || versions.Contains(testContext.Version)) + { + Assert.Ignore($"Ignoring for {testContext}: {reason}"); + } + } + } + } + + public void AfterTest(ITest test) + { + } + + public ActionTargets Targets { get; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteQueryTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteQueryTests.cs index 91912eb32..0c9af3b3a 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteQueryTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteQueryTests.cs @@ -6,115 +6,115 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteQueryTests - : OrmLiteTestBase - { - - [Test] - public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() - { + [TestFixtureOrmLite] + public class OrmLiteQueryTests : OrmLiteProvidersTestBase + { + public OrmLiteQueryTests(DialectContext context) : base(context) {} + + [Test] + public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() + { using (var db = OpenDbConnection()) - { + { db.DropAndCreateTable(); - var rowIds = new List(new[] { 1, 2, 3 }); + var rowIds = new List(new[] { 1, 2, 3 }); for (var i = 0; i < rowIds.Count; i++) rowIds[i] = (int)db.Insert(ModelWithFieldsOfDifferentTypes.Create(rowIds[i]), selectIdentity: true); var row = db.SingleById(rowIds[0]); - Assert.That(row.Id, Is.EqualTo(rowIds[0])); - } - } + Assert.That(row.Id, Is.EqualTo(rowIds[0])); + } + } - [Test] - public void Can_GetById_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + [Test] + public void Can_GetById_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + var row = db.SingleById("id-1"); - var row = db.SingleById("id-1"); + Assert.That(row.Id, Is.EqualTo("id-1")); + } + } - Assert.That(row.Id, Is.EqualTo("id-1")); - } - } - - [Test] - public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + [Test] + public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; - db.Insert(filterRow); + db.Insert(filterRow); - var rows = db.Where(new { filterRow.AlbumName }); - var dbRowIds = rows.ConvertAll(x => x.Id); - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + var rows = db.Where(new { filterRow.AlbumName }); + var dbRowIds = rows.ConvertAll(x => x.Id); + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - rows = db.Where(new { filterRow.AlbumName }); - dbRowIds = rows.ConvertAll(x => x.Id); - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + rows = db.Where(new { filterRow.AlbumName }); + dbRowIds = rows.ConvertAll(x => x.Id); + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - var queryByExample = new ModelWithOnlyStringFields { AlbumName = filterRow.AlbumName }; - rows = db.SelectNonDefaults(queryByExample); - dbRowIds = rows.ConvertAll(x => x.Id); - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + var queryByExample = new ModelWithOnlyStringFields { AlbumName = filterRow.AlbumName }; + rows = db.SelectNonDefaults(queryByExample); + dbRowIds = rows.ConvertAll(x => x.Id); + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); rows = db.Select( "SELECT * FROM {0} WHERE {1} = {2}AlbumName" - .Fmt("ModelWithOnlyStringFields".SqlTable(), "AlbumName".SqlColumn(), OrmLiteConfig.DialectProvider.ParamString), + .Fmt("ModelWithOnlyStringFields".SqlTable(DialectProvider), "AlbumName".SqlColumn(DialectProvider), DialectProvider.ParamString), new { filterRow.AlbumName }); - dbRowIds = rows.ConvertAll(x => x.Id); - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } - - [Test] - public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + dbRowIds = rows.ConvertAll(x => x.Id); + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } + + [Test] + public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; - db.Insert(filterRow); + db.Insert(filterRow); - var dbRowIds = new List(); - var rows = db.WhereLazy(new { filterRow.AlbumName }); - foreach (var row in rows) - { - dbRowIds.Add(row.Id); - } + var dbRowIds = new List(); + var rows = db.WhereLazy(new { filterRow.AlbumName }); + foreach (var row in rows) + { + dbRowIds.Add(row.Id); + } - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } [Test] public void Can_GetSingle_with_filter_from_ModelWithOnlyStringFields_table() @@ -162,30 +162,30 @@ public void Can_query_where_and_select_Notes() db.DropAndCreateTable(); var note = new Note - { - SchemaUri = "tcm:0-0-0", - NoteText = "Hello world 5", - LastUpdated = new DateTime(2013, 1, 5), - UpdatedBy = "RC" - }; + { + SchemaUri = "tcm:0-0-0", + NoteText = "Hello world 5", + LastUpdated = new DateTime(2013, 1, 5), + UpdatedBy = "RC" + }; note.Id = (int)db.Insert(note, selectIdentity: true); var notes = db.Where(new { SchemaUri = "tcm:0-0-0" }); Assert.That(notes[0].Id, Is.EqualTo(note.Id)); Assert.That(notes[0].NoteText, Is.EqualTo(note.NoteText)); - notes = db.SelectFmt("SchemaUri".SqlColumn() + "={0}", "tcm:0-0-0"); + notes = db.Select("SELECT * FROM Note WHERE {0}={1}schemaUri".Fmt("SchemaUri".SqlColumn(DialectProvider), DialectProvider.ParamString), new { schemaUri = "tcm:0-0-0" }); Assert.That(notes[0].Id, Is.EqualTo(note.Id)); Assert.That(notes[0].NoteText, Is.EqualTo(note.NoteText)); - notes = db.Select("SELECT * FROM Note WHERE {0}={1}schemaUri".Fmt("SchemaUri".SqlColumn(), OrmLiteConfig.DialectProvider.ParamString), new { schemaUri = "tcm:0-0-0" }); + notes = db.Select("SchemaUri".SqlColumn(DialectProvider) + "={0}schemaUri".Fmt(DialectProvider.ParamString), new { schemaUri = "tcm:0-0-0" }); Assert.That(notes[0].Id, Is.EqualTo(note.Id)); Assert.That(notes[0].NoteText, Is.EqualTo(note.NoteText)); - notes = db.Select("SchemaUri".SqlColumn() + "={0}schemaUri".Fmt(OrmLiteConfig.DialectProvider.ParamString), new { schemaUri = "tcm:0-0-0" }); + notes = db.Select(x => x.SchemaUri == "tcm:0-0-0"); Assert.That(notes[0].Id, Is.EqualTo(note.Id)); Assert.That(notes[0].NoteText, Is.EqualTo(note.NoteText)); - } + } } class NoteDto @@ -214,8 +214,9 @@ public void Can_select_NotesDto_with_pretty_sql() SELECT Id, {0}, {1} FROM {2} -WHERE {0}={3}schemaUri -".Fmt("SchemaUri".SqlColumn(), "NoteText".SqlColumn(), "Note".SqlTable(), OrmLiteConfig.DialectProvider.ParamString); +WHERE {0}={3} +".Fmt("SchemaUri".SqlColumn(DialectProvider), "NoteText".SqlColumn(DialectProvider), "Note".SqlTable(DialectProvider), +DialectProvider.GetParam("schemaUri")); var notes = db.Select(sql, new { schemaUri = "tcm:0-0-0" }); Assert.That(notes[0].Id, Is.EqualTo(id)); @@ -238,19 +239,18 @@ class CustomerDto [TestCase("t030CustomerId", "t030CustomerName", "t030Customer_birth_date")] [TestCase("t030_customer_id", "t030_customer_name", "t130_customer_birth_date")] [TestCase("t030#Customer_I#d", "t030CustomerNa$^me", "t030Cust^omer_birth_date")] + [IgnoreDialect(Tests.Dialect.AnyOracle, "Oracle provider is not smart enough to insert 'from dual' everywhere required in user supplied SQL")] public void Can_query_CustomerDto_and_map_db_fields_not_identical_by_guessing_the_mapping(string field1Name, string field2Name, string field3Name) { - SuppressIfOracle("Oracle provider is not smart enough to insert 'from dual' everywhere required in user supplied SQL"); - using (var db = OpenDbConnection()) { var sql = string.Format(@" SELECT 1 AS {0}, 'John' AS {1}, '1970-01-01' AS {2} UNION ALL SELECT 2 AS {0}, 'Jane' AS {1}, '1980-01-01' AS {2}", - field1Name.SqlColumn(), - field2Name.SqlColumn(), - field3Name.SqlColumn()); + field1Name.SqlColumn(DialectProvider), + field2Name.SqlColumn(DialectProvider), + field3Name.SqlColumn(DialectProvider)); var customers = db.Select(sql); @@ -265,5 +265,29 @@ UNION ALL Assert.That(customers[1].Customer_Birth_Date, Is.EqualTo(new DateTime(1980, 01, 01))); } } + + [Test] + public void Can_query_column_as_nullable() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var id = db.Insert(new Note + { + SchemaUri = "tcm:0-0-0", + NoteText = "Hello world 5", + LastUpdated = new DateTime(2013, 1, 5), + UpdatedBy = "RC" + }, selectIdentity: true); + + var result = db.Column(db + .From() + .Where(x => x.NoteText != null) + .Select(x => x.Id)); + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result[0], Is.EqualTo(id)); + } + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteSaveTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteSaveTests.cs index 5a81b0082..66e09d47a 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteSaveTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteSaveTests.cs @@ -1,293 +1,348 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteSaveTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteSaveTests : OrmLiteProvidersTestBase { + public OrmLiteSaveTests(DialectContext context) : base(context) {} + [Test] public void Save_populates_AutoIncrementId() { - using (var db = OpenDbConnection()) - { - db.CreateTable(overwrite: true); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - var row = new PersonWithAutoId - { - FirstName = "Jimi", - LastName = "Hendrix", - Age = 27 - }; + var row = new PersonWithAutoId + { + FirstName = "Jimi", + LastName = "Hendrix", + Age = 27 + }; - db.Save(row); + db.Save(row); - Assert.That(row.Id, Is.Not.EqualTo(0)); - } + Assert.That(row.Id, Is.Not.EqualTo(0)); } [Test] - public void SaveAll_populates_AutoIncrementId() + public void Can_disable_AutoIncrement_field() { - using (var db = OpenDbConnection()) + //Can't insert in identity column + if ((Dialect & Dialect.AnySqlServer) == Dialect) + return; + + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + typeof(PersonWithAutoId) + .GetModelMetadata() + .PrimaryKey.AutoIncrement = false; + + var row = new PersonWithAutoId { - db.CreateTable(overwrite: true); - - var rows = new[] { - new PersonWithAutoId { - FirstName = "Jimi", - LastName = "Hendrix", - Age = 27 - }, - new PersonWithAutoId { - FirstName = "Kurt", - LastName = "Cobain", - Age = 27 - }, - }; - - db.Save(rows); - - Assert.That(rows[0].Id, Is.Not.EqualTo(0)); - Assert.That(rows[1].Id, Is.Not.EqualTo(0)); - Assert.That(rows[0].Id, Is.Not.EqualTo(rows[1].Id)); - } + Id = 100, + FirstName = "Jimi", + LastName = "Hendrix", + Age = 27 + }; + + db.Insert(row); + + row = db.SingleById(100); + + Assert.That(row.Id, Is.EqualTo(100)); + + typeof(PersonWithAutoId) + .GetModelMetadata() + .PrimaryKey.AutoIncrement = true; } [Test] - public void Save_populates_NullableAutoIncrementId() + public void SaveAll_populates_AutoIncrementId() { - using (var db = OpenDbConnection()) - { - db.CreateTable(overwrite: true); + using var db = OpenDbConnection(); + db.CreateTable(overwrite: true); - var row = new PersonWithNullableAutoId - { + var rows = new[] { + new PersonWithAutoId { FirstName = "Jimi", LastName = "Hendrix", Age = 27 - }; + }, + new PersonWithAutoId { + FirstName = "Kurt", + LastName = "Cobain", + Age = 27 + }, + }; - db.Save(row); + db.Save(rows); - Assert.That(row.Id, Is.Not.EqualTo(0)); - Assert.That(row.Id, Is.Not.Null); - } + Assert.That(rows[0].Id, Is.Not.EqualTo(0)); + Assert.That(rows[1].Id, Is.Not.EqualTo(0)); + Assert.That(rows[0].Id, Is.Not.EqualTo(rows[1].Id)); } [Test] - public void SaveAll_populates_NullableAutoIncrementId() + public void Save_populates_NullableAutoIncrementId() { - using (var db = OpenDbConnection()) + using var db = OpenDbConnection(); + db.CreateTable(overwrite: true); + + var row = new PersonWithNullableAutoId { - db.CreateTable(overwrite: true); - - var rows = new[] { - new PersonWithNullableAutoId { - FirstName = "Jimi", - LastName = "Hendrix", - Age = 27 - }, - new PersonWithNullableAutoId { - FirstName = "Kurt", - LastName = "Cobain", - Age = 27 - }, - }; - - db.Save(rows); - - Assert.That(rows[0].Id, Is.Not.EqualTo(0)); - Assert.That(rows[0].Id, Is.Not.Null); - Assert.That(rows[1].Id, Is.Not.EqualTo(0)); - Assert.That(rows[1].Id, Is.Not.Null); - Assert.That(rows[0].Id, Is.Not.EqualTo(rows[1].Id)); - } + FirstName = "Jimi", + LastName = "Hendrix", + Age = 27 + }; + + db.Save(row); + + Assert.That(row.Id, Is.Not.EqualTo(0)); + Assert.That(row.Id, Is.Not.Null); + } + + [Test] + public void SaveAll_populates_NullableAutoIncrementId() + { + using var db = OpenDbConnection(); + db.CreateTable(overwrite: true); + + var rows = new[] { + new PersonWithNullableAutoId { + FirstName = "Jimi", + LastName = "Hendrix", + Age = 27 + }, + new PersonWithNullableAutoId { + FirstName = "Kurt", + LastName = "Cobain", + Age = 27 + }, + }; + + db.Save(rows); + + Assert.That(rows[0].Id, Is.Not.EqualTo(0)); + Assert.That(rows[0].Id, Is.Not.Null); + Assert.That(rows[1].Id, Is.Not.EqualTo(0)); + Assert.That(rows[1].Id, Is.Not.Null); + Assert.That(rows[0].Id, Is.Not.EqualTo(rows[1].Id)); } [Test] public void Save_works_within_a_transaction() { - using (var db = OpenDbConnection()) - using (var trans = db.OpenTransaction()) - { - db.CreateTable(overwrite: true); - - var rows = new[] { - new PersonWithAutoId { - FirstName = "Jimi", - LastName = "Hendrix", - Age = 27 - }, - new PersonWithAutoId { - FirstName = "Kurt", - LastName = "Cobain", - Age = 27 - }, - }; - - db.Save(rows); - - Assert.That(rows[0].Id, Is.Not.EqualTo(0)); - Assert.That(rows[1].Id, Is.Not.EqualTo(0)); - Assert.That(rows[0].Id, Is.Not.EqualTo(rows[1].Id)); - - trans.Commit(); - } + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + using var trans = db.OpenTransaction(); + var rows = new[] { + new PersonWithAutoId { + FirstName = "Jimi", + LastName = "Hendrix", + Age = 27 + }, + new PersonWithAutoId { + FirstName = "Kurt", + LastName = "Cobain", + Age = 27 + }, + }; + + db.Save(rows); + + Assert.That(rows[0].Id, Is.Not.EqualTo(0)); + Assert.That(rows[1].Id, Is.Not.EqualTo(0)); + Assert.That(rows[0].Id, Is.Not.EqualTo(rows[1].Id)); + + trans.Commit(); } [Test] public void Can_Save_into_ModelWithFieldsOfDifferentTypes_table() { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + using var db = OpenDbConnection(); + db.CreateTable(true); - var row = ModelWithFieldsOfDifferentTypes.Create(1); + var row = ModelWithFieldsOfDifferentTypes.Create(1); - db.Save(row); + db.Save(row); + } + + [Test] + public void Can_SaveAll_As_An_Update_Into_Table_Without_Autoincrement_Key() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.SaveAll(Rockstar.Rockstars); + + var updatedRockstars = new[] + { + new Rockstar(6, "Jimi", "Hendrix", 27), + new Rockstar(5, "Janis", "Joplin", 27), + new Rockstar(4, "Jim", "Morrisson", 27), + new Rockstar(3, "Kurt", "Cobain", 27), + new Rockstar(2, "Elvis", "Presley", 42), + new Rockstar(1, "Michael", "Jackson", 50), + }; + db.SaveAll(updatedRockstars); + } + + public class Rockstar + { + public static Rockstar[] Rockstars = { + new Rockstar(1, "Jimi", "Hendrix", 27), + new Rockstar(2, "Janis", "Joplin", 27), + new Rockstar(3, "Jim", "Morrisson", 27), + new Rockstar(4, "Kurt", "Cobain", 27), + new Rockstar(5, "Elvis", "Presley", 42), + new Rockstar(6, "Michael", "Jackson", 50), + }; + + public long RockstarId { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public int Age { get; set; } + + public Rockstar() { } + public Rockstar(int id, string firstName, string lastName, int age) + { + RockstarId = id; + FirstName = firstName; + LastName = lastName; + Age = age; } } [Test] public void Can_Save_and_select_from_ModelWithFieldsOfDifferentTypes_table() { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + using var db = OpenDbConnection(); + db.CreateTable(true); - var row = ModelWithFieldsOfDifferentTypes.Create(1); + var row = ModelWithFieldsOfDifferentTypes.Create(1); - db.Save(row); + db.Save(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithFieldsOfDifferentTypes.AssertIsEqual(rows[0], row); - } + ModelWithFieldsOfDifferentTypes.AssertIsEqual(rows[0], row); } [Test] public void Can_SaveAll_and_select_from_ModelWithFieldsOfDifferentTypes_table() { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + using var db = OpenDbConnection(); + db.CreateTable(true); - var rowIds = new List { 1, 2, 3, 4, 5 }; - var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(x)); + var rowIds = new List { 1, 2, 3, 4, 5 }; + var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(x)); - db.SaveAll(newRows); + db.SaveAll(newRows); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(newRows.Count)); - } + Assert.That(rows, Has.Count.EqualTo(newRows.Count)); } [Test] public void Can_SaveAll_and_select_from_ModelWithFieldsOfDifferentTypes_table_with_no_ids() { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + using var db = OpenDbConnection(); + db.CreateTable(true); - var rowIds = new List { 1, 2, 3, 4, 5 }; - var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(default(int))); + var rowIds = new List { 1, 2, 3, 4, 5 }; + var newRows = rowIds.ConvertAll(x => ModelWithFieldsOfDifferentTypes.Create(default(int))); - db.SaveAll(newRows); + db.SaveAll(newRows); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(newRows.Count)); - } + Assert.That(rows, Has.Count.EqualTo(newRows.Count)); } [Test] public void Can_Save_table_with_null_fields() { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + using var db = OpenDbConnection(); + db.CreateTable(true); - var row = ModelWithIdAndName.Create(1); - row.Name = null; + var row = ModelWithIdAndName.Create(1); + row.Name = null; - db.Save(row); + db.Save(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - ModelWithIdAndName.AssertIsEqual(rows[0], row); - } + ModelWithIdAndName.AssertIsEqual(rows[0], row); } [Test] public void Can_Save_TaskQueue_table() { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + using var db = OpenDbConnection(); + db.CreateTable(true); - var row = TaskQueue.Create(1); + var row = TaskQueue.Create(1); - db.Save(row); + db.Save(row); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(1)); + Assert.That(rows, Has.Count.EqualTo(1)); - //Update the auto-increment id - row.Id = rows[0].Id; + //Update the auto-increment id + row.Id = rows[0].Id; - TaskQueue.AssertIsEqual(rows[0], row); - } + TaskQueue.AssertIsEqual(rows[0], row); } [Test] public void Can_SaveAll_and_select_from_Movie_table() { - using (var db = OpenDbConnection()) - { - db.CreateTable(true); + using var db = OpenDbConnection(); + db.CreateTable(true); - var top5Movies = new List - { - new Movie { Id = "tt0111161", Title = "The Shawshank Redemption", Rating = 9.2m, Director = "Frank Darabont", ReleaseDate = new DateTime(1995,2,17), TagLine = "Fear can hold you prisoner. Hope can set you free.", Genres = new List{"Crime","Drama"}, }, - new Movie { Id = "tt0068646", Title = "The Godfather", Rating = 9.2m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1972,3,24), TagLine = "An offer you can't refuse.", Genres = new List {"Crime","Drama", "Thriller"}, }, - new Movie { Id = "tt1375666", Title = "Inception", Rating = 9.2m, Director = "Christopher Nolan", ReleaseDate = new DateTime(2010,7,16), TagLine = "Your mind is the scene of the crime", Genres = new List{"Action", "Mystery", "Sci-Fi", "Thriller"}, }, - new Movie { Id = "tt0071562", Title = "The Godfather: Part II", Rating = 9.0m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1974,12,20), Genres = new List {"Crime","Drama", "Thriller"}, }, - new Movie { Id = "tt0060196", Title = "The Good, the Bad and the Ugly", Rating = 9.0m, Director = "Sergio Leone", ReleaseDate = new DateTime(1967,12,29), TagLine = "They formed an alliance of hate to steal a fortune in dead man's gold", Genres = new List{"Adventure","Western"}, }, - }; + var top5Movies = new List + { + new Movie { Id = "tt0111161", Title = "The Shawshank Redemption", Rating = 9.2m, Director = "Frank Darabont", ReleaseDate = new DateTime(1995,2,17), TagLine = "Fear can hold you prisoner. Hope can set you free.", Genres = new List{"Crime","Drama"}, }, + new Movie { Id = "tt0068646", Title = "The Godfather", Rating = 9.2m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1972,3,24), TagLine = "An offer you can't refuse.", Genres = new List {"Crime","Drama", "Thriller"}, }, + new Movie { Id = "tt1375666", Title = "Inception", Rating = 9.2m, Director = "Christopher Nolan", ReleaseDate = new DateTime(2010,7,16), TagLine = "Your mind is the scene of the crime", Genres = new List{"Action", "Mystery", "Sci-Fi", "Thriller"}, }, + new Movie { Id = "tt0071562", Title = "The Godfather: Part II", Rating = 9.0m, Director = "Francis Ford Coppola", ReleaseDate = new DateTime(1974,12,20), Genres = new List {"Crime","Drama", "Thriller"}, }, + new Movie { Id = "tt0060196", Title = "The Good, the Bad and the Ugly", Rating = 9.0m, Director = "Sergio Leone", ReleaseDate = new DateTime(1967,12,29), TagLine = "They formed an alliance of hate to steal a fortune in dead man's gold", Genres = new List{"Adventure","Western"}, }, + }; - db.SaveAll(top5Movies); + db.SaveAll(top5Movies); - var rows = db.Select(); + var rows = db.Select(); - Assert.That(rows, Has.Count.EqualTo(top5Movies.Count)); - } + Assert.That(rows, Has.Count.EqualTo(top5Movies.Count)); } [Test] public void Can_Save_Update_Into_Table_With_Id_Only() { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + using var db = OpenDbConnection(); + db.DropAndCreateTable(); - db.Save(new ModelWithIdOnly(1)); + db.Save(new ModelWithIdOnly(1)); - db.Save(new ModelWithIdOnly(1)); + db.Save(new ModelWithIdOnly(1)); - db.Update(new ModelWithIdOnly(1)); - } + db.Update(new ModelWithIdOnly(1)); } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteSelectTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteSelectTests.cs index cee0663a0..7ba793b6d 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteSelectTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteSelectTests.cs @@ -3,25 +3,25 @@ using System.Diagnostics; using System.Linq; using NUnit.Framework; -using ServiceStack.Common; using ServiceStack.Common.Tests.Models; +using ServiceStack.OrmLite.Tests.Expression; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteSelectTests - : OrmLiteTestBase - { - - [Test] - public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { + [TestFixtureOrmLite] + public class OrmLiteSelectTests : OrmLiteProvidersTestBase + { + public OrmLiteSelectTests(DialectContext context) : base(context) { } + + [Test] + public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { 1, 2, 3 }); + var rowIds = new List(new[] { 1, 2, 3 }); for (var i = 0; i < rowIds.Count; i++) rowIds[i] = (int)db.Insert(ModelWithFieldsOfDifferentTypes.Create(rowIds[i]), selectIdentity: true); @@ -29,124 +29,124 @@ public void Can_GetById_int_from_ModelWithFieldsOfDifferentTypes_table() var row = db.SingleById(rowIds[1]); Assert.That(row.Id, Is.EqualTo(rowIds[1])); - } - } - - [Test] - public void Can_GetById_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + } + } + + [Test] + public void Can_GetById_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); var row = db.SingleById("id-1"); - Assert.That(row.Id, Is.EqualTo("id-1")); - } - } + Assert.That(row.Id, Is.EqualTo("id-1")); + } + } - [Test] - public void Can_GetByIds_int_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { + [Test] + public void Can_GetByIds_int_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { 1, 2, 3 }); + var rowIds = new List(new[] { 1, 2, 3 }); for (var i = 0; i < rowIds.Count; i++) rowIds[i] = (int)db.Insert(ModelWithFieldsOfDifferentTypes.Create(rowIds[i]), selectIdentity: true); - var rows = db.SelectByIds(rowIds); - var dbRowIds = rows.ConvertAll(x => x.Id); + var rows = db.SelectByIds(rowIds); + var dbRowIds = rows.ConvertAll(x => x.Id); Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } - - [Test] - public void Can_GetByIds_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + } + } + + [Test] + public void Can_GetByIds_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - var rows = db.SelectByIds(rowIds); - var dbRowIds = rows.ConvertAll(x => x.Id); + var rows = db.SelectByIds(rowIds); + var dbRowIds = rows.ConvertAll(x => x.Id); - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } - [Test] - public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + [Test] + public void Can_select_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; - db.Insert(filterRow); + db.Insert(filterRow); - var rows = db.SelectFmt("AlbumName".SqlColumn() + " = {0}", filterRow.AlbumName); - var dbRowIds = rows.ConvertAll(x => x.Id); + var rows = db.Select("AlbumName".SqlColumn(DialectProvider) + " = @album".PreNormalizeSql(db), new { album = filterRow.AlbumName }); + var dbRowIds = rows.ConvertAll(x => x.Id); - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } - [Test] - public void Can_select_scalar_value() - { - const int n = 5; + [Test] + public void Can_select_scalar_value() + { + const int n = 5; - using (var db = OpenDbConnection()) - { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - var count = db.ScalarFmt("SELECT COUNT(*) FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); + var count = db.Scalar("SELECT COUNT(*) FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); - Assert.That(count, Is.EqualTo(n)); - } - } + Assert.That(count, Is.EqualTo(n)); + } + } - [Test] - public void Can_loop_each_string_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + [Test] + public void Can_loop_each_string_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - var dbRowIds = new List(); - foreach (var row in db.SelectLazy()) - { - dbRowIds.Add(row.Id); - } + var dbRowIds = new List(); + foreach (var row in db.SelectLazy()) + { + dbRowIds.Add(row.Id); + } - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } [Test] public void Can_loop_each_string_from_ModelWithOnlyStringFields_table_Column() @@ -170,201 +170,261 @@ public void Can_loop_each_string_from_ModelWithOnlyStringFields_table_Column() } } - [Test] - public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() - { - using (var db = OpenDbConnection()) - { + [Test] + public void Can_loop_each_with_filter_from_ModelWithOnlyStringFields_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); + var rowIds = new List(new[] { "id-1", "id-2", "id-3" }); - rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); + rowIds.ForEach(x => db.Insert(ModelWithOnlyStringFields.Create(x))); - var filterRow = ModelWithOnlyStringFields.Create("id-4"); - filterRow.AlbumName = "FilteredName"; + var filterRow = ModelWithOnlyStringFields.Create("id-4"); + filterRow.AlbumName = "FilteredName"; - db.Insert(filterRow); + db.Insert(filterRow); - var dbRowIds = new List(); - var rows = db.SelectLazyFmt("AlbumName".SqlColumn() + " = {0}", filterRow.AlbumName); - foreach (var row in rows) - { - dbRowIds.Add(row.Id); - } + var dbRowIds = new List(); + var rows = db.SelectLazy("AlbumName".SqlColumn(DialectProvider) + " = @AlbumName".PreNormalizeSql(db), new { filterRow.AlbumName }); + foreach (var row in rows) + { + dbRowIds.Add(row.Id); + } - Assert.That(dbRowIds, Has.Count.EqualTo(1)); - Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); - } - } + Assert.That(dbRowIds, Has.Count.EqualTo(1)); + Assert.That(dbRowIds[0], Is.EqualTo(filterRow.Id)); + } + } - [Test] - public void Can_GetFirstColumn() - { - const int n = 5; + [Test] + public void Can_GetFirstColumn() + { + const int n = 5; - using (var db = OpenDbConnection()) - { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - var ids = db.ColumnFmt("SELECT Id FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); + var ids = db.Column("SELECT Id FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); - Assert.That(ids.Count, Is.EqualTo(n)); - } - } + Assert.That(ids.Count, Is.EqualTo(n)); + } + } - [Test] - public void Can_GetFirstColumnDistinct() - { - const int n = 5; + [Test] + public void Can_GetFirstColumnDistinct() + { + const int n = 5; - using (var db = OpenDbConnection()) - { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - var ids = db.ColumnDistinctFmt("SELECT Id FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); + var ids = db.ColumnDistinct("SELECT Id FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); - Assert.That(ids.Count, Is.EqualTo(n)); - } - } + Assert.That(ids.Count, Is.EqualTo(n)); + } + } - [Test] - public void Can_GetLookup() - { - const int n = 5; + [Test] + public void Can_GetLookup() + { + const int n = 5; - using (var db = OpenDbConnection()) - { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - n.Times(x => { - var row = ModelWithIdAndName.Create(x); - row.Name = x % 2 == 0 ? "OddGroup" : "EvenGroup"; - db.Insert(row); - }); + n.Times(x => + { + var row = ModelWithIdAndName.Create(x); + row.Name = x % 2 == 0 ? "OddGroup" : "EvenGroup"; + db.Insert(row); + }); - var lookup = db.LookupFmt("SELECT Name, Id FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); + var lookup = db.Lookup("SELECT Name, Id FROM " + "ModelWithIdAndName".SqlTable(DialectProvider)); - Assert.That(lookup, Has.Count.EqualTo(2)); - Assert.That(lookup["OddGroup"], Has.Count.EqualTo(3)); - Assert.That(lookup["EvenGroup"], Has.Count.EqualTo(2)); - } - } + Assert.That(lookup, Has.Count.EqualTo(2)); + Assert.That(lookup["OddGroup"], Has.Count.EqualTo(3)); + Assert.That(lookup["EvenGroup"], Has.Count.EqualTo(2)); + } + } - [Test] - public void Can_GetDictionary() - { - const int n = 5; + [Test] + public void Can_GetDictionary() + { + const int n = 5; - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - var dictionary = db.Dictionary("SELECT Id, Name FROM {0}".Fmt("ModelWithIdAndName".SqlTable())); + var dictionary = db.Dictionary("SELECT Id, Name FROM {0}".Fmt("ModelWithIdAndName".SqlTable(DialectProvider))); - Assert.That(dictionary, Has.Count.EqualTo(5)); + Assert.That(dictionary, Has.Count.EqualTo(5)); - //Console.Write(dictionary.Dump()); - } - } + //Console.Write(dictionary.Dump()); + } + } - [Test] - public void Can_Select_subset_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() - { - using (var db = OpenDbConnection()) - { + [Test] + [IgnoreDialect(Tests.Dialect.AnyOracle, "Oracle provider doesn't modify user supplied SQL to conform to name length restrictions")] + public void Can_Select_subset_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() + { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - var rowIds = new List(new[] { 1, 2, 3 }); + var rowIds = new List(new[] { 1, 2, 3 }); for (var i = 0; i < rowIds.Count; i++) rowIds[i] = (int)db.Insert(ModelWithFieldsOfDifferentTypes.Create(rowIds[i]), selectIdentity: true); - SuppressIfOracle("Oracle provider doesn't modify user supplied SQL to conform to name length restrictions"); + var rows = db.Select("SELECT Id, Name FROM " + "ModelWithFieldsOfDifferentTypes".SqlTable(DialectProvider)); + var dbRowIds = rows.ConvertAll(x => x.Id); - var rows = db.SelectFmt("SELECT Id, Name FROM {0}".Fmt("ModelWithFieldsOfDifferentTypes".SqlTable())); - var dbRowIds = rows.ConvertAll(x => x.Id); - - Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } + Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); + } + } - [Test] - public void Can_Select_Into_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() - { + [Test] + public void Can_Select_Into_ModelWithIdAndName_from_ModelWithFieldsOfDifferentTypes_table() + { using (var db = OpenDbConnection()) - { + { db.DropAndCreateTable(); - var rowIds = new List(new[] { 1, 2, 3 }); + var rowIds = new List(new[] { 1, 2, 3 }); for (var i = 0; i < rowIds.Count; i++) rowIds[i] = (int)db.Insert(ModelWithFieldsOfDifferentTypes.Create(rowIds[i]), selectIdentity: true); - - var rows = db.Select(typeof(ModelWithFieldsOfDifferentTypes)); - var dbRowIds = rows.ConvertAll(x => x.Id); + + var rows = db.Select(typeof(ModelWithFieldsOfDifferentTypes)); + var dbRowIds = rows.ConvertAll(x => x.Id); Assert.That(dbRowIds, Is.EquivalentTo(rowIds)); - } - } + } + } - [Test] - public void Can_Select_In_for_string_value() - { - const int n = 5; + [Test] + public void Can_Select_In_for_string_value() + { + const int n = 5; - using (var db = OpenDbConnection()) - { + using (var db = OpenDbConnection()) + { db.DropAndCreateTable(); - n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); - - var selectInNames = new[] {"Name1", "Name2"}; - var rows = db.SelectFmt("Name IN ({0})", selectInNames.SqlInValues()); - - Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); - } - } - - public class PocoFlag - { - public string Name { get; set; } - public bool Flag { get; set; } - } - - [Test] - public void Can_populate_PocoFlag() - { - using (var db = OpenDbConnection()) - { - var rows = db.SelectFmt("SELECT 1 as Flag"); - Assert.That(rows[0].Flag); - } - } - - public class PocoFlagWithId - { - public int Id { get; set; } - public bool Flag { get; set; } - } - - [Test] - public void Can_populate_PocoFlagWithId() - { - using (var db = OpenDbConnection()) - { - var rows = db.SelectFmt("SELECT 1 as Id, 1 as Flag"); - Assert.That(rows[0].Id, Is.EqualTo(1)); - Assert.That(rows[0].Flag); - } - } + n.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var selectInNames = new[] { "Name1", "Name2" }; + var rows = db.Select("Name IN ({0})".Fmt(selectInNames.SqlInParams(DialectProvider)), + new { values = selectInNames.SqlInValues(DialectProvider) }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + + rows = db.Select("Name IN (@values)", + new { values = selectInNames }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + + rows = db.Select("Name IN (@p1, @p2)".PreNormalizeSql(db), new { p1 = "Name1", p2 = "Name2" }); + Assert.That(rows.Count, Is.EqualTo(selectInNames.Length)); + } + } + + [Test] + public void Can_select_IN_using_array_or_List_params() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + 5.Times(x => db.Insert(ModelWithIdAndName.Create(x))); + + var names = new[] { "Name2", "Name3" }; + var rows = db.Select("Name IN (@names)", new { names }); + Assert.That(rows.Count, Is.EqualTo(2)); + Assert.That(rows.Map(x => x.Name), Is.EquivalentTo(names)); + + var ids = new List { 2, 3 }; + rows = db.Select("Id IN (@ids)", new { ids }); + Assert.That(rows.Count, Is.EqualTo(2)); + Assert.That(rows.Map(x => x.Id), Is.EquivalentTo(ids)); + } + } + + [Test] + public void Can_use_array_param_for_ExecuteSql() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + 5.Times(x => db.Insert(ModelWithIdAndName.Create(x + 1))); + + var q = db.From(); + + db.ExecuteSql($"UPDATE {q.Table()} SET Name = 'updated' WHERE Id IN (@ids)", + new { ids = new[] { 1, 2, 3 } }); + + var count = db.Count(x => x.Name == "updated"); + Assert.That(count, Is.EqualTo(3)); + + db.ExecuteSql($"UPDATE {q.Table()} SET Name = 'updated' WHERE Name IN (@names)", + new { names = new[] { "Name4", "Name5" } }); + + count = db.Count(x => x.Name == "updated"); + Assert.That(count, Is.EqualTo(5)); + } + } + + public class PocoFlag + { + public string Name { get; set; } + public bool Flag { get; set; } + } + + [Test] + public void Can_populate_PocoFlag() + { + using (var db = OpenDbConnection()) + { + var fromDual = ""; + if (Dialect == Dialect.Firebird) + fromDual = " FROM RDB$DATABASE"; + + var rows = db.Select("SELECT 1 as Flag" + fromDual); + Assert.That(rows[0].Flag); + } + } + + public class PocoFlagWithId + { + public int Id { get; set; } + public bool Flag { get; set; } + } + + [Test] + public void Can_populate_PocoFlagWithId() + { + using (var db = OpenDbConnection()) + { + var fromDual = ""; + if (Dialect == Dialect.Firebird) + fromDual = " FROM RDB$DATABASE"; + + var rows = db.Select("SELECT 1 as Id, 1 as Flag" + fromDual); + + Assert.That(rows[0].Id, Is.EqualTo(1)); + Assert.That(rows[0].Flag); + } + } public class TypeWithTimeSpan { @@ -388,9 +448,9 @@ public void Can_handle_TimeSpans() } } - [Test] - public void Does_return_correct_numeric_values() - { + [Test] + public void Does_return_correct_numeric_values() + { using (var db = OpenDbConnection()) { db.DropAndCreateTable(); @@ -405,25 +465,159 @@ public void Does_return_correct_numeric_values() Assert.That(row.Int, Is.EqualTo(fromDb.Int)); Assert.That(row.Long, Is.EqualTo(fromDb.Long)); Assert.That(row.Float, Is.EqualTo(fromDb.Float)); - Assert.That(row.Double, Is.EqualTo(fromDb.Double)); + Assert.That(row.Double, Is.EqualTo(fromDb.Double).Within(1d)); Assert.That(row.Decimal, Is.EqualTo(fromDb.Decimal)); } } - [TestCase(1E125)] - [TestCase(-1E125)] - public void Does_return_large_double_values(double value) - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - var expected = new ModelWithDifferentNumTypes {Double = value}; + [Test] + public void Does_not_evaluate_SqlFmt_when_no_params() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithIdAndName(1) { Name = "{test}" }); + + var rows = db.Select("Name = '{test}'"); + + Assert.That(rows.Count, Is.EqualTo(1)); + } + } + + [TestCase(1E125)] + [TestCase(-1E125)] + public void Does_return_large_double_values(double value) + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var expected = new ModelWithDifferentNumTypes { Double = value }; + + var id = db.Insert(expected, true); + var actual = db.SingleById(id); + + Assert.That(expected.Double, Is.EqualTo(actual.Double). + Or.EqualTo(-9.9999999999999992E+124d). + Or.EqualTo(9.9999999999999992E+124d)); //Firebird + } + } + + public class CustomSql + { + public int Id { get; set; } + public string Name { get; set; } + public int CustomMax { get; set; } + public int CustomCount { get; set; } + } + + [Test] + public void Does_project_Sql_columns() + { + OrmLiteConfig.BeforeExecFilter = cmd => cmd.GetDebugString().Print(); + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + db.Insert(AutoQueryTests.SeedRockstars); + db.Insert(AutoQueryTests.SeedAlbums); + + var q = db.From() + .Join() + .GroupBy(r => new { r.Id, r.FirstName, r.LastName }) + .Select((r, a) => new + { + r.Id, + Name = r.FirstName + " " + r.LastName, + CustomMax = Sql.Max(r.Id), + CustomCount = Sql.Count(r.Id > a.Id ? r.Id + 2 : a.Id + 2) + }); + + var results = db.Select(q); + var result = results[0]; + + // results.PrintDump(); + + Assert.That(result.Id, Is.GreaterThan(0)); + Assert.That(result.Name, Is.Not.Null); + Assert.That(result.CustomMax, Is.GreaterThan(0)); + Assert.That(result.CustomCount, Is.GreaterThan(0)); + } + + } + + [Test] + public void Can_select_from_Tasked_with_single_tags() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var parentId = db.Insert(new Tasked { Created = new DateTime(2000, 01, 01) }, selectIdentity: true); + db.Insert(new Tasked { ParentId = parentId, Created = new DateTime(2001, 01, 01) }, selectIdentity: true); + var tag = "Query Tasked"; + var q = db.From().TagWith(tag); + + Debug.Assert(q.Tags.Count == 1); + Debug.Assert(q.Tags.ToList()[0]== tag); + + var select = q.ToSelectStatement(); + Debug.Assert(select.Contains(tag)); + + var results = db.Select(q); + Debug.Assert(results.Count == 2); + } + } + + [Test] + public void Can_select_from_Tasked_with_multi_tags() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var parentId = db.Insert(new Tasked { Created = new DateTime(2000, 01, 01) }, selectIdentity: true); + db.Insert(new Tasked { ParentId = parentId, Created = new DateTime(2001, 01, 01) }, selectIdentity: true); + var tag1 = "Query Tasked 1"; + var tag2 = "Query Tasked 2"; + var q = db.From() + .TagWith(tag1) + .TagWith(tag2); + + Debug.Assert(q.Tags.Count == 2); + Debug.Assert(q.Tags.ToList()[0] == tag1); + Debug.Assert(q.Tags.ToList()[1] == tag2); + + var select = q.ToSelectStatement(); + Debug.Assert(select.Contains(tag1)); + Debug.Assert(select.Contains(tag2)); + + var results = db.Select(q); + Debug.Assert(results.Count == 2); + } + } + + [Test] + public void Can_select_from_Tasked_with_callsite_tags() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var parentId = db.Insert(new Tasked { Created = new DateTime(2000, 01, 01) }, selectIdentity: true); + db.Insert(new Tasked { ParentId = parentId, Created = new DateTime(2001, 01, 01) }, selectIdentity: true); - var id = db.Insert(expected, true); - var actual = db.SingleById(id); + var q = db.From().TagWithCallSite(nameof(OrmLiteSelectTests), 13); + var tag = $"File: {nameof(OrmLiteSelectTests)}:13"; + Debug.Assert(q.Tags.Count == 1); + Debug.Assert(q.Tags.ToList()[0] == tag); - Assert.That(expected.Double, Is.EqualTo(actual.Double)); - } - } - } + var select = q.ToSelectStatement(); + Debug.Assert(select.Contains(tag)); + + var results = db.Select(q); + Debug.Assert(results.Count == 2); + } + } + } } diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteTestBase.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteTestBase.cs index 27bdef697..cdff4a2e0 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteTestBase.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteTestBase.cs @@ -1,87 +1,110 @@ using System; +using System.Collections; using System.Data; using System.Data.Common; using System.IO; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.Logging; -using ServiceStack.OrmLite.Oracle; namespace ServiceStack.OrmLite.Tests { - public class Config +// public class Config +// { +// public static Dialect DefaultDialect = Dialect.Sqlite; +// public const bool EnableDebugLogging = false; +// +// public static string SqliteFileDir = "~/App_Data/".MapAbsolutePath(); +// public static string SqliteFileDb = "~/App_Data/db.sqlite".MapAbsolutePath(); +// public static string SqlServerDb = "~/App_Data/Database1.mdf".MapAbsolutePath(); +// //public static string SqlServerBuildDb = "Data Source=localhost;Initial Catalog=TestDb;Integrated Security=SSPI;Connect Timeout=120;MultipleActiveResultSets=True"; +// +// public static string SqliteMemoryDb = Environment.GetEnvironmentVariable("SQLITE_CONNECTION") ?? ":memory:"; +// public static string SqlServerBuildDb = Environment.GetEnvironmentVariable("MSSQL_CONNECTION") ?? "Data Source=tcp:localhost,48501\\SQLExpress;Initial Catalog=master;User Id=sa;Password=Test!tesT;Connect Timeout=120;MultipleActiveResultSets=True;"; +// public static string OracleDb = Environment.GetEnvironmentVariable("ORACLE_CONNECTION") ?? "Data Source=localhost:48401/XE;User ID=system;Password=test"; +// public static string MySqlDb_5_5 = Environment.GetEnvironmentVariable("MYSQL_CONNECTION") ?? "Server=localhost;Port=48201;Database=test;UID=root;Password=test;SslMode=none"; +// public static string MySqlDb_10_1 = Environment.GetEnvironmentVariable("MYSQL_CONNECTION") ?? "Server=localhost;Port=48202;Database=test;UID=root;Password=test;SslMode=none"; +// public static string MySqlDb_10_2 = Environment.GetEnvironmentVariable("MYSQL_CONNECTION") ?? "Server=localhost;Port=48203;Database=test;UID=root;Password=test;SslMode=none"; +// public static string MySqlDb_10_3 = Environment.GetEnvironmentVariable("MYSQL_CONNECTION") ?? "Server=localhost;Port=48204;Database=test;UID=root;Password=test;SslMode=none"; +// public static string MySqlDb_10_4 = Environment.GetEnvironmentVariable("MYSQL_CONNECTION") ?? "Server=localhost;Port=48205;Database=test;UID=root;Password=test;SslMode=none"; +// public static string PostgresDb_9 = Environment.GetEnvironmentVariable("PGSQL_CONNECTION") ?? "Server=localhost;Port=48301;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"; +// public static string PostgresDb_10 = Environment.GetEnvironmentVariable("PGSQL_CONNECTION") ?? "Server=localhost;Port=48302;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"; +// public static string PostgresDb_11 = Environment.GetEnvironmentVariable("PGSQL_CONNECTION") ?? "Server=localhost;Port=48303;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"; +// public static string FirebirdDb_3 = Environment.GetEnvironmentVariable("FIREBIRD_CONNECTION") ?? @"User=SYSDBA;Password=masterkey;Database=/firebird/data/test.gdb;DataSource=localhost;Port=48101;Dialect=3;charset=ISO8859_1;MinPoolSize=0;MaxPoolSize=100;"; +// +// public static IOrmLiteDialectProvider DefaultProvider = SqlServerDialect.Provider; +// public static string DefaultConnection = SqlServerBuildDb; +// +// public static string GetDefaultConnection() +// { +// OrmLiteConfig.DialectProvider = DefaultProvider; +// return DefaultConnection; +// } +// +// public static IDbConnection OpenDbConnection() +// { +// return GetDefaultConnection().OpenDbConnection(); +// } +// } + + public class OrmLiteTestBase { - public static string SqliteMemoryDb = ":memory:"; - public static string SqliteFileDir = "~/App_Data/".MapAbsolutePath(); - public static string SqliteFileDb = "~/App_Data/db.sqlite".MapAbsolutePath(); - public static string SqlServerDb = "~/App_Data/Database1.mdf".MapAbsolutePath(); - public static string SqlServerBuildDb = "Server={0};Database=test;User Id=test;Password=test;".Fmt(Environment.GetEnvironmentVariable("CI_HOST")); - //public static string SqlServerBuildDb = "Data Source=localhost;Initial Catalog=TestDb;Integrated Security=SSPI;Connect Timeout=120;MultipleActiveResultSets=True"; + protected virtual string ConnectionString { get; set; } - public static string OracleDb = "Data Source=localhost:1521/ormlite;User ID=test;Password=test"; - public static string MySqlDb = "Server=localhost;Database=test;UID=root;Password=test"; - public static string PostgreSqlDb = "Server=localhost;Port=5432;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200"; + public OrmLiteTestBase() { } - public static IOrmLiteDialectProvider DefaultProvider = SqlServerDialect.Provider; - public static string DefaultConnection = SqlServerBuildDb; - - public static string GetDefaultConnection() + public OrmLiteTestBase(Dialect dialect) { - OrmLiteConfig.DialectProvider = DefaultProvider; - return DefaultConnection; + Dialect = dialect; + Init(); } - public static IDbConnection OpenDbConnection() + protected string GetConnectionString() { - return GetDefaultConnection().OpenDbConnection(); + return GetFileConnectionString(); } - } - public class OrmLiteTestBase - { - protected virtual string ConnectionString { get; set; } - - public OrmLiteTestBase() {} - - public OrmLiteTestBase(Dialect dialect) - { - Dialect = dialect; - Init(); + public static OrmLiteConnectionFactory CreateSqliteMemoryDbFactory() + { + var dbFactory = new OrmLiteConnectionFactory(SqliteDb.MemoryConnection, SqliteDialect.Provider); + return dbFactory; } - protected string GetConnectionString() - { - return GetFileConnectionString(); - } + public static OrmLiteConnectionFactory CreateSqlServerDbFactory() + { + var dbFactory = new OrmLiteConnectionFactory(SqlServerDb.DefaultConnection, SqlServerDialect.Provider); + return dbFactory; + } - public static OrmLiteConnectionFactory CreateSqlServerDbFactory() - { - var dbFactory = new OrmLiteConnectionFactory(Config.SqlServerBuildDb, SqlServerDialect.Provider); - return dbFactory; - } + public static OrmLiteConnectionFactory CreateMySqlDbFactory() + { + var dbFactory = new OrmLiteConnectionFactory(MySqlDb.DefaultConnection, MySqlDialect.Provider); + return dbFactory; + } - public static OrmLiteConnectionFactory CreateSqliteMemoryDbFactory() + public static OrmLiteConnectionFactory CreatePostgreSqlDbFactory() { - var dbFactory = new OrmLiteConnectionFactory(Config.SqliteMemoryDb, SqliteDialect.Provider); + var dbFactory = new OrmLiteConnectionFactory(PostgreSqlDb.DefaultConnection, PostgreSqlDialect.Provider); return dbFactory; } - protected virtual string GetFileConnectionString() - { - var connectionString = Config.SqliteFileDb; - if (File.Exists(connectionString)) - File.Delete(connectionString); + protected virtual string GetFileConnectionString() + { + var connectionString = SqliteDb.FileConnection; + if (File.Exists(connectionString)) + File.Delete(connectionString); - return connectionString; - } + return connectionString; + } - protected void CreateNewDatabase() - { - if (ConnectionString.Contains(".sqlite")) - ConnectionString = GetFileConnectionString(); - } + protected void CreateNewDatabase() + { + if (ConnectionString.Contains(".sqlite")) + ConnectionString = GetFileConnectionString(); + } - public Dialect Dialect = Dialect.Sqlite; - protected OrmLiteConnectionFactory DbFactory; + public Dialect Dialect = TestConfig.Dialects; + protected OrmLiteConnectionFactory DbFactory; OrmLiteConnectionFactory Init(string connStr, IOrmLiteDialectProvider dialectProvider) { @@ -91,53 +114,66 @@ OrmLiteConnectionFactory Init(string connStr, IOrmLiteDialectProvider dialectPro return DbFactory; } - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { Init(); } + [OneTimeTearDown] + public void TestFixtureTearDown() + { + OrmLiteContext.Instance.ClearItems(); + } + private OrmLiteConnectionFactory Init() { - LogManager.LogFactory = new ConsoleLogFactory(debugEnabled: false); - switch (Dialect) - { - case Dialect.Sqlite: - var dbFactory = Init(Config.SqliteMemoryDb, SqliteDialect.Provider); - dbFactory.AutoDisposeConnection = false; - return dbFactory; - case Dialect.SqlServer: - return Init(Config.SqlServerBuildDb, SqlServerDialect.Provider); - case Dialect.MySql: - return Init(Config.MySqlDb, MySqlDialect.Provider); - case Dialect.PostgreSql: - return Init(Config.PostgreSqlDb, PostgreSqlDialect.Provider); - case Dialect.SqlServerMdf: - return Init(Config.SqlServerDb, SqlServerDialect.Provider); + //OrmLiteConfig.UseParameterizeSqlExpressions = false; + + //OrmLiteConfig.DeoptimizeReader = true; + LogManager.LogFactory = new ConsoleLogFactory(debugEnabled: TestConfig.EnableDebugLogging); + + switch (Dialect) + { + case Dialect.Sqlite: + var dbFactory = Init(SqliteDb.MemoryConnection, SqliteDialect.Provider); + dbFactory.AutoDisposeConnection = false; + return dbFactory; + case Dialect.SqlServer: + return Init(SqlServerDb.DefaultConnection, SqlServerDialect.Provider); + case Dialect.SqlServer2012: + return Init(SqlServerDb.DefaultConnection, SqlServer2012Dialect.Provider); + case Dialect.SqlServer2014: + return Init(SqlServerDb.DefaultConnection, SqlServer2014Dialect.Provider); + case Dialect.SqlServer2016: + return Init(SqlServerDb.DefaultConnection, SqlServer2016Dialect.Provider); + case Dialect.SqlServer2017: + return Init(SqlServerDb.DefaultConnection, SqlServer2017Dialect.Provider); + case Dialect.SqlServer2019: + return Init(SqlServerDb.DefaultConnection, SqlServer2019Dialect.Provider); + case Dialect.MySql: + return Init(MySqlDb.DefaultConnection, MySqlDialect.Provider); + case Dialect.PostgreSql9: + case Dialect.PostgreSql10: + case Dialect.PostgreSql11: + return Init(PostgreSqlDb.DefaultConnection, PostgreSqlDialect.Provider); +// case Dialect.SqlServerMdf: +// return Init(Config.SqlServerDb, SqlServerDialect.Provider); case Dialect.Oracle: - return Init(Config.OracleDb, OracleDialect.Provider); - case Dialect.VistaDb: - VistaDbDialect.Provider.UseLibraryFromGac = true; - var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["myVDBConnection"]; - var factory = DbProviderFactories.GetFactory(connectionString.ProviderName); - using (var db = factory.CreateConnection()) - using (var cmd = db.CreateCommand()) - { - var tmpFile = Path.GetTempPath().CombineWith(Guid.NewGuid().ToString("n") + ".vb5"); - cmd.CommandText = @"CREATE DATABASE '|DataDirectory|{0}', PAGE SIZE 4, LCID 1033, CASE SENSITIVE FALSE;" - .Fmt(tmpFile); - cmd.ExecuteNonQuery(); - return Init("Data Source={0};".Fmt(tmpFile), VistaDbDialect.Provider); - } + return Init(OracleDb.DefaultConnection, OracleDialect.Provider); + case Dialect.Firebird: + return Init(FirebirdDb.DefaultConnection, FirebirdDialect.Provider); + case Dialect.Firebird4: + return Init(FirebirdDb.V4Connection, Firebird4Dialect.Provider); } throw new NotImplementedException("{0}".Fmt(Dialect)); - } + } - public void Log(string text) - { - Console.WriteLine(text); - } + public void Log(string text) + { + Console.WriteLine(text); + } public IDbConnection InMemoryDbConnection { get; set; } @@ -156,9 +192,24 @@ public virtual IDbConnection OpenDbConnection() return DbFactory.OpenDbConnection(); } + public virtual Task OpenDbConnectionAsync() + { + if (ConnectionString == ":memory:") + { + if (InMemoryDbConnection == null || DbFactory.AutoDisposeConnection) + { + InMemoryDbConnection = new OrmLiteConnection(DbFactory); + InMemoryDbConnection.Open(); + } + return Task.FromResult(InMemoryDbConnection); + } + + return DbFactory.OpenDbConnectionAsync(); + } + protected void SuppressIfOracle(string reason, params object[] args) { // Not Oracle if this base class used } - } + } } diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteTransactionTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteTransactionTests.cs index 8f442c353..d86e66385 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteTransactionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteTransactionTests.cs @@ -1,16 +1,17 @@ using System; +using System.Data; using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Sqlite; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteTransactionTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteTransactionTests : OrmLiteProvidersTestBase { + public OrmLiteTransactionTests(DialectContext context) : base(context) {} + [Test] public void Transaction_commit_persists_data_to_the_db() { @@ -42,6 +43,8 @@ public void Transaction_commit_persists_data_to_the_db() [Test] public void Transaction_rollsback_if_not_committed() { + if (Dialect == Dialect.Firebird) return; //Keeps Table locked + using (var db = OpenDbConnection()) { db.DropAndCreateTable(); @@ -64,6 +67,8 @@ public void Transaction_rollsback_if_not_committed() [Test] public void Transaction_rollsback_transactions_to_different_tables() { + if (Dialect == Dialect.Firebird) return; //Keeps Table locked + using (var db = OpenDbConnection()) { db.DropAndCreateTable(); @@ -214,8 +219,17 @@ public void Does_allow_setting_transactions_on_raw_DbCommands() { dbCmd.Transaction = trans.ToDbTransaction(); - dbCmd.CommandText = "INSERT INTO {0} ({1}) VALUES ('From OrmLite DB Command')" - .Fmt("MyTable".SqlTable(), "SomeTextField".SqlColumn()); + if (Dialect != Dialect.Firebird) + { + dbCmd.CommandText = "INSERT INTO {0} ({1}) VALUES ('From OrmLite DB Command')" + .Fmt("MyTable".SqlTable(DialectProvider), "SomeTextField".SqlColumn(DialectProvider)); + } + else + { + dbCmd.CommandText = "INSERT INTO {0} ({1},{2}) VALUES (2,'From OrmLite DB Command')" + .Fmt("MyTable".SqlTable(DialectProvider), "Id".SqlColumn(DialectProvider), "SomeTextField".SqlColumn(DialectProvider)); + } + dbCmd.ExecuteNonQuery(); } @@ -239,8 +253,17 @@ public void Can_use_OpenCommand_in_Transaction() using (var dbCmd = db.OpenCommand()) { - dbCmd.CommandText = "INSERT INTO {0} ({1}) VALUES ('From OrmLite DB Command')" - .Fmt("MyTable".SqlTable(), "SomeTextField".SqlColumn()); + if (Dialect != Dialect.Firebird) + { + dbCmd.CommandText = "INSERT INTO {0} ({1}) VALUES ('From OrmLite DB Command')" + .Fmt("MyTable".SqlTable(DialectProvider), "SomeTextField".SqlColumn(DialectProvider)); + } + else + { + dbCmd.CommandText = "INSERT INTO {0} ({1},{2}) VALUES (2,'From OrmLite DB Command')" + .Fmt("MyTable".SqlTable(DialectProvider), "Id".SqlColumn(DialectProvider), "SomeTextField".SqlColumn(DialectProvider)); + } + dbCmd.ExecuteNonQuery(); } @@ -250,6 +273,42 @@ public void Can_use_OpenCommand_in_Transaction() Assert.That(db.Count(), Is.EqualTo(2)); } } + + public class TestRollback + { + [AutoIncrement] + public int Id { get; set; } + + [Required] + public string Data { get; set; } + } + + [Test] + public void Does_rollback_Serializable_transaction() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) + { + try + { + var test = new TestRollback(); + //test.Data = "This is test1"; + var saved = db.Save(test); //This will fail because test.Data is required + transaction.Commit(); + } + catch (Exception e) + { + transaction.Rollback(); + } + } + + var rows = db.Select(); + Assert.That(rows.Count, Is.EqualTo(0)); + } + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteUpdateTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteUpdateTests.cs index 9b90e6f32..fe74aa2b2 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteUpdateTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteUpdateTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.Common.Tests.Models; using ServiceStack.DataAnnotations; @@ -10,25 +11,12 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class OrmLiteUpdateTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteUpdateTests : OrmLiteProvidersTestBase { - private IDbConnection db; + public OrmLiteUpdateTests(DialectContext context) : base(context) {} - [SetUp] - public void SetUp() - { - db = OpenDbConnection(); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - - private ModelWithFieldsOfDifferentTypes CreateModelWithFieldsOfDifferentTypes() + private ModelWithFieldsOfDifferentTypes CreateModelWithFieldsOfDifferentTypes(IDbConnection db) { db.DropAndCreateTable(); @@ -39,7 +27,8 @@ private ModelWithFieldsOfDifferentTypes CreateModelWithFieldsOfDifferentTypes() [Test] public void Can_update_ModelWithFieldsOfDifferentTypes_table() { - var row = CreateModelWithFieldsOfDifferentTypes(); + using var db = OpenDbConnection(); + var row = CreateModelWithFieldsOfDifferentTypes(db); row.Id = (int)db.Insert(row, selectIdentity: true); @@ -53,15 +42,16 @@ public void Can_update_ModelWithFieldsOfDifferentTypes_table() } [Test] - public void Can_update_ModelWithFieldsOfDifferentTypes_table_with_filter() + public void Can_update_ModelWithFieldsOfDifferentTypes_table_with_commandFilter() { - var row = CreateModelWithFieldsOfDifferentTypes(); + using var db = OpenDbConnection(); + var row = CreateModelWithFieldsOfDifferentTypes(db); row.Id = (int)db.Insert(row, selectIdentity: true); row.Name = "UpdatedName"; - db.Update(row, x => x.LongId <= row.LongId); + db.Update(row, cmd => cmd.CommandText.Print()); var dbRow = db.SingleById(row.Id); @@ -69,47 +59,34 @@ public void Can_update_ModelWithFieldsOfDifferentTypes_table_with_filter() } [Test] - public void Can_update_with_anonymousType_and_expr_filter() + public void Can_update_ModelWithFieldsOfDifferentTypes_table_with_filter() { - var row = CreateModelWithFieldsOfDifferentTypes(); + using var db = OpenDbConnection(); + var row = CreateModelWithFieldsOfDifferentTypes(db); row.Id = (int)db.Insert(row, selectIdentity: true); - row.DateTime = DateTime.Now; - row.Name = "UpdatedName"; - - db.Update(new { row.Name, row.DateTime }, - x => x.LongId >= row.LongId && x.LongId <= row.LongId); - - var dbRow = db.SingleById(row.Id); - Console.WriteLine(dbRow.Dump()); - ModelWithFieldsOfDifferentTypes.AssertIsEqual(dbRow, row); - } - - [Test] - public void Can_update_with_optional_string_params() - { - var row = CreateModelWithFieldsOfDifferentTypes(); - row.Id = (int)db.Insert(row, selectIdentity: true); row.Name = "UpdatedName"; - db.UpdateFmt(set: "NAME = {0}".SqlFmt(row.Name), where: "LongId".SqlColumn() + " <= {0}".SqlFmt(row.LongId)); + db.Update(row, x => x.Long <= row.Long); var dbRow = db.SingleById(row.Id); - Console.WriteLine(dbRow.Dump()); + ModelWithFieldsOfDifferentTypes.AssertIsEqual(dbRow, row); } [Test] - public void Can_update_with_tableName_and_optional_string_params() + public void Can_update_with_anonymousType_and_expr_filter() { - var row = CreateModelWithFieldsOfDifferentTypes(); + using var db = OpenDbConnection(); + var row = CreateModelWithFieldsOfDifferentTypes(db); row.Id = (int)db.Insert(row, selectIdentity: true); + row.DateTime = DateTime.Now; row.Name = "UpdatedName"; - db.UpdateFmt(table: "ModelWithFieldsOfDifferentTypes".SqlTableRaw(), - set: "NAME = {0}".SqlFmt(row.Name), where: "LongId".SqlColumn() + " <= {0}".SqlFmt(row.LongId)); + db.Update(new { row.Name, row.DateTime }, + x => x.Long >= row.Long && x.Long <= row.Long); var dbRow = db.SingleById(row.Id); Console.WriteLine(dbRow.Dump()); @@ -119,6 +96,7 @@ public void Can_update_with_tableName_and_optional_string_params() [Test] public void Can_Update_Into_Table_With_Id_Only() { + using var db = OpenDbConnection(); db.CreateTable(true); var row1 = new ModelWithIdOnly(1); db.Insert(row1); @@ -129,6 +107,7 @@ public void Can_Update_Into_Table_With_Id_Only() [Test] public void Can_Update_Many_Into_Table_With_Id_Only() { + using var db = OpenDbConnection(); db.CreateTable(true); var row1 = new ModelWithIdOnly(1); var row2 = new ModelWithIdOnly(2); @@ -143,30 +122,122 @@ public void Can_Update_Many_Into_Table_With_Id_Only() [Test] public void Can_UpdateOnly_multiple_columns() { + using var db = OpenDbConnection(); db.DropAndCreateTable(); - db.Insert(new Person { FirstName = "FirstName", Age = 100 }); + db.Insert(new Person { FirstName = "FirstName", Age = 100, LastName = "Original" }); var existingPerson = db.Select().First(); + existingPerson.LastName = "Updated"; existingPerson.FirstName = "JJ"; existingPerson.Age = 12; - db.UpdateOnly(existingPerson, + db.UpdateOnlyFields(existingPerson, onlyFields: p => new { p.FirstName, p.Age }); var person = db.Select().First(); Assert.That(person.FirstName, Is.EqualTo("JJ")); Assert.That(person.Age, Is.EqualTo(12)); + Assert.That(person.LastName, Is.EqualTo("Original")); + } + + [Test] + public void Supports_different_ways_to_UpdateOnly() + { + void Reset(IDbConnection db) + { + db.DeleteAll(); + db.Insert(new Person {Id = 1, FirstName = "OriginalFirst", LastName = "OriginalLast", Age = 100}); + } + + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + Reset(db); + db.UpdateOnly(() => new Person { FirstName = "UpdatedFirst", Age = 27 }); + var row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + db.UpdateOnlyFields(new Person { FirstName = "UpdatedFirst", Age = 27 }, p => p.FirstName); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 100))); + + Reset(db); + db.UpdateOnlyFields(new Person { FirstName = "UpdatedFirst", Age = 27 }, p => new { p.FirstName, p.Age }); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + db.UpdateOnlyFields(new Person { FirstName = "UpdatedFirst", Age = 27 }, new[] { "FirstName", "Age" }); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + db.UpdateOnly(() => new Person { FirstName = "UpdatedFirst", Age = 27 }, db.From().Where(x => x.Age == 100)); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + var q = db.From().Where(x => x.Age == 100); + db.UpdateOnly(() => new Person { FirstName = "UpdatedFirst", Age = 27 }, q.WhereExpression, q.Params); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + } + + [Test] + public async Task Supports_different_ways_to_UpdateOnly_Async() + { + void Reset(IDbConnection db) + { + db.DeleteAll(); + db.Insert(new Person {Id = 1, FirstName = "OriginalFirst", LastName = "OriginalLast", Age = 100}); + } + + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + + Reset(db); + await db.UpdateOnlyAsync(() => new Person { FirstName = "UpdatedFirst", Age = 27 }); + var row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "UpdatedFirst", Age = 27 }, p => p.FirstName); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 100))); + + Reset(db); + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "UpdatedFirst", Age = 27 }, p => new { p.FirstName, p.Age }); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + await db.UpdateOnlyFieldsAsync(new Person { FirstName = "UpdatedFirst", Age = 27 }, new[] { "FirstName", "Age" }); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + await db.UpdateOnlyAsync(() => new Person { FirstName = "UpdatedFirst", Age = 27 }, db.From().Where(x => x.Age == 100)); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); + + Reset(db); + var q = db.From().Where(x => x.Age == 100); + await db.UpdateOnlyAsync(() => new Person { FirstName = "UpdatedFirst", Age = 27 }, q.WhereExpression, q.Params); + row = db.Select().First(); + Assert.That(row, Is.EqualTo(new Person(1, "UpdatedFirst", "OriginalLast", 27))); } [Test] public void Can_Update_Only_Blobs() { + using var db = OpenDbConnection(); db.DropAndCreateTable(); - db.Insert(new SomeBlobs {FirstName = "Bro", LastName = "Last"}); + db.Insert(new SomeBlobs { FirstName = "Bro", LastName = "Last" }); db.Insert(new SomeBlobs { FirstName = "Sis", LastName = "Last" }); var existing = db.Select(p => p.FirstName == "Bro").First(); @@ -183,7 +254,7 @@ public void Can_Update_Only_Blobs() existing.Blob2 = new byte[blob2Bytes]; Buffer.BlockCopy(blob2Array, 0, existing.Blob2, 0, blob2Bytes); - db.UpdateOnly(existing, p => new {p.Blob1, p.Blob2, p.FirstName}, r => r.LastName == "Last" && r.FirstName == "Bro"); + db.UpdateOnlyFields(existing, p => new { p.Blob1, p.Blob2, p.FirstName }, r => r.LastName == "Last" && r.FirstName == "Bro"); var verify = db.Select(p => p.FirstName == "Bro").First(); @@ -193,6 +264,632 @@ public void Can_Update_Only_Blobs() Assert.That(existing.Blob1, Is.EquivalentTo(verify.Blob1)); Assert.That(existing.Blob2, Is.EquivalentTo(verify.Blob2)); } + + public class PocoWithBool + { + public int Id { get; set; } + public bool Bool { get; set; } + } + + public class PocoWithNullableBool + { + public int Id { get; set; } + public bool? Bool { get; set; } + } + + [Test] + public void Can_UpdateOnly_bool_columns() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new PocoWithBool { Id = 1, Bool = false }); + var row = db.SingleById(1); + Assert.That(row.Bool, Is.False); + + db.UpdateNonDefaults(new PocoWithBool { Bool = true }, x => x.Id == 1); + row = db.SingleById(1); + Assert.That(row.Bool, Is.True); + + Assert.Throws(() => + db.UpdateNonDefaults(new PocoWithBool { Bool = false }, x => x.Id == 1)); + + db.UpdateOnlyFields(new PocoWithBool { Bool = false }, + onlyFields: x => x.Bool, + @where: x => x.Id == 1); + row = db.SingleById(1); + Assert.That(row.Bool, Is.False); + + db.UpdateOnly(() => new PocoWithBool { Bool = true }, + @where: x => x.Id == 1); + row = db.SingleById(1); + Assert.That(row.Bool, Is.True); + + db.UpdateOnly(() => new PocoWithBool { Bool = false }, + db.From().Where(x => x.Id == 1)); + row = db.SingleById(1); + Assert.That(row.Bool, Is.False); + } + + [Test] + public void Can_UpdateOnly_nullable_bool_columns() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new PocoWithNullableBool { Id = 1, Bool = true }); + var row = db.SingleById(1); + Assert.That(row.Bool, Is.True); + + db.UpdateNonDefaults(new PocoWithNullableBool { Bool = false }, x => x.Id == 1); + row = db.SingleById(1); + Assert.That(row.Bool, Is.False); + + db.UpdateOnly(() => new PocoWithNullableBool { Bool = true }, x => x.Id == 1); + row = db.SingleById(1); + Assert.That(row.Bool, Is.True); + + db.UpdateOnly(() => new PocoWithNullableBool { Bool = false }, + db.From().Where(x => x.Id == 1)); + row = db.SingleById(1); + Assert.That(row.Bool, Is.False); + } + + public class PocoWithNullableInt + { + public int Id { get; set; } + public int? Int { get; set; } + } + + [Test] + public void Can_UpdateOnly_nullable_int_columns() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new PocoWithNullableInt { Id = 1, Int = 1 }); + var row = db.SingleById(1); + Assert.That(row.Int, Is.EqualTo(1)); + + db.UpdateNonDefaults(new PocoWithNullableInt { Int = 0 }, x => x.Id == 1); + row = db.SingleById(1); + Assert.That(row.Int, Is.EqualTo(0)); + + db.UpdateOnly(() => new PocoWithNullableInt { Int = 1 }, x => x.Id == 1); + Assert.That(db.SingleById(1).Int, Is.EqualTo(1)); + db.UpdateOnly(() => new PocoWithNullableInt { Int = 0 }, x => x.Id == 1); + Assert.That(db.SingleById(1).Int, Is.EqualTo(0)); + } + + [Test] + public void Can_UpdateAdd_nullable_int_columns() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new PocoWithNullableInt { Id = 1, Int = 0 }); + var row = db.SingleById(1); + Assert.That(row.Int, Is.EqualTo(0)); + + db.UpdateAdd(() => new PocoWithNullableInt { Int = 1 }, x => x.Id == 1); + Assert.That(db.SingleById(1).Int, Is.EqualTo(1)); + db.UpdateAdd(() => new PocoWithNullableInt { Int = -1 }, x => x.Id == 1); + Assert.That(db.SingleById(1).Int, Is.EqualTo(0)); + } + + [Test] + public void Does_Save_nullable_bool() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new Shutdown { IsShutdownGraceful = null }); + var rows = db.Select(); + + Assert.That(rows.Count, Is.EqualTo(1)); + Assert.That(rows[0].IsShutdownGraceful, Is.Null); + } + + [Test] + public void Can_updated_with_ExecuteSql_and_db_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.Insert(new PocoUpdate { Id = 1, Name = "A" }); + db.Insert(new PocoUpdate { Id = 2, Name = "B" }); + + var paramString = DialectProvider.ParamString; + var table = db.GetDialectProvider().GetTableName(nameof(PocoUpdate)); + var sql = $"UPDATE {table} SET name = {paramString}name WHERE id = {paramString}id"; + var result = db.ExecuteSql(sql, new { id = 2, name = "UPDATED" }); + Assert.That(result, Is.EqualTo(1)); + + var row = db.SingleById(2); + Assert.That(row.Name, Is.EqualTo("UPDATED")); + + sql = $"UPDATE {table} SET name = {paramString}name WHERE id = {paramString}id"; + result = db.ExecuteSql(sql, new Dictionary { {"id", 2}, {"name", "RE-UPDATED" } }); + Assert.That(result, Is.EqualTo(1)); + + row = db.SingleById(2); + Assert.That(row.Name, Is.EqualTo("RE-UPDATED")); + } + + private class PocoUpdate + { + public int Id { get; set; } + public string Name { get; set; } + } + + [Test] + public void Does_Update_using_db_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("id=@id")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + } + + [Test] + public void Does_Update_anonymous_using_db_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + db.Update(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + } + + [Test] + public void Does_UpdateNonDefaults_using_db_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + } + + [Test] + public void Does_UpdateOnly_using_Object_Dictionary() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var fields = new Dictionary { + [nameof(Person.FirstName)] = "JJ", + [nameof(Person.LastName)] = null, + }; + + db.UpdateOnly(fields, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + Assert.That(row.LastName, Is.Null); + } + + [Test] + public void Does_UpdateOnly_using_Object_Dictionary_containing_Id() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var fields = new Dictionary { + [nameof(Person.Id)] = 1, + [nameof(Person.FirstName)] = "JJ", + [nameof(Person.LastName)] = null, + }; + + db.UpdateOnly(fields); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (id = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + Assert.That(row.LastName, Is.Null); + } + + [Test] + public async Task Does_UpdateOnly_using_Object_Dictionary_containing_Id_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + await db.InsertAllAsync(Person.Rockstars); + + var fields = new Dictionary { + [nameof(Person.Id)] = 1, + [nameof(Person.FirstName)] = "JJ", + [nameof(Person.LastName)] = null, + }; + + await db.UpdateOnlyAsync(fields); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (id = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + Assert.That(row.LastName, Is.Null); + } + + [Test] + public void Does_UpdateOnly_using_Object_Dictionary_and_id() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var fields = new Dictionary { + [nameof(Person.FirstName)] = "JJ", + [nameof(Person.LastName)] = null, + }; + + db.UpdateOnly(fields, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + Assert.That(row.LastName, Is.Null); + } + + [Test] + public async Task Does_UpdateOnly_using_Object_Dictionary_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var fields = new Dictionary { + [nameof(Person.FirstName)] = "JJ", + [nameof(Person.LastName)] = null, + }; + + await db.UpdateOnlyAsync(fields, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + Assert.That(row.LastName, Is.Null); + } + + [Test] + public void Does_UpdateOnly_using_db_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + } + + [Test] + public void Does_UpdateOnly_using_AssignmentExpression() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + db.UpdateOnly(() => new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (lastname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + + db.UpdateOnly(() => new Person { FirstName = "HH" }, + db.From().Where(p => p.LastName == "Hendrix")); + row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("HH")); + } + + [Test] + public void Does_UpdateAdd_using_AssignmentExpression() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var count = db.UpdateAdd(() => new Person { FirstName = "JJ", Age = 1 }, @where: p => p.LastName == "Hendrix"); + Assert.That(count, Is.EqualTo(1)); + + var hendrix = Person.Rockstars.First(x => x.LastName == "Hendrix"); + var kurt = Person.Rockstars.First(x => x.LastName == "Cobain"); + + var row = db.Single(p => p.LastName == "Hendrix"); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + Assert.That(row.Age, Is.EqualTo(hendrix.Age + 1)); + + count = db.UpdateAdd(() => new Person { FirstName = "KC", Age = hendrix.Age + 1 }, @where: p => p.LastName == "Cobain"); + Assert.That(count, Is.EqualTo(1)); + + row = db.Single(p => p.LastName == "Cobain"); + Assert.That(row.FirstName, Is.EqualTo("KC")); + Assert.That(row.Age, Is.EqualTo(kurt.Age + hendrix.Age + 1)); + } + + [Test] + public void Does_UpdateOnly_with_SqlExpression_using_db_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + db.UpdateOnlyFields(new Person { FirstName = "JJ" }, db.From().Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); + + var sql = db.GetLastSql().NormalizeSql(); + Assert.That(sql, Does.Contain("where (firstname = @0)")); + Assert.That(sql, Does.Contain("firstname=@firstname")); + + var row = db.SingleById(1); + Assert.That(row.FirstName, Is.EqualTo("JJ")); + } + + + [Test] + public void Can_UpdateOnly_aliased_fields() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.UpdateOnly(() => new PersonWithAliasedAge { Name = "Bob", Age = 30 }); + } + + [Test] + public void Can_UpdateOnly_fields_using_EnumAsInt() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + db.InsertOnly(() => new PersonUsingEnumAsInt { Name = "Gene", Gender = Gender.Female }); + db.UpdateOnly(() => new PersonUsingEnumAsInt { Name = "Gene", Gender = Gender.Male }); + + var saved = db.Single(p => p.Name == "Gene"); + Assert.That(saved.Name, Is.EqualTo("Gene")); + Assert.That(saved.Gender, Is.EqualTo(Gender.Male)); + } + + [Test] + public void Can_UpdateOnly_fields_case_insensitive() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + var hendrix = new Person(1, "Jimi", "Hendrix", 27); + db.Insert(hendrix); + + hendrix.FirstName = "JJ"; + hendrix.LastName = "Ignored"; + + var q = db.From().Update(new[] { "FIRSTNAME" }); + + db.UpdateOnlyFields(hendrix, q); + + var updatedRow = db.SingleById(hendrix.Id); + + Assert.That(updatedRow.FirstName, Is.EqualTo("JJ")); + Assert.That(updatedRow.LastName, Is.EqualTo("Hendrix")); + Assert.That(updatedRow.Age, Is.EqualTo(27)); + } + + [Test] + public void Does_use_constant_size_string_params() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + + var converter = db.GetDialectProvider().GetStringConverter(); + + void AssertDbStringParamSizes(IDbCommand cmd) + { + foreach (IDbDataParameter p in cmd.Parameters) + { + if (p.Value is string s) + { + //MySql sets DB Param to string length + Assert.That(p.Size, Is.EqualTo(converter.StringLength).Or.EqualTo(s.Length)); + } + } + } + + var hendrix = new Person(1, "Jimi", "Hendrix", 27); + db.Insert(hendrix, commandFilter: AssertDbStringParamSizes); + + hendrix.FirstName = "Updated"; + + db.Update(hendrix, commandFilter: AssertDbStringParamSizes); + + var row = db.SingleById(hendrix.Id); + Assert.That(row.FirstName, Is.EqualTo("Updated")); + } + + [Test] + public void Can_update_DefaultValue() + { + using var db = OpenDbConnection(); + db.DropAndCreateTable(); + AssertDefaultValueFieldTypeDefaultValues(); + + var orig = new DefaultValue { + Id = 1, + Bool = true, + NBool = false, + Int = 2, + NInt = 0, + String = "A", + }; + db.Insert(orig); + var row = db.SingleById(1); + AssertDefaultValues(row, orig); + + db.UpdateOnly(new Dictionary { + [nameof(DefaultValue.Id)] = 1, + [nameof(DefaultValue.Bool)] = false, + [nameof(DefaultValue.NBool)] = null, + [nameof(DefaultValue.Int)] = 0, + [nameof(DefaultValue.NInt)] = null, + [nameof(DefaultValue.String)] = null, + }); + + row = db.SingleById(1); + AssertDefaultValues(row, new DefaultValue { + Id = 1, + Bool = false, + NBool = null, + Int = 0, + NInt = null, + String = null, + }); + + db.UpdateOnly(new Dictionary { + [nameof(DefaultValue.Id)] = 1, + [nameof(DefaultValue.Bool)] = true, + [nameof(DefaultValue.NBool)] = false, + [nameof(DefaultValue.Int)] = 1, + [nameof(DefaultValue.NInt)] = 0, + [nameof(DefaultValue.String)] = "", + }); + + row = db.SingleById(1); + AssertDefaultValues(row, new DefaultValue { + Id = 1, + Bool = true, + NBool = false, + Int = 1, + NInt = 0, + String = "", + }); + } + + [Test] + public async Task Can_update_DefaultValue_Async() + { + using var db = await OpenDbConnectionAsync(); + db.DropAndCreateTable(); + AssertDefaultValueFieldTypeDefaultValues(); + + var orig = new DefaultValue { + Id = 1, + Bool = true, + NBool = false, + Int = 2, + NInt = 0, + String = "A", + }; + await db.InsertAsync(orig); + var row = await db.SingleByIdAsync(1); + AssertDefaultValues(row, orig); + + db.UpdateOnly(new Dictionary { + [nameof(DefaultValue.Id)] = 1, + [nameof(DefaultValue.Bool)] = false, + [nameof(DefaultValue.NBool)] = null, + [nameof(DefaultValue.Int)] = 0, + [nameof(DefaultValue.NInt)] = null, + [nameof(DefaultValue.String)] = null, + }); + + row = await db.SingleByIdAsync(1); + AssertDefaultValues(row, new DefaultValue { + Id = 1, + Bool = false, + NBool = null, + Int = 0, + NInt = null, + String = null, + }); + + await db.UpdateOnlyAsync(new Dictionary { + [nameof(DefaultValue.Id)] = 1, + [nameof(DefaultValue.Bool)] = true, + [nameof(DefaultValue.NBool)] = false, + [nameof(DefaultValue.Int)] = 1, + [nameof(DefaultValue.NInt)] = 0, + [nameof(DefaultValue.String)] = "", + }); + + row = db.SingleById(1); + AssertDefaultValues(row, new DefaultValue { + Id = 1, + Bool = true, + NBool = false, + Int = 1, + NInt = 0, + String = "", + }); + } + + private static void AssertDefaultValueFieldTypeDefaultValues() + { + var modelDef = typeof(DefaultValue).GetModelMetadata(); + Assert.That(modelDef.GetFieldDefinition(nameof(DefaultValue.Int)).FieldTypeDefaultValue, + Is.EqualTo(default(int))); + Assert.That(modelDef.GetFieldDefinition(nameof(DefaultValue.NInt)).FieldTypeDefaultValue, + Is.EqualTo(default(int?))); + Assert.That(modelDef.GetFieldDefinition(nameof(DefaultValue.Bool)).FieldTypeDefaultValue, + Is.EqualTo(default(bool))); + Assert.That(modelDef.GetFieldDefinition(nameof(DefaultValue.NBool)).FieldTypeDefaultValue, + Is.EqualTo(default(bool?))); + Assert.That(modelDef.GetFieldDefinition(nameof(DefaultValue.String)).FieldTypeDefaultValue, + Is.EqualTo(default(string))); + } + + private void AssertDefaultValues(DefaultValue row, DefaultValue orig) + { + Assert.That(row.Id, Is.EqualTo(orig.Id)); + Assert.That(row.Bool, Is.EqualTo(orig.Bool)); + Assert.That(row.NBool, Is.EqualTo(orig.NBool)); + Assert.That(row.Int, Is.EqualTo(orig.Int)); + Assert.That(row.NInt, Is.EqualTo(orig.NInt)); + Assert.That(row.String, Is.EqualTo(orig.String)); + } + } [CompositeIndex("FirstName", "LastName")] @@ -205,4 +902,21 @@ public class SomeBlobs public byte[] Blob1 { get; set; } public byte[] Blob2 { get; set; } } + + public class Shutdown + { + public int Id { get; set; } + public bool? IsShutdownGraceful { get; set; } + } + + public class DefaultValue + { + public int Id { get; set; } + public int Int { get; set; } + public int? NInt { get; set; } + public bool Bool { get; set; } + public bool? NBool { get; set; } + public string String { get; set; } + } + } diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteUtilExtensionsTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteUtilExtensionsTests.cs index bd29c21b8..8d7190030 100644 --- a/tests/ServiceStack.OrmLite.Tests/OrmLiteUtilExtensionsTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteUtilExtensionsTests.cs @@ -1,18 +1,18 @@ -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using ServiceStack.OrmLite; +using NUnit.Framework; namespace ServiceStack.OrmLite.Tests { - public class OrmLiteUtilExtensionsTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class OrmLiteUtilExtensionsTests : OrmLiteProvidersTestBase { + public OrmLiteUtilExtensionsTests(DialectContext context) : base(context) {} + [Test] public void CanCreateStringInStatement() { var list = new string[] { "A", "B", "C" }; - var sql = "IN ({0})".SqlFmt(list.SqlInValues()); + var sql = "IN ({0})".SqlFmt(DialectProvider, list.SqlInValues(DialectProvider)); Assert.AreEqual("IN ('A','B','C')", sql); } @@ -22,7 +22,7 @@ public void CanCreateIntInStatement() { var list = new int[] { 1, 2, 3 }; - var sql = "IN ({0})".SqlFmt(list.SqlInValues()); + var sql = "IN ({0})".SqlFmt(DialectProvider, list.SqlInValues(DialectProvider)); Assert.AreEqual("IN (1,2,3)", sql); } @@ -32,9 +32,23 @@ public void CanCreateNullInStatementFromEmptyList() { var list = new string[] {}; - var sql = "IN ({0})".SqlFmt(list.SqlInValues()); + var sql = "IN ({0})".SqlFmt(DialectProvider, list.SqlInValues(DialectProvider)); Assert.AreEqual("IN (NULL)", sql); } + + [Test] + public void Can_parse_field_Tokens() + { + Assert.That("FirstName".ParseTokens(), Is.EquivalentTo(new[] { "FirstName" })); + Assert.That("FirstName, LastName".ParseTokens(), Is.EquivalentTo(new[] { "FirstName", "LastName" })); + Assert.That("\"FirstName\"".ParseTokens(), Is.EquivalentTo(new[] { "\"FirstName\"" })); + Assert.That("\"FirstName\",\"LastName\"".ParseTokens(), Is.EquivalentTo(new[] { "\"FirstName\"", "\"LastName\"" })); + Assert.That("COALESCE(\"Time\", '2015-10-05')".ParseTokens(), Is.EquivalentTo(new[] { "COALESCE(\"Time\", '2015-10-05')" })); + Assert.That("\"FirstName\",COALESCE(\"Time\", '2015-10-05'),\"LastName\"".ParseTokens(), Is.EquivalentTo( + new[] { "\"FirstName\"", "COALESCE(\"Time\", '2015-10-05')", "\"LastName\"" })); + Assert.That(" \"FirstName\" , COALESCE(\"Time\", '2015-10-05') , \"LastName\" ".ParseTokens(), Is.EquivalentTo( + new[] { "\"FirstName\"", "COALESCE(\"Time\", '2015-10-05')", "\"LastName\"" })); + } } } diff --git a/tests/ServiceStack.OrmLite.Tests/OrmLiteUtilsTests.cs b/tests/ServiceStack.OrmLite.Tests/OrmLiteUtilsTests.cs new file mode 100644 index 000000000..3e9d9cd27 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/OrmLiteUtilsTests.cs @@ -0,0 +1,27 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixture] + public class OrmLiteUtilsTests + { + [Test] + public void ParseTokens() + { + var sql = + @"(CASE WHEN NOT (((""table_1"".""_display_name"") is null or (""table_1"".""_display_name"") = '')) THEN (""table_1"".""_display_name"") ELSE ""table_1"".""_name"" END) + ""tabel_2"".""_name"""; + var tokens = OrmLiteUtils.ParseTokens(sql); + + Assert.AreEqual(1, tokens.Count); + } + + [Test] + public void Can_UnquotedColumnName() + { + Assert.That(OrmLiteUtils.UnquotedColumnName("Col"), Is.EqualTo("Col")); + Assert.That(OrmLiteUtils.UnquotedColumnName("\"Col\""), Is.EqualTo("Col")); + Assert.That(OrmLiteUtils.UnquotedColumnName("Table.Col"), Is.EqualTo("Col")); + Assert.That(OrmLiteUtils.UnquotedColumnName("\"Table\".\"Col\""), Is.EqualTo("Col")); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/PerfTests.cs b/tests/ServiceStack.OrmLite.Tests/PerfTests.cs index 45eeefc44..c5583424f 100644 --- a/tests/ServiceStack.OrmLite.Tests/PerfTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/PerfTests.cs @@ -31,9 +31,11 @@ public static ModelWithDifferentNumTypes Create(int i) } } - [TestFixture, Explicit] - public class PerfTests : OrmLiteTestBase + [TestFixtureOrmLite, Explicit] + public class PerfTests : OrmLiteProvidersTestBase { + public PerfTests(DialectContext context) : base(context) {} + [Test] public void Is_GetValue_Slow() { diff --git a/tests/ServiceStack.OrmLite.Tests/Properties/AssemblyInfo.cs b/tests/ServiceStack.OrmLite.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index c20dbe9d9..000000000 --- a/tests/ServiceStack.OrmLite.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLite.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("ServiceStack.OrmLite.Tests")] -[assembly: AssemblyCopyright("Copyright © ServiceStack 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("3570f0e8-68c5-4211-b73d-a239ec8800b3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/ServiceStack.OrmLite.Tests/Properties/Settings.Designer.cs b/tests/ServiceStack.OrmLite.Tests/Properties/Settings.Designer.cs deleted file mode 100644 index fd6af8807..000000000 --- a/tests/ServiceStack.OrmLite.Tests/Properties/Settings.Designer.cs +++ /dev/null @@ -1,37 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18449 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ServiceStack.OrmLite.Tests.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - - [global::System.Configuration.ApplicationScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] - [global::System.Configuration.DefaultSettingValueAttribute("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\App_Data\\Database1.mdf;" + - "Integrated Security=True;User Instance=True")] - public string Database1ConnectionString { - get { - return ((string)(this["Database1ConnectionString"])); - } - } - } -} diff --git a/tests/ServiceStack.OrmLite.Tests/Properties/Settings.settings b/tests/ServiceStack.OrmLite.Tests/Properties/Settings.settings deleted file mode 100644 index 7525b1ea9..000000000 --- a/tests/ServiceStack.OrmLite.Tests/Properties/Settings.settings +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - <?xml version="1.0" encoding="utf-16"?> -<SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> - <ConnectionString>Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\App_Data\Database1.mdf;Integrated Security=True;User Instance=True</ConnectionString> - <ProviderName>System.Data.SqlClient</ProviderName> -</SerializableConnectionString> - Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\App_Data\Database1.mdf;Integrated Security=True;User Instance=True - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/RowVersionTests.cs b/tests/ServiceStack.OrmLite.Tests/RowVersionTests.cs index 548529762..7bb083a4f 100644 --- a/tests/ServiceStack.OrmLite.Tests/RowVersionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/RowVersionTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; +using System.Threading.Tasks; using NUnit.Framework; using ServiceStack.Data; using ServiceStack.DataAnnotations; @@ -49,6 +50,30 @@ public class ModelWithAliasedRowVersion public long Version { get; set; } } + [Alias("ModelAlias")] + public class ModelWithAlias + { + [Alias("ModelId")] + [AutoIncrement] + public int Id { get; set; } + + [Alias("IntAlias")] + public int IntField { get; set; } + } + + [Schema("Schema")] + public class ModelWithSchemaAndRowVersionForInnerJoin + { + [AutoIncrement] + public long Id { get; set; } + + public string Text { get; set; } + + public long ModelWithRowVersionId { get; set; } + + public ulong RowVersion { get; set; } + } + public class ModelWithOptimisticChildren { [AutoIncrement] @@ -74,11 +99,14 @@ public class ModelWithRowVersionAndParent public long Version { get; set; } } - public class RowVersionTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class RowVersionTests : OrmLiteProvidersTestBase { + public RowVersionTests(DialectContext context) : base(context) {} + private IDbConnection db; - [TestFixtureSetUp] + [OneTimeSetUp] public void FixtureSetUp() { LogManager.LogFactory = new ConsoleLogFactory(debugEnabled: true); @@ -206,6 +234,62 @@ public void Can_Save_new_row_and_retrieve_rowversion() Assert.That(row.RowVersion, Is.EqualTo(actualRow.RowVersion)); } + [Test] + public async Task Can_Save_new_row_and_retrieve_rowversion_Async() + { + var row = new ModelWithRowVersion { Text = "First" }; + + bool wasInserted = await db.SaveAsync(row); + + Assert.That(wasInserted, Is.True); + var actualRow = await db.SingleByIdAsync(row.Id); + Assert.That(row.RowVersion, Is.EqualTo(actualRow.RowVersion)); + } + + public class ModelWithAutoGuidAndRowVersion + { + [AutoId] + public Guid Id { get; set; } + public string Name { get; set; } + public ulong RowVersion { get; set; } + } + + [Test] + public void Can_Save_ModelWithAutoGuidAndRowVersion() + { + db.DropAndCreateTable(); + var row = new ModelWithAutoGuidAndRowVersion { Name = "A" }; + + Assert.That(db.Save(row)); + + var dbRow = db.SingleById(row.Id); + Assert.That(dbRow.Name, Is.EqualTo(row.Name)); + + dbRow.Name = "B"; + db.Save(dbRow); + + dbRow = db.SingleById(row.Id); + Assert.That(dbRow.Name, Is.EqualTo("B")); + } + + [Test] + public async Task Can_Save_ModelWithAutoGuidAndRowVersion_Async() + { + db.DropAndCreateTable(); + var row = new ModelWithAutoGuidAndRowVersion { Name = "A" }; + + Assert.That(await db.SaveAsync(row)); + + var dbRow = await db.SingleByIdAsync(row.Id); + Assert.That(dbRow.Name, Is.EqualTo(row.Name)); + + dbRow.Name = "B"; + await db.SaveAsync(dbRow); + + dbRow = await db.SingleByIdAsync(row.Id); + Assert.That(dbRow.Name, Is.EqualTo("B")); + } + [Test] public void Can_SaveAll_new_rows_and_retrieve_rowversion() { @@ -272,6 +356,78 @@ public void Can_update_with_current_rowversion_base() Assert.That(actual.RowVersion, Is.Not.EqualTo(row.RowVersion)); } + [Test] + public void Can_update_with_current_rowversion_base_ObjectDictionary() + { + var rowId = db.Insert(new ModelWithRowVersionBase { Text = "Two", MoreData = "Fred" }, selectIdentity: true); + var row = db.SingleById(rowId); + + row.Text = "Three"; + db.Update(row.ToObjectDictionary()); + + var actual = db.SingleById(rowId); + Assert.That(actual.Text, Is.EqualTo("Three")); + Assert.That(actual.RowVersion, Is.Not.EqualTo(row.RowVersion)); + + row.Text = "Four"; + Assert.Throws(() => + db.Update(row.ToObjectDictionary())); + } + + [Test] + public async Task Can_update_with_current_rowversion_base_ObjectDictionary_Async() + { + var rowId = await db.InsertAsync(new ModelWithRowVersionBase { Text = "Two", MoreData = "Fred" }, selectIdentity: true); + var row = await db.SingleByIdAsync(rowId); + + row.Text = "Three"; + await db.UpdateAsync(row.ToObjectDictionary()); + + var actual = await db.SingleByIdAsync(rowId); + Assert.That(actual.Text, Is.EqualTo("Three")); + Assert.That(actual.RowVersion, Is.Not.EqualTo(row.RowVersion)); + + row.Text = "Four"; + Assert.ThrowsAsync(async () => + await db.UpdateAsync(row.ToObjectDictionary())); + } + + [Test] + public void Can_update_with_current_rowversion_base_UpdateOnly_ObjectDictionary() + { + var rowId = db.Insert(new ModelWithRowVersionBase { Text = "Two", MoreData = "Fred" }, selectIdentity: true); + var row = db.SingleById(rowId); + + row.Text = "Three"; + db.UpdateOnly(row.ToObjectDictionary()); + + var actual = db.SingleById(rowId); + Assert.That(actual.Text, Is.EqualTo("Three")); + Assert.That(actual.RowVersion, Is.Not.EqualTo(row.RowVersion)); + + row.Text = "Four"; + Assert.Throws(() => + db.UpdateOnly(row.ToObjectDictionary())); + } + + [Test] + public async Task Can_update_with_current_rowversion_base_UpdateOnly_ObjectDictionary_Async() + { + var rowId = await db.InsertAsync(new ModelWithRowVersionBase { Text = "Two", MoreData = "Fred" }, selectIdentity: true); + var row = await db.SingleByIdAsync(rowId); + + row.Text = "Three"; + await db.UpdateOnlyAsync(row.ToObjectDictionary()); + + var actual = await db.SingleByIdAsync(rowId); + Assert.That(actual.Text, Is.EqualTo("Three")); + Assert.That(actual.RowVersion, Is.Not.EqualTo(row.RowVersion)); + + row.Text = "Four"; + Assert.ThrowsAsync(async () => + await db.UpdateOnlyAsync(row.ToObjectDictionary())); + } + [Test] public void Can_update_multiple_with_current_rowversions() { @@ -360,6 +516,18 @@ public void Can_delete_with_current_rowversion() var count = db.Count(m => m.Id == rowId); Assert.That(count, Is.EqualTo(0)); } + + [Test] + public void Can_DeleteById_with_current_rowversion() + { + var rowId = db.Insert(new ModelWithRowVersion { Text = "Four" }, selectIdentity: true); + var row = db.SingleById(rowId); + + db.DeleteById(row.Id, rowVersion:row.RowVersion); + + var count = db.Count(m => m.Id == rowId); + Assert.That(count, Is.EqualTo(0)); + } [Test] public void Update_with_outdated_rowversion_throws() @@ -513,6 +681,31 @@ public void Delete_with_outdated_rowversion_throws() Assert.That(count, Is.EqualTo(1)); } + [Test] + public async Task Can_read_from_inner_join_with_schema() + { + if ((Dialect & Dialect.AnyMySql) == Dialect) //ERROR table name too long + return; + + db.DropAndCreateTable(); + var rowVersionModel = new ModelWithRowVersion { + Text = "test" + }; + var modelId = await db.InsertAsync(rowVersionModel, selectIdentity: true).ConfigureAwait(false); + var innerJoinTable = new ModelWithSchemaAndRowVersionForInnerJoin { + ModelWithRowVersionId = modelId, + Text = "inner join table" + }; + var joinId = await db.InsertAsync(innerJoinTable, selectIdentity: true).ConfigureAwait(false); + + var query = db + .From((x, y) => x.Id == y.ModelWithRowVersionId) + .Where(model => model.Id == joinId); + + var result = await db.SingleAsync(query).ConfigureAwait(false); + Assert.NotNull(result); + } + private void TouchRow(long rowId) { var row = db.SingleById(rowId); diff --git a/tests/ServiceStack.OrmLite.Tests/SchemaTests.cs b/tests/ServiceStack.OrmLite.Tests/SchemaTests.cs new file mode 100644 index 000000000..fa473e378 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/SchemaTests.cs @@ -0,0 +1,221 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.Issues; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class SchemaTests : OrmLiteProvidersTestBase + { + public SchemaTests(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void OneTimeSetup() + { + // sqlite doesn't support schemas + if (DialectFeatures.SchemaSupport) + { + using (var db = OpenDbConnection()) + { + db.CreateSchema(); + db.CreateSchema("SchemaTest"); + } + } + } + + public class Schematest + { + public int Id { get; set; } + public string Name { get; set; } + } + + [Alias("SchemaTest")] + public class NewSchematest + { + public int Id { get; set; } + public string Name { get; set; } + + [Default(0)] + public int Int { get; set; } + + public int? NInt { get; set; } + } + + [Schema("Schema")] + public class TestWithSchema + { + public int Id { get; set; } + public string Name { get; set; } + } + + [Test] + public void Does_verify_if_table_exists() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + Assert.That(!db.TableExists()); + + db.CreateTable(); + Assert.That(db.TableExists()); + + db.DropTable(); + Assert.That(!db.TableExists()); + + db.CreateTable(); + Assert.That(db.TableExists()); + } + } + + [Test] + public void Does_verify_if_column_exists() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + + Assert.That(!db.ColumnExists(x => x.Id)); + Assert.That(!db.ColumnExists(x => x.Name)); + Assert.That(!db.ColumnExists(x => x.Int)); + Assert.That(!db.ColumnExists(x => x.NInt)); + + db.CreateTable(); + + Assert.That(db.ColumnExists(x => x.Id)); + Assert.That(db.ColumnExists(x => x.Name)); + Assert.That(!db.ColumnExists(x => x.Int)); + Assert.That(!db.ColumnExists(x => x.NInt)); + + db.CreateTable(); + + if (!db.ColumnExists(x => x.Int)) + db.AddColumn(x => x.Int); + Assert.That(db.ColumnExists(x => x.Int)); + + if (!db.ColumnExists(x => x.NInt)) + db.AddColumn(x => x.NInt); + Assert.That(db.ColumnExists(x => x.NInt)); + + db.DropTable(); + Assert.That(!db.ColumnExists(x => x.Id)); + db.CreateTable(); + Assert.That(db.ColumnExists(x => x.Id)); + } + } + + [Test] + [IgnoreDialect(Dialect.Sqlite, "DROP COLUMN Not supported")] + public void Can_drop_and_add_column() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + Assert.That(db.ColumnExists(x => x.Id)); + Assert.That(db.ColumnExists(x => x.Name)); + + db.DropColumn(x => x.Name); + Assert.That(!db.ColumnExists(x => x.Name)); + + try + { + db.DropColumn(x => x.Name); + Assert.Fail("Should throw"); + } + catch (Exception) { } + + db.AddColumn(x => x.Name); + Assert.That(db.ColumnExists(x => x.Name)); + + try + { + db.AddColumn(x => x.Name); + Assert.Fail("Should throw"); + } + catch (Exception) { } + } + } + + [Test] + public void Can_get_Schema_Table() + { + using var db = OpenDbConnection(); + db.CreateTableIfNotExists(); + + var columnSchemas = db.GetTableColumns(); + + columnSchemas.Each(x => x.ToString().Print()); + + // columnSchemas.Each(x => x.PrintDump()); + columnSchemas.Each(x => x.ToString().Print()); + } + + [Test] + public async Task Can_get_Schema_Table_Async() + { + using var db = await OpenDbConnectionAsync(); + db.CreateTableIfNotExists(); + + var columnSchemas = await db.GetTableColumnsAsync(); + + // columnSchemas.Each(x => x.PrintDump()); + columnSchemas.Each(x => x.ToString().Print()); + } + + [Test] + public void GetTableNames_does_not_return_tables_in_different_schema() + { + if (Dialect == Dialect.Sqlite || (Dialect & Dialect.AnyMySql) == Dialect) + return; + + using var db = OpenDbConnection(); + db.CreateTableIfNotExists(); + + var name = db.GetDialectProvider().GetTableName(nameof(ModelWithSchema)).StripDbQuotes().ToLower(); + + var tableNames = db.GetTableNames().Map(x => x.ToLower()); + Assert.That(tableNames.Contains(name), Is.False); + + var tableNamesWithCounts = db.GetTableNamesWithRowCounts().Map(x => x.Key.ToLower()); + Assert.That(tableNamesWithCounts.Contains(name), Is.False); + } + + [Test] + public void GetTableNames_does_return_tables_in_schema() + { + if (Dialect == Dialect.Sqlite || (Dialect & Dialect.AnyMySql) == Dialect) + return; + + using var db = OpenDbConnection(); + db.CreateTableIfNotExists(); + + var name = db.GetDialectProvider().GetTableName(nameof(ModelWithSchema)).StripDbQuotes().ToLower(); + + var tableNames = db.GetTableNames("Schema").Map(x => x.ToLower()); + Assert.That(tableNames.Contains(name)); + + var tableNamesWithCounts = db.GetTableNamesWithRowCounts(schema:"Schema").Map(x => x.Key.ToLower()); + Assert.That(tableNamesWithCounts.Contains(name)); + } + + [Test] + public void Can_get_definition_of_ModelWithSchema() + { + using var db = OpenDbConnection(); + db.CreateTableIfNotExists(); + + var tableColumns = db.GetTableColumns(); + Assert.That(tableColumns.Length, Is.EqualTo(typeof(ModelWithSchema).GetProperties().Length)); + + Assert.That(tableColumns.First(x => x.ColumnName.EqualsIgnoreCase(nameof(ModelWithSchema.Id))).IsKey); + + // tableColumns.Map(x => x.ToString()).PrintDump(); + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/SelectParamTests.cs b/tests/ServiceStack.OrmLite.Tests/SelectParamTests.cs new file mode 100644 index 000000000..bc30f1b3d --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/SelectParamTests.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class SelectParamTests : OrmLiteProvidersTestBase + { + public SelectParamTests(DialectContext context) : base(context) {} + + [Test] + public void Can_Select_with_Different_APIs() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + Assert.That(db.Select(x => x.Age == 27).Count, Is.EqualTo(4)); + Assert.That(db.Select(db.From().Where(x => x.Age == 27)).Count, Is.EqualTo(4)); + Assert.That(db.Select("Age = @age", new { age = 27 }).Count, Is.EqualTo(4)); + Assert.That(db.Select("Age = @age", new Dictionary { { "age", 27 } }).Count, Is.EqualTo(4)); + Assert.That(db.Select("Age = @age", new[] { db.CreateParam("age", 27) }).Count, Is.EqualTo(4)); + Assert.That(db.Select("SELECT * FROM Person WHERE Age = @age", new { age = 27 }).Count, Is.EqualTo(4)); + Assert.That(db.Select("SELECT * FROM Person WHERE Age = @age", new Dictionary { { "age", 27 } }).Count, Is.EqualTo(4)); + Assert.That(db.Select("SELECT * FROM Person WHERE Age = @age", new[] { db.CreateParam("age", 27) }).Count, Is.EqualTo(4)); + + Assert.That(db.Select("Age = @age", new { age = 27 }).Count, Is.EqualTo(4)); + + Assert.That(db.SelectNonDefaults(new Person { Age = 27 }).Count, Is.EqualTo(4)); + + Assert.That(db.SqlList("SELECT * FROM Person WHERE Age = @age", new { age = 27 }).Count, Is.EqualTo(4)); + Assert.That(db.SqlList("SELECT * FROM Person WHERE Age = @age", new Dictionary { { "age", 27 } }).Count, Is.EqualTo(4)); + Assert.That(db.SqlList("SELECT * FROM Person WHERE Age = @age", new[] { db.CreateParam("age", 27) }).Count, Is.EqualTo(4)); + } + } + + [Test] + public void Can_Select_with_Null_param() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var dbCmd = db.CreateCommand();//demo code, just for dbCmd.CreateParam + + // for sqlite that works with parameter with DBNull.Value and usual null. + Assert.That(db.Select("age = @age", new List { + dbCmd.CreateParam("age", null) + }).Count, Is.EqualTo(0)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj b/tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj index 54796eca2..5f232f721 100644 --- a/tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj +++ b/tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj @@ -1,353 +1,42 @@ - - + - Debug - AnyCPU - 9.0.30729 - 2.0 - {9B64F4A7-C008-46A8-AD6F-99626DCFEFBD} - Library - Properties - ServiceStack.OrmLite.Tests + net472;net6.0 + + portable ServiceStack.OrmLite.Tests - v4.5 - 512 - false - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - x86 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - x86 - false - - - bin\Signed\ - TRACE - true - pdbonly - x86 - prompt - AllRules.ruleset - 4 - false + Library + ServiceStack.OrmLite.Tests + default - - ..\..\lib\tests\ServiceStack.dll - - - False - ..\..\lib\ServiceStack.Client.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - 3.5 - - - - 3.5 - - - 3.0 - - - - - 3.5 - - - 3.5 - - - - - ..\..\lib\tests\Mono.Data.Sqlite.dll - - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - + + + + + + + + + + + + + + + + + + + + + + $(DefineConstants);NETCORE;NET6_0 + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Settings.settings + + TestConfig.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sqlite3.dll - PreserveNewest - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 2.0 %28x86%29 - false - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - False - .NET Framework 3.5 SP1 - true - - - False - SQL Server 2008 Express - true - - - False - SQL Server 2005 Express Edition SP2 %28x86%29 - true - - - False - Windows Installer 3.1 - true - - - False - Windows Installer 4.5 - true - - - - - - - - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - {317B64BA-D7A6-4A15-8719-821B38147C63} - ServiceStack.OrmLite.Firebird - - - {fd20f088-acc0-4979-ac0c-8c541c2e7de5} - ServiceStack.OrmLite.MySql - - - {517B64BA-D7A6-4A15-8719-821B38147C61} - ServiceStack.OrmLite.Oracle - - - {3220F088-BDD0-6979-AC0C-8C541C2E7DE5} - ServiceStack.OrmLite.PostgreSQL - - - {CF68A37D-D071-469D-AE04-68594CB95382} - ServiceStack.OrmLite.Sqlite - - - {1887dc99-9139-43e3-a7aa-6d74714b3a5d} - ServiceStack.OrmLite.SqlServer - - - {D18D9D3C-B3B3-433C-9578-68E978587858} - ServiceStack.OrmLite.VistaDB - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj.user b/tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj.user deleted file mode 100644 index 3347b8838..000000000 --- a/tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj.user +++ /dev/null @@ -1,20 +0,0 @@ - - - - ProjectFiles - - - - - - - - - - - - - en-US - false - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ApiUtilExtensions.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ApiUtilExtensions.cs index c5a63144c..594560b3f 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ApiUtilExtensions.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ApiUtilExtensions.cs @@ -13,7 +13,7 @@ public static string PrintLastSql(this IDbConnection dbConn) "".Print(); return dbConn.GetLastSql(); } - + //[Explicit] //public void Benchmark() //{ @@ -38,8 +38,7 @@ static double MeasureFor(Action fn, int timeMinimum) static double Measure(Action fn, int times = 10, int runfor = 2000, Action setup = null, Action warmup = null, Action teardown = null) { - if (setup != null) - setup(); + setup?.Invoke(); // Warmup for at least 100ms. Discard result. if (warmup == null) @@ -54,8 +53,7 @@ static double Measure(Action fn, int times = 10, int runfor = 2000, Action setup fn(); }, runfor); - if (teardown != null) - teardown(); + teardown?.Invoke(); return result; } diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/BuiltInsFactory.cs b/tests/ServiceStack.OrmLite.Tests/Shared/BuiltInsFactory.cs index aa344f310..4731b2170 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/BuiltInsFactory.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/BuiltInsFactory.cs @@ -1,55 +1,54 @@ using System; -using System.Collections.Generic; using NUnit.Framework; namespace ServiceStack.Common.Tests.Models { - public class BuiltInsFactory - : ModelFactoryBase - { - readonly string[] StringValues = new[] { - "one", "two", "three", "four", - "five", "six", "seven" - }; + public class BuiltInsFactory + : ModelFactoryBase + { + readonly string[] StringValues = new[] { + "one", "two", "three", "four", + "five", "six", "seven" + }; - public override void AssertIsEqual(string actual, string expected) - { - Assert.That(actual, Is.EqualTo(expected)); - } + public override void AssertIsEqual(string actual, string expected) + { + Assert.That(actual, Is.EqualTo(expected)); + } - public override string CreateInstance(int i) - { - return i < StringValues.Length - ? StringValues[i] - : i.ToString(); - } - } + public override string CreateInstance(int i) + { + return i < StringValues.Length + ? StringValues[i] + : i.ToString(); + } + } - public class IntFactory - : ModelFactoryBase - { - public override void AssertIsEqual(int actual, int expected) - { - Assert.That(actual, Is.EqualTo(expected)); - } + public class IntFactory + : ModelFactoryBase + { + public override void AssertIsEqual(int actual, int expected) + { + Assert.That(actual, Is.EqualTo(expected)); + } - public override int CreateInstance(int i) - { - return i; - } - } + public override int CreateInstance(int i) + { + return i; + } + } - public class DateTimeFactory - : ModelFactoryBase - { - public override void AssertIsEqual(DateTime actual, DateTime expected) - { - Assert.That(actual, Is.EqualTo(expected)); - } + public class DateTimeFactory + : ModelFactoryBase + { + public override void AssertIsEqual(DateTime actual, DateTime expected) + { + Assert.That(actual, Is.EqualTo(expected)); + } - public override DateTime CreateInstance(int i) - { - return new DateTime(i, DateTimeKind.Utc); - } - } + public override DateTime CreateInstance(int i) + { + return new DateTime(i, DateTimeKind.Utc); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/DefaultValues.cs b/tests/ServiceStack.OrmLite.Tests/Shared/DefaultValues.cs new file mode 100644 index 000000000..602d5c4b0 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Shared/DefaultValues.cs @@ -0,0 +1,75 @@ +using System; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Models +{ + public class DefaultValues + { + public int Id { get; set; } + + [Default(1)] + public int DefaultInt { get; set; } + + public int DefaultIntNoDefault { get; set; } + + [Default(1)] + public int? NDefaultInt { get; set; } + + [Default(1.1)] + public double DefaultDouble { get; set; } + + [Default(1.1)] + public double? NDefaultDouble { get; set; } + + [Default("'String'")] + public string DefaultString { get; set; } + + [Default(OrmLiteVariables.SystemUtc)] + public DateTime CreatedDateUtc { get; set; } + + [Default(OrmLiteVariables.SystemUtc)] + public DateTime? NCreatedDateUtc { get; set; } + + [Default(OrmLiteVariables.SystemUtc)] + public DateTime UpdatedDateUtc { get; set; } + } + + public class DefaultValuesUpdate + { + public int Id { get; set; } + + [Default(1)] + public int DefaultInt { get; set; } + + public int DefaultIntNoDefault { get; set; } + + [Default(1)] + public int? NDefaultInt { get; set; } + + [Default(1.1)] + public double DefaultDouble { get; set; } + + [Default(1.1)] + public double? NDefaultDouble { get; set; } + + [Default("'String'")] + public string DefaultString { get; set; } + + [Default(OrmLiteVariables.SystemUtc)] + public DateTime UpdatedDateUtc { get; set; } + } + + public class ModelWithDefaults + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + + [Default(1)] + public int DefaultInt { get; set; } + + [Default("'String'")] + public string DefaultString { get; set; } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/IModelFactory.cs b/tests/ServiceStack.OrmLite.Tests/Shared/IModelFactory.cs index 78ebfaa2c..dbfb4c019 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/IModelFactory.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/IModelFactory.cs @@ -2,15 +2,15 @@ namespace ServiceStack.Common.Tests.Models { - public interface IModelFactory - { - void AssertListsAreEqual(List actualList, IList expectedList); - void AssertIsEqual(T actual, T expected); + public interface IModelFactory + { + void AssertListsAreEqual(List actualList, IList expectedList); + void AssertIsEqual(T actual, T expected); - T ExistingValue { get; } - T NonExistingValue { get; } - List CreateList(); - List CreateList2(); - T CreateInstance(int i); - } + T ExistingValue { get; } + T NonExistingValue { get; } + List CreateList(); + List CreateList2(); + T CreateInstance(int i); + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelFactoryBase.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelFactoryBase.cs index 09c1494c3..6169e327e 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelFactoryBase.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelFactoryBase.cs @@ -3,60 +3,45 @@ namespace ServiceStack.Common.Tests.Models { - public abstract class ModelFactoryBase - : IModelFactory - { - #region Implementation of IModelFactory - - public void AssertListsAreEqual(List actualList, IList expectedList) - { - Assert.That(actualList, Has.Count.EqualTo(expectedList.Count)); - var i = 0; - - actualList.ForEach(x => - AssertIsEqual(x, expectedList[i++])); - } - - public abstract T CreateInstance(int i); - - public abstract void AssertIsEqual(T actual, T expected); - - public T ExistingValue - { - get - { - return CreateInstance(4); - } - } - - public T NonExistingValue - { - get - { - return CreateInstance(5); - } - } - - public List CreateList() - { - return new List - { - CreateInstance(1), - CreateInstance(2), - CreateInstance(3), - CreateInstance(4), - }; - } - public List CreateList2() - { - return new List - { - CreateInstance(5), - CreateInstance(6), - CreateInstance(7), - }; - } - - #endregion - } + public abstract class ModelFactoryBase + : IModelFactory + { + public void AssertListsAreEqual(List actualList, IList expectedList) + { + Assert.That(actualList, Has.Count.EqualTo(expectedList.Count)); + var i = 0; + + actualList.ForEach(x => + AssertIsEqual(x, expectedList[i++])); + } + + public abstract T CreateInstance(int i); + + public abstract void AssertIsEqual(T actual, T expected); + + public T ExistingValue => CreateInstance(4); + + public T NonExistingValue => CreateInstance(5); + + public List CreateList() + { + return new List + { + CreateInstance(1), + CreateInstance(2), + CreateInstance(3), + CreateInstance(4), + }; + } + + public List CreateList2() + { + return new List + { + CreateInstance(5), + CreateInstance(6), + CreateInstance(7), + }; + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypes.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypes.cs index d7693fc84..5dd35667c 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypes.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypes.cs @@ -1,77 +1,77 @@ -using System; using System.Collections.Generic; using NUnit.Framework; namespace ServiceStack.Common.Tests.Models { - public class ModelWithComplexTypes - { - public ModelWithComplexTypes() - { - this.StringList = new List(); - this.IntList = new List(); - this.StringMap = new Dictionary(); - this.IntMap = new Dictionary(); - } + public class ModelWithComplexTypes + { + public ModelWithComplexTypes() + { + this.StringList = new List(); + this.IntList = new List(); + this.StringMap = new Dictionary(); + this.IntMap = new Dictionary(); + } - public long Id { get; set; } + public long Id { get; set; } - public List StringList { get; set; } + public List StringList { get; set; } - public List IntList { get; set; } + public List IntList { get; set; } - public Dictionary StringMap { get; set; } + public Dictionary StringMap { get; set; } - public Dictionary IntMap { get; set; } + public Dictionary IntMap { get; set; } - public ModelWithComplexTypes Child { get; set; } + public ModelWithComplexTypes Child { get; set; } - public static ModelWithComplexTypes Create(int id) - { - var row = new ModelWithComplexTypes { - Id = id, - StringList = { "val" + id + 1, "val" + id + 2, "val" + id + 3 }, - IntList = { id + 1, id + 2, id + 3 }, - StringMap = - { - {"key" + id + 1, "val" + id + 1}, - {"key" + id + 2, "val" + id + 2}, - {"key" + id + 3, "val" + id + 3}, - }, - IntMap = - { - {id + 1, id + 2}, - {id + 3, id + 4}, - {id + 5, id + 6}, - }, - Child = new ModelWithComplexTypes { Id = id * 2 }, - }; + public static ModelWithComplexTypes Create(int id) + { + var row = new ModelWithComplexTypes + { + Id = id, + StringList = { "val" + id + 1, "val" + id + 2, "val" + id + 3 }, + IntList = { id + 1, id + 2, id + 3 }, + StringMap = + { + {"key" + id + 1, "val" + id + 1}, + {"key" + id + 2, "val" + id + 2}, + {"key" + id + 3, "val" + id + 3}, + }, + IntMap = + { + {id + 1, id + 2}, + {id + 3, id + 4}, + {id + 5, id + 6}, + }, + Child = new ModelWithComplexTypes { Id = id * 2 }, + }; - return row; - } + return row; + } - public static ModelWithComplexTypes CreateConstant(int i) - { - return Create(i); - } + public static ModelWithComplexTypes CreateConstant(int i) + { + return Create(i); + } - public static void AssertIsEqual(ModelWithComplexTypes actual, ModelWithComplexTypes expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.StringList, Is.EquivalentTo(expected.StringList)); - Assert.That(actual.IntList, Is.EquivalentTo(expected.IntList)); - Assert.That(actual.StringMap, Is.EquivalentTo(expected.StringMap)); - Assert.That(actual.IntMap, Is.EquivalentTo(expected.IntMap)); + public static void AssertIsEqual(ModelWithComplexTypes actual, ModelWithComplexTypes expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.StringList, Is.EquivalentTo(expected.StringList)); + Assert.That(actual.IntList, Is.EquivalentTo(expected.IntList)); + Assert.That(actual.StringMap, Is.EquivalentTo(expected.StringMap)); + Assert.That(actual.IntMap, Is.EquivalentTo(expected.IntMap)); - if (expected.Child == null) - { - Assert.That(actual.Child, Is.Null); - } - else - { - Assert.That(actual.Child, Is.Not.Null); - AssertIsEqual(actual.Child, expected.Child); - } - } - } + if (expected.Child == null) + { + Assert.That(actual.Child, Is.Null); + } + else + { + Assert.That(actual.Child, Is.Not.Null); + AssertIsEqual(actual.Child, expected.Child); + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypesFactory.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypesFactory.cs index a3f9f6b97..0f607dd6e 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypesFactory.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithComplexTypesFactory.cs @@ -1,20 +1,20 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithComplexTypesFactory - : ModelFactoryBase - { - public static ModelWithComplexTypesFactory Instance - = new ModelWithComplexTypesFactory(); + public class ModelWithComplexTypesFactory + : ModelFactoryBase + { + public static ModelWithComplexTypesFactory Instance + = new ModelWithComplexTypesFactory(); - public override void AssertIsEqual( - ModelWithComplexTypes actual, ModelWithComplexTypes expected) - { - ModelWithComplexTypes.AssertIsEqual(actual, expected); - } + public override void AssertIsEqual( + ModelWithComplexTypes actual, ModelWithComplexTypes expected) + { + ModelWithComplexTypes.AssertIsEqual(actual, expected); + } - public override ModelWithComplexTypes CreateInstance(int i) - { - return ModelWithComplexTypes.CreateConstant(i); - } - } + public override ModelWithComplexTypes CreateInstance(int i) + { + return ModelWithComplexTypes.CreateConstant(i); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithCompositeIndexFields.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithCompositeIndexFields.cs index 00fcbb1a9..acc6ff870 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithCompositeIndexFields.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithCompositeIndexFields.cs @@ -2,21 +2,65 @@ namespace ServiceStack.Common.Tests.Models { - [CompositeIndex(true, "Composite1", "Composite2")] - public class ModelWithCompositeIndexFields - { - public string Id { get; set; } + [CompositeIndex(true, "Composite1", "Composite2")] + public class ModelWithCompositeIndexFields + { + public string Id { get; set; } - [Index] - public string Name { get; set; } + [Index] + public string Name { get; set; } - public string AlbumId { get; set; } + public string AlbumId { get; set; } - [Index(true)] - public string UniqueName { get; set; } + [Index(true)] + public string UniqueName { get; set; } - public string Composite1 { get; set; } + public string Composite1 { get; set; } - public string Composite2 { get; set; } - } + public string Composite2 { get; set; } + } + + [CompositeIndex("Composite1", "Composite2 DESC")] + public class ModelWithCompositeIndexFieldsDesc + { + public string Id { get; set; } + + [Index] + public string Name { get; set; } + + public string AlbumId { get; set; } + + [Index(true)] + public string UniqueName { get; set; } + + public string Composite1 { get; set; } + + public string Composite2 { get; set; } + } + + [CompositeIndex("Field WithSpace1", "Field WithSpace2 DESC")] + public class ModelWithCompositeIndexOnFieldSpacesDesc + { + public string Id { get; set; } + + [Alias("Field WithSpace1")] + public string FieldWithSpace1 { get; set; } + + [Alias("Field WithSpace2")] + public string FieldWithSpace2 { get; set; } + } + + [CompositeIndex(true, nameof(UserId), nameof(UserRole))] + public class ModelWithEnum + { + public long Id { get; set; } + public long UserId { get; set; } + public UserRoleEnum UserRole { get; set; } + } + + public enum UserRoleEnum + { + User, + Admin + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypes.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypes.cs index 0313672f0..c9b9a3b7f 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypes.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypes.cs @@ -2,124 +2,98 @@ using NUnit.Framework; using ServiceStack.DataAnnotations; using ServiceStack.Logging; -using ServiceStack.Text; namespace ServiceStack.Common.Tests.Models { - public class ModelWithFieldsOfDifferentAndNullableTypes - { - private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfDifferentAndNullableTypes)); - - [AutoIncrement] - public int Id { get; set; } - public int? NId { get; set; } - - public long LongId { get; set; } - public long? NLongId { get; set; } - - public Guid Guid { get; set; } - public Guid? NGuid { get; set; } - - public bool Bool { get; set; } - public bool? NBool { get; set; } - - public DateTime DateTime { get; set; } - public DateTime? NDateTime { get; set; } - - public float Float { get; set; } - public float? NFloat { get; set; } - - public double Double { get; set; } - public double? NDouble { get; set; } - - public decimal Decimal { get; set; } - public decimal? NDecimal { get; set; } - - public TimeSpan TimeSpan { get; set; } - public TimeSpan? NTimeSpan { get; set; } - - public static ModelWithFieldsOfDifferentAndNullableTypes Create(int id) - { - var row = new ModelWithFieldsOfDifferentAndNullableTypes { - Id = id, - Bool = id % 2 == 0, - DateTime = DateTime.Now.AddDays(id), - Float = 1.11f + id, - Double = 1.11d + id, - Guid = Guid.NewGuid(), - LongId = 999 + id, - Decimal = id + 0.5m, - TimeSpan = TimeSpan.FromSeconds(id), - }; - - return row; - } - - public static ModelWithFieldsOfDifferentAndNullableTypes CreateConstant(int id) - { - var row = new ModelWithFieldsOfDifferentAndNullableTypes { - Id = id, - Bool = id % 2 == 0, - DateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), - Float = 1.11f + id, - Double = 1.11d + id, - Guid = new Guid(((id % 240) + 16).ToString("X") + "461D9D-47DB-4778-B3FA-458379AE9BDC"), - LongId = 999 + id, - Decimal = id + 0.5m, - TimeSpan = TimeSpan.FromSeconds(id), - }; - - return row; - } - - public static void AssertIsEqual(ModelWithFieldsOfDifferentAndNullableTypes actual, ModelWithFieldsOfDifferentAndNullableTypes expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.Guid, Is.EqualTo(expected.Guid)); - Assert.That(actual.LongId, Is.EqualTo(expected.LongId)); - Assert.That(actual.Bool, Is.EqualTo(expected.Bool)); - Assert.That(actual.TimeSpan, Is.EqualTo(expected.TimeSpan)); - - try - { - Assert.That(actual.DateTime, Is.EqualTo(expected.DateTime)); - } - catch (Exception ex) - { - Log.Error("Trouble with DateTime precisions, trying Assert again with rounding to seconds", ex); - Assert.That(actual.DateTime.RoundToSecond(), Is.EqualTo(expected.DateTime.RoundToSecond())); - } - - try - { - Assert.That(actual.Float, Is.EqualTo(expected.Float)); - } - catch (Exception ex) - { - Log.Error("Trouble with float precisions, trying Assert again with rounding to 10 decimals", ex); - Assert.That(Math.Round(actual.Float, 10), Is.EqualTo(Math.Round(actual.Float, 10))); - } - - try - { - Assert.That(actual.Double, Is.EqualTo(expected.Double)); - } - catch (Exception ex) - { - Log.Error("Trouble with double precisions, trying Assert again with rounding to 10 decimals", ex); - Assert.That(Math.Round(actual.Double, 10), Is.EqualTo(Math.Round(actual.Double, 10))); - } - - Assert.That(actual.NBool, Is.EqualTo(expected.NBool)); - Assert.That(actual.NDateTime, Is.EqualTo(expected.NDateTime)); - Assert.That(actual.NDecimal, Is.EqualTo(expected.NDecimal)); - Assert.That(actual.NDouble, Is.EqualTo(expected.NDouble)); - Assert.That(actual.NFloat, Is.EqualTo(expected.NFloat)); - Assert.That(actual.NGuid, Is.EqualTo(expected.NGuid)); - Assert.That(actual.NId, Is.EqualTo(expected.NId)); - Assert.That(actual.NLongId, Is.EqualTo(expected.NLongId)); - Assert.That(actual.NTimeSpan, Is.EqualTo(expected.NTimeSpan)); - - } - } + public class ModelWithFieldsOfDifferentAndNullableTypes + { + private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfDifferentAndNullableTypes)); + + [AutoIncrement] + public int Id { get; set; } + public int? NId { get; set; } + + public long LongId { get; set; } + public long? NLongId { get; set; } + + public Guid Guid { get; set; } + public Guid? NGuid { get; set; } + + public bool Bool { get; set; } + public bool? NBool { get; set; } + + public DateTime DateTime { get; set; } + public DateTime? NDateTime { get; set; } + + public float Float { get; set; } + public float? NFloat { get; set; } + + public double Double { get; set; } + public double? NDouble { get; set; } + + public decimal Decimal { get; set; } + public decimal? NDecimal { get; set; } + + public TimeSpan TimeSpan { get; set; } + public TimeSpan? NTimeSpan { get; set; } + + public static ModelWithFieldsOfDifferentAndNullableTypes Create(int id) + { + var row = new ModelWithFieldsOfDifferentAndNullableTypes + { + Id = id, + Bool = id % 2 == 0, + DateTime = DateTime.Now.AddDays(id), + Float = 1.11f + id, + Double = 1.11d + id, + Guid = Guid.NewGuid(), + LongId = 999 + id, + Decimal = id + 0.5m, + TimeSpan = TimeSpan.FromSeconds(id), + }; + + return row; + } + + public static ModelWithFieldsOfDifferentAndNullableTypes CreateConstant(int id) + { + var row = new ModelWithFieldsOfDifferentAndNullableTypes + { + Id = id, + Bool = id % 2 == 0, + DateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), + Float = 1.11f + id, + Double = 1.11d + id, + Guid = new Guid(((id % 240) + 16).ToString("X") + "461D9D-47DB-4778-B3FA-458379AE9BDC"), + LongId = 999 + id, + Decimal = id + 0.5m, + TimeSpan = TimeSpan.FromSeconds(id), + }; + + return row; + } + + public static void AssertIsEqual(ModelWithFieldsOfDifferentAndNullableTypes actual, ModelWithFieldsOfDifferentAndNullableTypes expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.Guid, Is.EqualTo(expected.Guid)); + Assert.That(actual.LongId, Is.EqualTo(expected.LongId)); + Assert.That(actual.Bool, Is.EqualTo(expected.Bool)); + Assert.That(actual.TimeSpan, Is.EqualTo(expected.TimeSpan)); + Assert.That(actual.DateTime, Is.EqualTo(expected.DateTime).Within(System.TimeSpan.FromSeconds(1))); + Assert.That(actual.Float, Is.EqualTo(expected.Float).Within(1f)); + Assert.That(actual.Double, Is.EqualTo(expected.Double).Within(1d)); + + Assert.That(actual.NBool, Is.EqualTo(expected.NBool)); + Assert.That(actual.NDateTime, Is.EqualTo(expected.NDateTime)); + Assert.That(actual.NDecimal, Is.EqualTo(expected.NDecimal)); + Assert.That(actual.NDouble, Is.EqualTo(expected.NDouble)); + Assert.That(actual.NFloat, Is.EqualTo(expected.NFloat)); + Assert.That(actual.NGuid, Is.EqualTo(expected.NGuid)); + Assert.That(actual.NId, Is.EqualTo(expected.NId)); + Assert.That(actual.NLongId, Is.EqualTo(expected.NLongId)); + Assert.That(actual.NTimeSpan, Is.EqualTo(expected.NTimeSpan)); + + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypesFactory.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypesFactory.cs index 9ae7e1131..bed7fcde6 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypesFactory.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentAndNullableTypesFactory.cs @@ -1,20 +1,20 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithFieldsOfDifferentAndNullableTypesFactory - : ModelFactoryBase - { - public static ModelWithFieldsOfDifferentAndNullableTypesFactory Instance - = new ModelWithFieldsOfDifferentAndNullableTypesFactory(); + public class ModelWithFieldsOfDifferentAndNullableTypesFactory + : ModelFactoryBase + { + public static ModelWithFieldsOfDifferentAndNullableTypesFactory Instance + = new ModelWithFieldsOfDifferentAndNullableTypesFactory(); - public override void AssertIsEqual( - ModelWithFieldsOfDifferentAndNullableTypes actual, ModelWithFieldsOfDifferentAndNullableTypes expected) - { - ModelWithFieldsOfDifferentAndNullableTypes.AssertIsEqual(actual, expected); - } + public override void AssertIsEqual( + ModelWithFieldsOfDifferentAndNullableTypes actual, ModelWithFieldsOfDifferentAndNullableTypes expected) + { + ModelWithFieldsOfDifferentAndNullableTypes.AssertIsEqual(actual, expected); + } - public override ModelWithFieldsOfDifferentAndNullableTypes CreateInstance(int i) - { - return ModelWithFieldsOfDifferentAndNullableTypes.CreateConstant(i); - } - } + public override ModelWithFieldsOfDifferentAndNullableTypes CreateInstance(int i) + { + return ModelWithFieldsOfDifferentAndNullableTypes.CreateConstant(i); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypes.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypes.cs index 48bcb89a1..302a4a61a 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypes.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypes.cs @@ -6,180 +6,186 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithFieldsOfDifferentTypesAsNullables - { - private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfDifferentTypesAsNullables)); - - public int? Id { get; set; } - - public string Name { get; set; } - - public long? LongId { get; set; } - - public Guid? Guid { get; set; } - - public bool? Bool { get; set; } - - public DateTime? DateTime { get; set; } - - public double? Double { get; set; } - - public static ModelWithFieldsOfDifferentTypesAsNullables Create(int id) - { - var row = new ModelWithFieldsOfDifferentTypesAsNullables { - Id = id, - Bool = id % 2 == 0, - DateTime = System.DateTime.Now.AddDays(id), - Double = 1.11d + id, - Guid = System.Guid.NewGuid(), - LongId = 999 + id, - Name = "Name" + id - }; - - return row; - } - - public static ModelWithFieldsOfDifferentTypesAsNullables CreateConstant(int id) - { - var row = new ModelWithFieldsOfDifferentTypesAsNullables { - Id = id, - Bool = id % 2 == 0, - DateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), - Double = 1.11d + id, - Guid = new Guid(((id % 240) + 16).ToString("X") + "726E3B-9983-40B4-A8CB-2F8ADA8C8760"), - LongId = 999 + id, - Name = "Name" + id - }; - - return row; - } - - public static void AssertIsEqual(ModelWithFieldsOfDifferentTypes actual, ModelWithFieldsOfDifferentTypesAsNullables expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id.Value)); - Assert.That(actual.Name, Is.EqualTo(expected.Name)); - Assert.That(actual.Guid, Is.EqualTo(expected.Guid.Value)); - Assert.That(actual.LongId, Is.EqualTo(expected.LongId.Value)); - Assert.That(actual.Bool, Is.EqualTo(expected.Bool.Value)); - try - { - Assert.That(actual.DateTime, Is.EqualTo(expected.DateTime.Value)); - } - catch (Exception ex) - { - Log.Error("Trouble with DateTime precisions, trying Assert again with rounding to seconds", ex); - Assert.That(actual.DateTime.RoundToSecond(), Is.EqualTo(expected.DateTime.Value.RoundToSecond())); - } - try - { - Assert.That(actual.Double, Is.EqualTo(expected.Double.Value)); - } - catch (Exception ex) - { - Log.Error("Trouble with double precisions, trying Assert again with rounding to 10 decimals", ex); - Assert.That(Math.Round(actual.Double, 10), Is.EqualTo(Math.Round(actual.Double, 10))); - } - } - } - - - public class ModelWithFieldsOfDifferentTypes - { - private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfDifferentTypes)); - - [AutoIncrement] - public int Id { get; set; } - - public string Name { get; set; } - - public long LongId { get; set; } - - public Guid Guid { get; set; } - - public bool Bool { get; set; } + public class ModelWithFieldsOfDifferentTypesAsNullables + { + private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfDifferentTypesAsNullables)); + + public int? Id { get; set; } + + public string Name { get; set; } + + public long? LongId { get; set; } + + public Guid? Guid { get; set; } + + public bool? Bool { get; set; } + + public DateTime? DateTime { get; set; } + + public double? Double { get; set; } + + public static ModelWithFieldsOfDifferentTypesAsNullables Create(int id) + { + var row = new ModelWithFieldsOfDifferentTypesAsNullables + { + Id = id, + Bool = id % 2 == 0, + DateTime = System.DateTime.Now.AddDays(id), + Double = 1.11d + id, + Guid = System.Guid.NewGuid(), + LongId = 999 + id, + Name = "Name" + id + }; + + return row; + } + + public static ModelWithFieldsOfDifferentTypesAsNullables CreateConstant(int id) + { + var row = new ModelWithFieldsOfDifferentTypesAsNullables + { + Id = id, + Bool = id % 2 == 0, + DateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), + Double = 1.11d + id, + Guid = new Guid(((id % 240) + 16).ToString("X") + "726E3B-9983-40B4-A8CB-2F8ADA8C8760"), + LongId = 999 + id, + Name = "Name" + id + }; + + return row; + } + + public static void AssertIsEqual(ModelWithFieldsOfDifferentTypes actual, ModelWithFieldsOfDifferentTypesAsNullables expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id.Value)); + Assert.That(actual.Name, Is.EqualTo(expected.Name)); + Assert.That(actual.Guid, Is.EqualTo(expected.Guid.Value)); + Assert.That(actual.Long, Is.EqualTo(expected.LongId.Value)); + Assert.That(actual.Bool, Is.EqualTo(expected.Bool.Value)); + try + { + Assert.That(actual.DateTime, Is.EqualTo(expected.DateTime.Value)); + } + catch (Exception ex) + { + Log.Error("Trouble with DateTime precisions, trying Assert again with rounding to seconds", ex); + Assert.That(actual.DateTime.RoundToSecond(), Is.EqualTo(expected.DateTime.Value.RoundToSecond())); + } + try + { + Assert.That(actual.Double, Is.EqualTo(expected.Double.Value)); + } + catch (Exception ex) + { + Log.Error("Trouble with double precisions, trying Assert again with rounding to 10 decimals", ex); + Assert.That(Math.Round(actual.Double, 10), Is.EqualTo(Math.Round(actual.Double, 10))); + } + } + } + + + public class ModelWithFieldsOfDifferentTypes + { + private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfDifferentTypes)); + + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + + public int Int { get; set; } + + public long Long { get; set; } + + public Guid Guid { get; set; } + + public bool Bool { get; set; } public DateTime DateTime { get; set; } public TimeSpan TimeSpan { get; set; } - public double Double { get; set; } - - public static ModelWithFieldsOfDifferentTypes Create(int id) - { - var row = new ModelWithFieldsOfDifferentTypes { - Id = id, - Bool = id % 2 == 0, - DateTime = DateTime.Now.AddDays(id), - Double = 1.11d + id, - Guid = Guid.NewGuid(), - LongId = 999 + id, - Name = "Name" + id - }; - - return row; - } - - public static ModelWithFieldsOfDifferentTypes CreateConstant(int id) - { - var row = new ModelWithFieldsOfDifferentTypes { - Id = id, - Bool = id % 2 == 0, - DateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), - Double = 1.11d + id, - Guid = new Guid(((id % 240) + 16).ToString("X") + "726E3B-9983-40B4-A8CB-2F8ADA8C8760"), - LongId = 999 + id, - Name = "Name" + id - }; - - return row; - } - - public override bool Equals(object obj) - { - var other = obj as ModelWithFieldsOfDifferentTypes; - if (other == null) return false; - - try - { - AssertIsEqual(this, other); - return true; - } - catch (Exception) - { - return false; - } - } - - public override int GetHashCode() - { - return (Id + Guid.ToString()).GetHashCode(); - } - - public static void AssertIsEqual(ModelWithFieldsOfDifferentTypes actual, ModelWithFieldsOfDifferentTypes expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.Name, Is.EqualTo(expected.Name)); - Assert.That(actual.Guid, Is.EqualTo(expected.Guid)); - Assert.That(actual.LongId, Is.EqualTo(expected.LongId)); - Assert.That(actual.Bool, Is.EqualTo(expected.Bool)); - try - { - Assert.That(actual.DateTime, Is.EqualTo(expected.DateTime)); - } - catch (Exception ex) - { - Log.Error("Trouble with DateTime precisions, trying Assert again with rounding to seconds", ex); - Assert.That(actual.DateTime.RoundToSecond(), Is.EqualTo(expected.DateTime.RoundToSecond())); - } - try - { - Assert.That(actual.Double, Is.EqualTo(expected.Double)); - } - catch (Exception ex) - { - Log.Error("Trouble with double precisions, trying Assert again with rounding to 10 decimals", ex); - Assert.That(Math.Round(actual.Double, 10), Is.EqualTo(Math.Round(actual.Double, 10))); - } - } - } + public double Double { get; set; } + + public decimal Decimal { get; set; } + + public static ModelWithFieldsOfDifferentTypes Create(int id) + { + var row = new ModelWithFieldsOfDifferentTypes + { + Id = id, + Bool = id % 2 == 0, + DateTime = DateTime.Now.AddDays(id), + Double = 1.11d + id, + Decimal = 2.22m + id, + Guid = Guid.NewGuid(), + Int = 10 + id, + Long = 999 + id, + Name = "Name" + id + }; + + return row; + } + + public static ModelWithFieldsOfDifferentTypes CreateConstant(int id) + { + var row = new ModelWithFieldsOfDifferentTypes + { + Id = id, + Bool = id % 2 == 0, + DateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), + Double = 1.11d + id, + Decimal = 2.22m + id, + Guid = new Guid(((id % 240) + 16).ToString("X") + "726E3B-9983-40B4-A8CB-2F8ADA8C8760"), + Int = 10 + id, + Long = 999 + id, + Name = "Name" + id + }; + + return row; + } + + public override bool Equals(object obj) + { + var other = obj as ModelWithFieldsOfDifferentTypes; + if (other == null) return false; + + try + { + AssertIsEqual(this, other); + return true; + } + catch (Exception) + { + return false; + } + } + + public override int GetHashCode() + { + return (Id + Guid.ToString()).GetHashCode(); + } + + public static void AssertIsEqual(ModelWithFieldsOfDifferentTypes actual, ModelWithFieldsOfDifferentTypes expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.Name, Is.EqualTo(expected.Name)); + Assert.That(actual.Guid, Is.EqualTo(expected.Guid)); + Assert.That(actual.Long, Is.EqualTo(expected.Long)); + Assert.That(actual.Bool, Is.EqualTo(expected.Bool)); + + Assert.That(actual.DateTime, Is.EqualTo(expected.DateTime).Within(TimeSpan.FromSeconds(1))); + + try + { + Assert.That(actual.Double, Is.EqualTo(expected.Double)); + } + catch (Exception ex) + { + Log.Error("Trouble with double precisions, trying Assert again with rounding to 10 decimals", ex); + Assert.That(Math.Round(actual.Double, 10), Is.EqualTo(Math.Round(actual.Double, 10))); + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypesFactory.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypesFactory.cs index 5299d7d0a..b9f427891 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypesFactory.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfDifferentTypesFactory.cs @@ -1,22 +1,20 @@ -using System; - namespace ServiceStack.Common.Tests.Models { - public class ModelWithFieldsOfDifferentTypesFactory - : ModelFactoryBase - { - public static ModelWithFieldsOfDifferentTypesFactory Instance - = new ModelWithFieldsOfDifferentTypesFactory(); + public class ModelWithFieldsOfDifferentTypesFactory + : ModelFactoryBase + { + public static ModelWithFieldsOfDifferentTypesFactory Instance + = new ModelWithFieldsOfDifferentTypesFactory(); - public override void AssertIsEqual( - ModelWithFieldsOfDifferentTypes actual, ModelWithFieldsOfDifferentTypes expected) - { - ModelWithFieldsOfDifferentTypes.AssertIsEqual(actual, expected); - } + public override void AssertIsEqual( + ModelWithFieldsOfDifferentTypes actual, ModelWithFieldsOfDifferentTypes expected) + { + ModelWithFieldsOfDifferentTypes.AssertIsEqual(actual, expected); + } - public override ModelWithFieldsOfDifferentTypes CreateInstance(int i) - { - return ModelWithFieldsOfDifferentTypes.CreateConstant(i); - } - } + public override ModelWithFieldsOfDifferentTypes CreateInstance(int i) + { + return ModelWithFieldsOfDifferentTypes.CreateConstant(i); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypes.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypes.cs index 2a298c36c..1fdbf4b9c 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypes.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypes.cs @@ -2,109 +2,82 @@ using NUnit.Framework; using ServiceStack.Model; using ServiceStack.Logging; -using ServiceStack.Text; namespace ServiceStack.Common.Tests.Models { - public class ModelWithFieldsOfNullableTypes - : IHasIntId - { - private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfNullableTypes)); - - public int Id { get; set; } - public int? NId { get; set; } - - public long? NLongId { get; set; } - - public Guid? NGuid { get; set; } - - public bool? NBool { get; set; } - - public DateTime? NDateTime { get; set; } - - public float? NFloat { get; set; } - - public double? NDouble { get; set; } - - public decimal? NDecimal { get; set; } - - public TimeSpan? NTimeSpan { get; set; } - - public static ModelWithFieldsOfNullableTypes Create(int id) - { - var row = new ModelWithFieldsOfNullableTypes { - Id = id, - NId = id, - NBool = id % 2 == 0, - NDateTime = DateTime.Now.AddDays(id), - NFloat = 1.11f + id, - NDouble = 1.11d + id, - NGuid = Guid.NewGuid(), - NLongId = 999 + id, - NDecimal = id + 0.5m, - NTimeSpan = TimeSpan.FromSeconds(id), - }; - - return row; - } - - public static ModelWithFieldsOfNullableTypes CreateConstant(int id) - { - var row = new ModelWithFieldsOfNullableTypes { - Id = id, - NId = id, - NBool = id % 2 == 0, - NDateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), - NFloat = 1.11f + id, - NDouble = 1.11d + id, - NGuid = new Guid(((id % 240) + 16).ToString("X") + "7DA519-73B6-4525-84BA-B57673B2360D"), - NLongId = 999 + id, - NDecimal = id + 0.5m, - NTimeSpan = TimeSpan.FromSeconds(id), - }; - - return row; - } - - public static void AssertIsEqual(ModelWithFieldsOfNullableTypes actual, ModelWithFieldsOfNullableTypes expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.NId, Is.EqualTo(expected.NId)); - Assert.That(actual.NGuid, Is.EqualTo(expected.NGuid)); - Assert.That(actual.NLongId, Is.EqualTo(expected.NLongId)); - Assert.That(actual.NBool, Is.EqualTo(expected.NBool)); - Assert.That(actual.NTimeSpan, Is.EqualTo(expected.NTimeSpan)); - - try - { - Assert.That(actual.NDateTime, Is.EqualTo(expected.NDateTime)); - } - catch (Exception ex) - { - Log.Error("Trouble with DateTime precisions, trying Assert again with rounding to seconds", ex); - Assert.That(actual.NDateTime.Value.ToUniversalTime().RoundToSecond(), Is.EqualTo(expected.NDateTime.Value.ToUniversalTime().RoundToSecond())); - } - - try - { - Assert.That(actual.NFloat, Is.EqualTo(expected.NFloat)); - } - catch (Exception ex) - { - Log.Error("Trouble with float precisions, trying Assert again with rounding to 10 decimals", ex); - Assert.That(Math.Round(actual.NFloat.Value, 10), Is.EqualTo(Math.Round(actual.NFloat.Value, 10))); - } - - try - { - Assert.That(actual.NDouble, Is.EqualTo(expected.NDouble)); - } - catch (Exception ex) - { - Log.Error("Trouble with double precisions, trying Assert again with rounding to 10 decimals", ex); - Assert.That(Math.Round(actual.NDouble.Value, 10), Is.EqualTo(Math.Round(actual.NDouble.Value, 10))); - } - - } - } + public class ModelWithFieldsOfNullableTypes + : IHasIntId + { + private static readonly ILog Log = LogManager.GetLogger(typeof(ModelWithFieldsOfNullableTypes)); + + public int Id { get; set; } + public int? NId { get; set; } + + public long? NLongId { get; set; } + + public Guid? NGuid { get; set; } + + public bool? NBool { get; set; } + + public DateTime? NDateTime { get; set; } + + public float? NFloat { get; set; } + + public double? NDouble { get; set; } + + public decimal? NDecimal { get; set; } + + public TimeSpan? NTimeSpan { get; set; } + + public static ModelWithFieldsOfNullableTypes Create(int id) + { + var row = new ModelWithFieldsOfNullableTypes + { + Id = id, + NId = id, + NBool = id % 2 == 0, + NDateTime = DateTime.Now.AddDays(id), + NFloat = 1.11f + id, + NDouble = 1.11d + id, + NGuid = Guid.NewGuid(), + NLongId = 999 + id, + NDecimal = id + 0.5m, + NTimeSpan = TimeSpan.FromSeconds(id), + }; + + return row; + } + + public static ModelWithFieldsOfNullableTypes CreateConstant(int id) + { + var row = new ModelWithFieldsOfNullableTypes + { + Id = id, + NId = id, + NBool = id % 2 == 0, + NDateTime = new DateTime(1979, (id % 12) + 1, (id % 28) + 1), + NFloat = 1.11f + id, + NDouble = 1.11d + id, + NGuid = new Guid(((id % 240) + 16).ToString("X") + "7DA519-73B6-4525-84BA-B57673B2360D"), + NLongId = 999 + id, + NDecimal = id + 0.5m, + NTimeSpan = TimeSpan.FromSeconds(id), + }; + + return row; + } + + public static void AssertIsEqual(ModelWithFieldsOfNullableTypes actual, ModelWithFieldsOfNullableTypes expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.NId, Is.EqualTo(expected.NId)); + Assert.That(actual.NGuid, Is.EqualTo(expected.NGuid)); + Assert.That(actual.NLongId, Is.EqualTo(expected.NLongId)); + Assert.That(actual.NBool, Is.EqualTo(expected.NBool)); + Assert.That(actual.NTimeSpan, Is.EqualTo(expected.NTimeSpan)); + Assert.That(actual.NDateTime, Is.EqualTo(expected.NDateTime).Within(TimeSpan.FromSeconds(1))); + Assert.That(actual.NFloat, Is.EqualTo(expected.NFloat).Within(1f)); + Assert.That(actual.NDouble, Is.EqualTo(expected.NDouble).Within(1d)); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypesFactory.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypesFactory.cs index 1fde381ec..1c04743ca 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypesFactory.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithFieldsOfNullableTypesFactory.cs @@ -1,20 +1,20 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithFieldsOfNullableTypesFactory - : ModelFactoryBase - { - public static ModelWithFieldsOfNullableTypesFactory Instance - = new ModelWithFieldsOfNullableTypesFactory(); + public class ModelWithFieldsOfNullableTypesFactory + : ModelFactoryBase + { + public static ModelWithFieldsOfNullableTypesFactory Instance + = new ModelWithFieldsOfNullableTypesFactory(); - public override void AssertIsEqual( - ModelWithFieldsOfNullableTypes actual, ModelWithFieldsOfNullableTypes expected) - { - ModelWithFieldsOfNullableTypes.AssertIsEqual(actual, expected); - } + public override void AssertIsEqual( + ModelWithFieldsOfNullableTypes actual, ModelWithFieldsOfNullableTypes expected) + { + ModelWithFieldsOfNullableTypes.AssertIsEqual(actual, expected); + } - public override ModelWithFieldsOfNullableTypes CreateInstance(int i) - { - return ModelWithFieldsOfNullableTypes.CreateConstant(i); - } - } + public override ModelWithFieldsOfNullableTypes CreateInstance(int i) + { + return ModelWithFieldsOfNullableTypes.CreateConstant(i); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdAndName.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdAndName.cs index 76aa47073..c84f65015 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdAndName.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdAndName.cs @@ -1,64 +1,63 @@ -using System; using NUnit.Framework; using ServiceStack.DataAnnotations; namespace ServiceStack.Common.Tests.Models { - public class ModelWithIdAndName - { - public ModelWithIdAndName() - { - } - - public ModelWithIdAndName(int id) - { - Id = id; - Name = "Name" + id; - } + public class ModelWithIdAndName + { + public ModelWithIdAndName() + { + } + + public ModelWithIdAndName(int id) + { + Id = id; + Name = "Name" + id; + } [AutoIncrement] - public int Id { get; set; } - - public string Name { get; set; } - - public static ModelWithIdAndName Create(int id) - { - return new ModelWithIdAndName(id); - } - - public static void AssertIsEqual(ModelWithIdAndName actual, ModelWithIdAndName expected) - { - if (actual == null || expected == null) - { - Assert.That(actual == expected, Is.True); - return; - } - - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.Name, Is.EqualTo(expected.Name)); - } - - public bool Equals(ModelWithIdAndName other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return other.Id == Id && Equals(other.Name, Name); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != typeof (ModelWithIdAndName)) return false; - return Equals((ModelWithIdAndName) obj); - } - - public override int GetHashCode() - { - unchecked - { - return (Id*397) ^ (Name != null ? Name.GetHashCode() : 0); - } - } - } + public int Id { get; set; } + + public string Name { get; set; } + + public static ModelWithIdAndName Create(int id) + { + return new ModelWithIdAndName(id); + } + + public static void AssertIsEqual(ModelWithIdAndName actual, ModelWithIdAndName expected) + { + if (actual == null || expected == null) + { + Assert.That(actual == expected, Is.True); + return; + } + + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.Name, Is.EqualTo(expected.Name)); + } + + public bool Equals(ModelWithIdAndName other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return other.Id == Id && Equals(other.Name, Name); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof(ModelWithIdAndName)) return false; + return Equals((ModelWithIdAndName)obj); + } + + public override int GetHashCode() + { + unchecked + { + return (Id * 397) ^ (Name != null ? Name.GetHashCode() : 0); + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdOnly.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdOnly.cs index 4d2684e3b..2c531b6a0 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdOnly.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIdOnly.cs @@ -1,18 +1,18 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithIdOnly - { - public ModelWithIdOnly() - { - } + public class ModelWithIdOnly + { + public ModelWithIdOnly() + { + } - public ModelWithIdOnly(long id) - { - Id = id; - } + public ModelWithIdOnly(long id) + { + Id = id; + } - // must be long as you cannot have a table with only an autoincrement field - public long Id { get; set; } + // must be long as you cannot have a table with only an autoincrement field + public long Id { get; set; } - } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIndexFields.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIndexFields.cs index 97c93669b..b4069625d 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIndexFields.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithIndexFields.cs @@ -2,16 +2,19 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithIndexFields - { - public string Id { get; set; } + public class ModelWithIndexFields + { + public string Id { get; set; } - [Index] - public string Name { get; set; } + [Index] + public string Name { get; set; } - public string AlbumId { get; set; } + public string AlbumId { get; set; } - [Index(true)] - public string UniqueName { get; set; } - } + [Index(true)] + public string UniqueName { get; set; } + + [Index(Name = "altname")] + public string Custom { get; set; } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithLongIdAndStringFields.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithLongIdAndStringFields.cs index 8201895bc..12a696ba7 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithLongIdAndStringFields.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithLongIdAndStringFields.cs @@ -1,13 +1,13 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithLongIdAndStringFields - { - public long Id { get; set; } + public class ModelWithLongIdAndStringFields + { + public long Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public string AlbumId { get; set; } + public string AlbumId { get; set; } - public string AlbumName { get; set; } - } + public string AlbumName { get; set; } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithMapAndList.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithMapAndList.cs index e7b178b78..60c911e6a 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithMapAndList.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithMapAndList.cs @@ -3,40 +3,40 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithMapAndList - { - public ModelWithMapAndList() - { - this.Map = new Dictionary(); - this.List = new List(); - } - - public ModelWithMapAndList(int id) - : this() - { - Id = id; - Name = "Name" + id; - } - - public int Id { get; set; } - - public string Name { get; set; } - - public Dictionary Map { get; set; } - - public List List { get; set; } - - public static ModelWithMapAndList Create(int id) - { - return new ModelWithMapAndList(id); - } - - public static void AssertIsEqual(ModelWithMapAndList actual, ModelWithMapAndList expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.Name, Is.EqualTo(expected.Name)); - Assert.That(actual.Map, Is.EquivalentTo(expected.Map)); - Assert.That(actual.List, Is.EquivalentTo(expected.List)); - } - } + public class ModelWithMapAndList + { + public ModelWithMapAndList() + { + this.Map = new Dictionary(); + this.List = new List(); + } + + public ModelWithMapAndList(int id) + : this() + { + Id = id; + Name = "Name" + id; + } + + public int Id { get; set; } + + public string Name { get; set; } + + public Dictionary Map { get; set; } + + public List List { get; set; } + + public static ModelWithMapAndList Create(int id) + { + return new ModelWithMapAndList(id); + } + + public static void AssertIsEqual(ModelWithMapAndList actual, ModelWithMapAndList expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.Name, Is.EqualTo(expected.Name)); + Assert.That(actual.Map, Is.EquivalentTo(expected.Map)); + Assert.That(actual.List, Is.EquivalentTo(expected.List)); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNamedCompositeIndex.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNamedCompositeIndex.cs index 7e9221ed8..28670876b 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNamedCompositeIndex.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNamedCompositeIndex.cs @@ -2,21 +2,21 @@ namespace ServiceStack.Common.Tests.Models { - [CompositeIndex(true, "Composite1", "Composite2", Name = "custom_index_name")] - public class ModelWithNamedCompositeIndex - { - public string Id { get; set; } + [CompositeIndex(true, "Composite1", "Composite2", Name = "custom_index_name")] + public class ModelWithNamedCompositeIndex + { + public string Id { get; set; } - [Index] - public string Name { get; set; } + [Index] + public string Name { get; set; } - public string AlbumId { get; set; } + public string AlbumId { get; set; } - [Index(true)] - public string UniqueName { get; set; } + [Index(true)] + public string UniqueName { get; set; } - public string Composite1 { get; set; } + public string Composite1 { get; set; } - public string Composite2 { get; set; } - } + public string Composite2 { get; set; } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNumerics.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNumerics.cs index de448f1ca..70974b7f2 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNumerics.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithNumerics.cs @@ -28,14 +28,14 @@ public bool Equals(ModelWithNumerics x, ModelWithNumerics y) if (x.GetType() != y.GetType()) return false; return x.Byte == y.Byte && x.SByte == y.SByte - && x.Short == y.Short - && x.UShort == y.UShort - && x.Int == y.Int - && x.UInt == y.UInt - && x.Long == y.Long - && x.ULong == y.ULong - && x.Float.Equals(y.Float) - && x.Double.Equals(y.Double) + && x.Short == y.Short + && x.UShort == y.UShort + && x.Int == y.Int + && x.UInt == y.UInt + && x.Long == y.Long + && x.ULong == y.ULong + && x.Float.Equals(y.Float) + && x.Double.Equals(y.Double) && x.Decimal == y.Decimal; } @@ -44,16 +44,16 @@ public int GetHashCode(ModelWithNumerics obj) unchecked { var hashCode = obj.Byte.GetHashCode(); - hashCode = (hashCode*397) ^ obj.SByte.GetHashCode(); - hashCode = (hashCode*397) ^ obj.Short.GetHashCode(); - hashCode = (hashCode*397) ^ obj.UShort.GetHashCode(); - hashCode = (hashCode*397) ^ obj.Int; - hashCode = (hashCode*397) ^ (int) obj.UInt; - hashCode = (hashCode*397) ^ obj.Long.GetHashCode(); - hashCode = (hashCode*397) ^ obj.ULong.GetHashCode(); - hashCode = (hashCode*397) ^ obj.Float.GetHashCode(); - hashCode = (hashCode*397) ^ obj.Double.GetHashCode(); - hashCode = (hashCode*397) ^ obj.Decimal.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.SByte.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.Short.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.UShort.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.Int; + hashCode = (hashCode * 397) ^ (int)obj.UInt; + hashCode = (hashCode * 397) ^ obj.Long.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.ULong.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.Float.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.Double.GetHashCode(); + hashCode = (hashCode * 397) ^ obj.Decimal.GetHashCode(); return hashCode; } } diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithOnlyStringFields.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithOnlyStringFields.cs index 64621d0f4..c85225400 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithOnlyStringFields.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ModelWithOnlyStringFields.cs @@ -1,23 +1,24 @@ namespace ServiceStack.Common.Tests.Models { - public class ModelWithOnlyStringFields - { - public string Id { get; set; } + public class ModelWithOnlyStringFields + { + public string Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public string AlbumId { get; set; } + public string AlbumId { get; set; } - public string AlbumName { get; set; } + public string AlbumName { get; set; } - public static ModelWithOnlyStringFields Create(string id) - { - return new ModelWithOnlyStringFields { - Id = id, - Name = "Name", - AlbumId = "AlbumId", - AlbumName = "AlbumName", - }; - } - } + public static ModelWithOnlyStringFields Create(string id) + { + return new ModelWithOnlyStringFields + { + Id = id, + Name = "Name", + AlbumId = "AlbumId", + AlbumName = "AlbumName", + }; + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/Movie.cs b/tests/ServiceStack.OrmLite.Tests/Shared/Movie.cs index f935ea4fb..fd670386d 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/Movie.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/Movie.cs @@ -4,63 +4,63 @@ namespace ServiceStack.Common.Tests.Models { - [DataContract] - public class Movie - { - public Movie() - { - this.Genres = new List(); - } + [DataContract] + public class Movie + { + public Movie() + { + this.Genres = new List(); + } - [DataMember] - public string Id { get; set; } + [DataMember] + public string Id { get; set; } - [DataMember] - public string Title { get; set; } + [DataMember] + public string Title { get; set; } - [DataMember] - public decimal Rating { get; set; } + [DataMember] + public decimal Rating { get; set; } - [DataMember] - public string Director { get; set; } + [DataMember] + public string Director { get; set; } - [DataMember] - public DateTime ReleaseDate { get; set; } + [DataMember] + public DateTime ReleaseDate { get; set; } - [DataMember] - public string TagLine { get; set; } + [DataMember] + public string TagLine { get; set; } - [DataMember] - public List Genres { get; set; } + [DataMember] + public List Genres { get; set; } - public bool Equals(Movie other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Equals(other.Id, Id) && Equals(other.Title, Title) && other.Rating == Rating && Equals(other.Director, Director) && other.ReleaseDate.Equals(ReleaseDate) && Equals(other.TagLine, TagLine) && Genres.EquivalentTo(other.Genres); - } + public bool Equals(Movie other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(other.Id, Id) && Equals(other.Title, Title) && other.Rating == Rating && Equals(other.Director, Director) && other.ReleaseDate.Equals(ReleaseDate) && Equals(other.TagLine, TagLine) && Genres.EquivalentTo(other.Genres); + } - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != typeof (Movie)) return false; - return Equals((Movie) obj); - } + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof(Movie)) return false; + return Equals((Movie)obj); + } - public override int GetHashCode() - { - unchecked - { - int result = (Id != null ? Id.GetHashCode() : 0); - result = (result*397) ^ (Title != null ? Title.GetHashCode() : 0); - result = (result*397) ^ Rating.GetHashCode(); - result = (result*397) ^ (Director != null ? Director.GetHashCode() : 0); - result = (result*397) ^ ReleaseDate.GetHashCode(); - result = (result*397) ^ (TagLine != null ? TagLine.GetHashCode() : 0); - result = (result*397) ^ (Genres != null ? Genres.GetHashCode() : 0); - return result; - } - } - } + public override int GetHashCode() + { + unchecked + { + int result = (Id != null ? Id.GetHashCode() : 0); + result = (result * 397) ^ (Title != null ? Title.GetHashCode() : 0); + result = (result * 397) ^ Rating.GetHashCode(); + result = (result * 397) ^ (Director != null ? Director.GetHashCode() : 0); + result = (result * 397) ^ ReleaseDate.GetHashCode(); + result = (result * 397) ^ (TagLine != null ? TagLine.GetHashCode() : 0); + result = (result * 397) ^ (Genres != null ? Genres.GetHashCode() : 0); + return result; + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/MultipleTables.cs b/tests/ServiceStack.OrmLite.Tests/Shared/MultipleTables.cs new file mode 100644 index 000000000..f3c948a75 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Shared/MultipleTables.cs @@ -0,0 +1,51 @@ +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Shared +{ + public class Table1 + { + public int Id { get; set; } + public string String { get; set; } + public string Field1 { get; set; } + } + public class Table2 + { + public int Id { get; set; } + public string String { get; set; } + public string Field2 { get; set; } + } + public class Table3 + { + public int Id { get; set; } + public string String { get; set; } + public string Field3 { get; set; } + } + public class Table4 + { + public int Id { get; set; } + public string String { get; set; } + public string Field4 { get; set; } + } + public class Table5 + { + public int Id { get; set; } + public string String { get; set; } + public string Field5 { get; set; } + } + + [Schema("Schema")] + public class Schematable1 + { + public int Id { get; set; } + public string String { get; set; } + public string Field1 { get; set; } + } + [Schema("Schema")] + public class Schematable2 + { + public int Id { get; set; } + public string String { get; set; } + public string Field2 { get; set; } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs index 6131cfd8e..f80b06bfa 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/Person.cs @@ -1,16 +1,17 @@ -using ServiceStack.DataAnnotations; +using System; +using ServiceStack.DataAnnotations; namespace ServiceStack.OrmLite.Tests.Shared { public class Person { public static Person[] Rockstars = new[] { - new Person(1, "Jimi", "Hendrix", 27), - new Person(2, "Janis", "Joplin", 27), - new Person(3, "Jim", "Morrisson", 27), - new Person(4, "Kurt", "Cobain", 27), - new Person(5, "Elvis", "Presley", 42), - new Person(6, "Michael", "Jackson", 50), + new Person(1, "Jimi", "Hendrix", 27), + new Person(2, "Janis", "Joplin", 27), + new Person(3, "Jim", "Morrisson", 27), + new Person(4, "Kurt", "Cobain", 27), + new Person(5, "Elvis", "Presley", 42), + new Person(6, "Michael", "Jackson", 50), }; public int Id { get; set; } @@ -26,6 +27,34 @@ public Person(int id, string firstName, string lastName, int age) LastName = lastName; Age = age; } + + protected bool Equals(Person other) + { + return Id == other.Id && + string.Equals(FirstName, other.FirstName) && + string.Equals(LastName, other.LastName) && + Age == other.Age; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((Person)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Id; + hashCode = (hashCode * 397) ^ (FirstName != null ? FirstName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LastName != null ? LastName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Age; + return hashCode; + } + } } public class PersonWithAutoId @@ -51,4 +80,127 @@ public class EntityWithId public int Id { get; set; } } + + public class PersonWithAliasedAge + { + [PrimaryKey] + public string Name { get; set; } + + [Alias("YearsOld")] + public int Age { get; set; } + + public string Ignored { get; set; } + } + + public class PersonUsingEnumAsInt + { + public string Name { get; set; } + public Gender Gender { get; set; } + } + + [EnumAsInt] + public enum Gender + { + Unknown = 0, + Female, + Male + } + + public class PersonWithReferenceType + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public Person BestFriend { get; set; } + + public static PersonWithReferenceType[] TestValues = new[] + { + new PersonWithReferenceType + { + FirstName = "Test", + LastName = "McTest", + Id = 1 + }, + new PersonWithReferenceType + { + FirstName = "John", + LastName = "Doe", + Id = 2, + BestFriend = new Person(1,"Jane","Doe",33) + } + }; + + protected bool Equals(PersonWithReferenceType other) + { + return Id == other.Id && + string.Equals(FirstName, other.FirstName) && + string.Equals(LastName, other.LastName) && + ((BestFriend == null && other.BestFriend == null) || (BestFriend != null && BestFriend.Equals(other.BestFriend))) ; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((PersonWithReferenceType)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Id; + hashCode = (hashCode * 397) ^ (FirstName != null ? FirstName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LastName != null ? LastName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (BestFriend != null ? BestFriend.GetHashCode() : 0); + return hashCode; + } + } + } + + public class TestProduct + { + public string Id { get; set; } + + public string Name { get; set; } + + public DateTime? Modified { get; set; } + + public static TestProduct[] TestValues = + { + new TestProduct + { + Id = "1", + Modified = null, + Name = "Testing" + } + }; + + protected bool Equals(TestProduct other) + { + return Id == other.Id && + string.Equals(Name, other.Name) && + Modified.Equals(other.Modified); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((TestProduct)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (Id != null ? Id.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Name != null ? Name.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Modified != null ? Modified.GetHashCode() : 0); + return hashCode; + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/Poco.cs b/tests/ServiceStack.OrmLite.Tests/Shared/Poco.cs index 476cbb551..35b593b99 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/Poco.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/Poco.cs @@ -2,6 +2,7 @@ { public class Poco { - public string Name { get; set; } + public int Id { get; set; } + public string Name { get; set; } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/SampleOrderLine.cs b/tests/ServiceStack.OrmLite.Tests/Shared/SampleOrderLine.cs index 22c93f153..5ab624f54 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/SampleOrderLine.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/SampleOrderLine.cs @@ -1,152 +1,144 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using ServiceStack.Model; namespace ServiceStack.Common.Tests.Models { - public class SampleOrderLine - : IHasStringId - { - public string Id { get; set; } + public class SampleOrderLine + : IHasStringId + { + public string Id { get; set; } - public string OrderUrn - { - get - { - return CreateUrn(this.UserId, this.OrderId, this.OrderLineId); - } - } + public string OrderUrn => CreateUrn(this.UserId, this.OrderId, this.OrderLineId); - public long OrderId { get; set; } + public long OrderId { get; set; } - public long OrderLineId { get; set; } + public long OrderLineId { get; set; } - public DateTime CreatedDate { get; set; } + public DateTime CreatedDate { get; set; } - public Guid UserId { get; set; } + public Guid UserId { get; set; } - public string UserName { get; set; } + public string UserName { get; set; } - public Guid ProductId { get; set; } + public Guid ProductId { get; set; } - public string MflowUrn { get; set; } + public string MflowUrn { get; set; } - public string ProductType { get; set; } + public string ProductType { get; set; } - public string Description { get; set; } + public string Description { get; set; } - public string UpcEan { get; set; } + public string UpcEan { get; set; } - public string Isrc { get; set; } + public string Isrc { get; set; } - public Guid? RecommendationUserId { get; set; } + public Guid? RecommendationUserId { get; set; } - public string RecommendationUserName { get; set; } + public string RecommendationUserName { get; set; } - public string SupplierKeyName { get; set; } + public string SupplierKeyName { get; set; } - public string CostTierKeyName { get; set; } + public string CostTierKeyName { get; set; } - public string PriceTierKeyName { get; set; } + public string PriceTierKeyName { get; set; } - public decimal VatRate { get; set; } + public decimal VatRate { get; set; } - public int ProductPriceIncVat { get; set; } + public int ProductPriceIncVat { get; set; } - public int Quantity { get; set; } + public int Quantity { get; set; } - public decimal TransactionValueExVat { get; set; } + public decimal TransactionValueExVat { get; set; } - public decimal TransactionValueIncVat { get; set; } + public decimal TransactionValueIncVat { get; set; } - public decimal RecommendationDiscountRate { get; set; } + public decimal RecommendationDiscountRate { get; set; } - public decimal DistributionDiscountRate { get; set; } + public decimal DistributionDiscountRate { get; set; } - public decimal RecommendationDiscountAccruedExVat { get; set; } + public decimal RecommendationDiscountAccruedExVat { get; set; } - public decimal DistributionDiscountAccruedExVat { get; set; } + public decimal DistributionDiscountAccruedExVat { get; set; } - public decimal PromoMix { get; set; } + public decimal PromoMix { get; set; } - public decimal DiscountMix { get; set; } + public decimal DiscountMix { get; set; } - public decimal CashMix { get; set; } + public decimal CashMix { get; set; } - public decimal PromoMixValueExVat { get; set; } + public decimal PromoMixValueExVat { get; set; } - public decimal DiscountMixValueExVat { get; set; } + public decimal DiscountMixValueExVat { get; set; } - public decimal CashMixValueIncVat { get; set; } + public decimal CashMixValueIncVat { get; set; } - public string ContentUrn - { - get { return this.MflowUrn; } - set { this.MflowUrn = value; } - } + public string ContentUrn + { + get { return this.MflowUrn; } + set { this.MflowUrn = value; } + } - public string TrackUrn - { - get; - set; - } + public string TrackUrn + { + get; + set; + } - public string Title - { - get; - set; - } + public string Title + { + get; + set; + } - public string ArtistUrn - { - get; - set; - } + public string ArtistUrn + { + get; + set; + } - public string ArtistName - { - get; - set; - } + public string ArtistName + { + get; + set; + } - public string AlbumUrn - { - get; - set; - } + public string AlbumUrn + { + get; + set; + } - public string AlbumName - { - get; - set; - } + public string AlbumName + { + get; + set; + } - public static string CreateUrn(Guid userId, long orderId, long orderLineId) - { - return string.Format("urn:orderline:{0}/{1}/{2}", - userId.ToString("N"), orderId, orderLineId); - } + public static string CreateUrn(Guid userId, long orderId, long orderLineId) + { + return string.Format("urn:orderline:{0}/{1}/{2}", + userId.ToString("N"), orderId, orderLineId); + } - public static SampleOrderLine Create(Guid userId) - { - return Create(userId, 1, 1); - } + public static SampleOrderLine Create(Guid userId) + { + return Create(userId, 1, 1); + } - public static SampleOrderLine Create(Guid userId, int orderId, int orderLineId) - { - return new SampleOrderLine { - Id = CreateUrn(userId, orderId, orderLineId), - CreatedDate = DateTime.Now, - OrderId = orderId, - OrderLineId = orderLineId, - AlbumName = "AlbumName", - CashMixValueIncVat = 0.79m / 1.15m, - TransactionValueExVat = 0.79m, - ContentUrn = "urn:content:" + Guid.NewGuid().ToString("N"), - }; - } + public static SampleOrderLine Create(Guid userId, int orderId, int orderLineId) + { + return new SampleOrderLine + { + Id = CreateUrn(userId, orderId, orderLineId), + CreatedDate = DateTime.Now, + OrderId = orderId, + OrderLineId = orderLineId, + AlbumName = "AlbumName", + CashMixValueIncVat = 0.79m / 1.15m, + TransactionValueExVat = 0.79m, + ContentUrn = "urn:content:" + Guid.NewGuid().ToString("N"), + }; + } - } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/Shipper.cs b/tests/ServiceStack.OrmLite.Tests/Shared/Shipper.cs index 05a495a1b..1af895c3a 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/Shipper.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/Shipper.cs @@ -3,34 +3,34 @@ namespace ServiceStack.Common.Tests.Models { - public class Shipper - : IHasIntId - { - public int Id { get; set; } - public string CompanyName { get; set; } - public ShipperType ShipperType { get; set; } - public DateTime DateCreated { get; set; } - public Guid UniqueRef { get; set; } + public class Shipper + : IHasIntId + { + public int Id { get; set; } + public string CompanyName { get; set; } + public ShipperType ShipperType { get; set; } + public DateTime DateCreated { get; set; } + public Guid UniqueRef { get; set; } - public override bool Equals(object obj) - { - var other = obj as Shipper; - if (other == null) return false; - return this.Id == other.Id && this.UniqueRef == other.UniqueRef; - } + public override bool Equals(object obj) + { + var other = obj as Shipper; + if (other == null) return false; + return this.Id == other.Id && this.UniqueRef == other.UniqueRef; + } - public override int GetHashCode() - { - return string.Concat(Id, UniqueRef).GetHashCode(); - } - } + public override int GetHashCode() + { + return string.Concat(Id, UniqueRef).GetHashCode(); + } + } - public enum ShipperType - { - All = Planes | Trains | Automobiles, - Unknown = 0, - Planes = 1, - Trains = 2, - Automobiles = 4 - } + public enum ShipperType + { + All = Planes | Trains | Automobiles, + Unknown = 0, + Planes = 1, + Trains = 2, + Automobiles = 4 + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/ShipperFactory.cs b/tests/ServiceStack.OrmLite.Tests/Shared/ShipperFactory.cs index 0387177c4..713784e8a 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/ShipperFactory.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/ShipperFactory.cs @@ -3,28 +3,29 @@ namespace ServiceStack.Common.Tests.Models { - public class ShipperFactory - : ModelFactoryBase - { - public override Shipper CreateInstance(int i) - { - var hex = ((i % 240) + 16).ToString("X"); - return new Shipper { - Id = i, - CompanyName = "Shipper" + i, + public class ShipperFactory + : ModelFactoryBase + { + public override Shipper CreateInstance(int i) + { + var hex = ((i % 240) + 16).ToString("X"); + return new Shipper + { + Id = i, + CompanyName = "Shipper" + i, DateCreated = new DateTime(i + 1 % 3000, (i % 11) + 1, (i % 27) + 1, 0, 0, 0, DateTimeKind.Utc), - ShipperType = (ShipperType)(i % 3), - UniqueRef = new Guid(hex + "D148A5-E5F1-4E5A-8C60-52E5A80ACCC6"), - }; - } + ShipperType = (ShipperType)(i % 3), + UniqueRef = new Guid(hex + "D148A5-E5F1-4E5A-8C60-52E5A80ACCC6"), + }; + } - public override void AssertIsEqual(Shipper actual, Shipper expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.CompanyName, Is.EqualTo(expected.CompanyName)); - Assert.That(actual.ShipperType, Is.EqualTo(expected.ShipperType)); - Assert.That(actual.DateCreated, Is.EqualTo(expected.DateCreated)); - Assert.That(actual.UniqueRef, Is.EqualTo(expected.UniqueRef)); - } - } + public override void AssertIsEqual(Shipper actual, Shipper expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.CompanyName, Is.EqualTo(expected.CompanyName)); + Assert.That(actual.ShipperType, Is.EqualTo(expected.ShipperType)); + Assert.That(actual.DateCreated, Is.EqualTo(expected.DateCreated)); + Assert.That(actual.UniqueRef, Is.EqualTo(expected.UniqueRef)); + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/TaskQueue.cs b/tests/ServiceStack.OrmLite.Tests/Shared/TaskQueue.cs index af6442696..f33c2b981 100644 --- a/tests/ServiceStack.OrmLite.Tests/Shared/TaskQueue.cs +++ b/tests/ServiceStack.OrmLite.Tests/Shared/TaskQueue.cs @@ -1,74 +1,66 @@ using System; using NUnit.Framework; using ServiceStack.Logging; -using ServiceStack.Text; namespace ServiceStack.Common.Tests.Models { - public class TaskQueue - { - private static readonly ILog Log = LogManager.GetLogger(typeof(TaskQueue)); - - public const string TaskLoad = "Load"; - public const string TaskIndex = "Index"; - - public const string StatusPending = "Pending"; - public const string StatusStarted = "Started"; - public const string StatusCompleted = "Completed"; - public const string StatusFailed = "Failed"; - - public const int PriorityLow = 0; - public const int PriorityMedium = 1; - public const int PriorityHigh = 2; - - public int Id { get; set; } - - public Guid? UserId { get; set; } - - public string Task { get; set; } - - public string ContentUrn { get; set; } - - public string Status { get; set; } - - public DateTime CreatedDate { get; set; } - - public int Priority { get; set; } - - public int NoOfAttempts { get; set; } - - public string ErrorMessage { get; set; } - - public static TaskQueue Create(int id) - { - return new TaskQueue { - ContentUrn = "urn:track:" + id, - CreatedDate = DateTime.Now, - Task = TaskLoad, - Status = StatusPending, - NoOfAttempts = 0, - }; - } - - public static void AssertIsEqual(TaskQueue actual, TaskQueue expected) - { - Assert.That(actual.Id, Is.EqualTo(expected.Id)); - Assert.That(actual.UserId, Is.EqualTo(expected.UserId)); - Assert.That(actual.ContentUrn, Is.EqualTo(expected.ContentUrn)); - Assert.That(actual.Status, Is.EqualTo(expected.Status)); - try - { - Assert.That(actual.CreatedDate, Is.EqualTo(expected.CreatedDate)); - } - catch (Exception ex) - { - Log.Error("Trouble with DateTime precisions, trying Assert again with rounding to seconds", ex); - Assert.That(actual.CreatedDate.RoundToSecond(), Is.EqualTo(expected.CreatedDate.RoundToSecond())); - } - Assert.That(actual.Priority, Is.EqualTo(expected.Priority)); - Assert.That(actual.NoOfAttempts, Is.EqualTo(expected.NoOfAttempts)); - Assert.That(actual.ErrorMessage, Is.EqualTo(expected.ErrorMessage)); - } - - } + public class TaskQueue + { + private static readonly ILog Log = LogManager.GetLogger(typeof(TaskQueue)); + + public const string TaskLoad = "Load"; + public const string TaskIndex = "Index"; + + public const string StatusPending = "Pending"; + public const string StatusStarted = "Started"; + public const string StatusCompleted = "Completed"; + public const string StatusFailed = "Failed"; + + public const int PriorityLow = 0; + public const int PriorityMedium = 1; + public const int PriorityHigh = 2; + + public int Id { get; set; } + + public Guid? UserId { get; set; } + + public string Task { get; set; } + + public string ContentUrn { get; set; } + + public string Status { get; set; } + + public DateTime CreatedDate { get; set; } + + public int Priority { get; set; } + + public int NoOfAttempts { get; set; } + + public string ErrorMessage { get; set; } + + public static TaskQueue Create(int id) + { + return new TaskQueue + { + ContentUrn = "urn:track:" + id, + CreatedDate = DateTime.Now, + Task = TaskLoad, + Status = StatusPending, + NoOfAttempts = 0, + }; + } + + public static void AssertIsEqual(TaskQueue actual, TaskQueue expected) + { + Assert.That(actual.Id, Is.EqualTo(expected.Id)); + Assert.That(actual.UserId, Is.EqualTo(expected.UserId)); + Assert.That(actual.ContentUrn, Is.EqualTo(expected.ContentUrn)); + Assert.That(actual.Status, Is.EqualTo(expected.Status)); + Assert.That(actual.CreatedDate, Is.EqualTo(expected.CreatedDate).Within(TimeSpan.FromSeconds(1))); + Assert.That(actual.Priority, Is.EqualTo(expected.Priority)); + Assert.That(actual.NoOfAttempts, Is.EqualTo(expected.NoOfAttempts)); + Assert.That(actual.ErrorMessage, Is.EqualTo(expected.ErrorMessage)); + } + + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/Shared/UpdateCommandFilter.cs b/tests/ServiceStack.OrmLite.Tests/Shared/UpdateCommandFilter.cs new file mode 100644 index 000000000..1ef252794 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/Shared/UpdateCommandFilter.cs @@ -0,0 +1,31 @@ +using System.Data; +using System.Reflection; +using System.Text.RegularExpressions; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests.Shared +{ + public static class UpdateCommandFilter + { + public static void SetUpdateDate(this IDbCommand cmd, string fieldName, IOrmLiteDialectProvider dialectProvider) where T : new() + { + var field = typeof(T).GetProperty(fieldName); + var alias = field.GetCustomAttribute(typeof(AliasAttribute)) as AliasAttribute; + var columnName = dialectProvider.GetQuotedColumnName(dialectProvider.NamingStrategy.GetColumnName(alias?.Name ?? field.Name)); + var columnEqual = columnName + "="; + + var defaultValue = dialectProvider.GetDefaultValue(typeof(T), fieldName); + var regex = new Regex(columnEqual + "(" + dialectProvider.ParamString + @"\w*\b)(,|\s)"); + var match = regex.Match(cmd.CommandText); + if (match.Success) + { + cmd.CommandText = regex.Replace(cmd.CommandText, columnEqual + defaultValue + "$2", 1); + cmd.Parameters.RemoveAt(match.Groups[1].Value); + } + else + { + cmd.CommandText = Regex.Replace(cmd.CommandText, @"(^|\s)SET ", "$1SET " + columnEqual + defaultValue + ", "); + } + } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/ShippersExample.cs b/tests/ServiceStack.OrmLite.Tests/ShippersExample.cs index 8134ed3e2..afb2368f9 100644 --- a/tests/ServiceStack.OrmLite.Tests/ShippersExample.cs +++ b/tests/ServiceStack.OrmLite.Tests/ShippersExample.cs @@ -1,15 +1,15 @@ -using System; using System.Data; using NUnit.Framework; using ServiceStack.DataAnnotations; using ServiceStack.Model; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class ShippersExample : OrmLiteTestBase + [TestFixtureOrmLite] + public class ShippersExample : OrmLiteProvidersTestBase { + public ShippersExample(DialectContext context) : base(context) {} + [Alias("Shippers")] public class Shipper : IHasId @@ -88,7 +88,7 @@ public void Shippers_UseCase() Assert.That(db.Select(), Has.Count.EqualTo(2)); - //Performing standard Insert's and Selects + // Performing standard Insert's and Selects db.Insert(new Shipper { CompanyName = "Trains R Us", Phone = "555-TRAINS", ShipperTypeId = trainsType.Id }); db.Insert(new Shipper { CompanyName = "Planes R Us", Phone = "555-PLANES", ShipperTypeId = planesType.Id }); db.Insert(new Shipper { CompanyName = "We do everything!", Phone = "555-UNICORNS", ShipperTypeId = planesType.Id }); @@ -96,22 +96,23 @@ public void Shippers_UseCase() var trainsAreUs = db.Single(q => q.ShipperTypeId == trainsType.Id); Assert.That(trainsAreUs.CompanyName, Is.EqualTo("Trains R Us")); - trainsAreUs = db.SingleFmt("ShipperTypeId".SqlColumn() + " = {0}", trainsType.Id); + trainsAreUs = db.Single("ShipperTypeId".SqlColumn(DialectProvider) + " = @Id".PreNormalizeSql(db), new { trainsType.Id }); Assert.That(trainsAreUs.CompanyName, Is.EqualTo("Trains R Us")); Assert.That(db.Select(q => q.CompanyName == "Trains R Us" || q.Phone == "555-UNICORNS"), Has.Count.EqualTo(2)); - Assert.That(db.SelectFmt("CompanyName".SqlColumn() + " = {0} OR Phone = {1}", "Trains R Us", "555-UNICORNS"), Has.Count.EqualTo(2)); + Assert.That(db.Select("CompanyName".SqlColumn(DialectProvider) + " = @company OR Phone = @phone".PreNormalizeSql(db), + new { company = "Trains R Us", phone = "555-UNICORNS" }), Has.Count.EqualTo(2)); Assert.That(db.Select(q => q.ShipperTypeId == planesType.Id), Has.Count.EqualTo(2)); - Assert.That(db.SelectFmt("ShipperTypeId".SqlColumn() + " = {0}", planesType.Id), Has.Count.EqualTo(2)); + Assert.That(db.Select("ShipperTypeId".SqlColumn(DialectProvider) + " = @Id".PreNormalizeSql(db), new { planesType.Id }), Has.Count.EqualTo(2)); //Lets update a record trainsAreUs.Phone = "666-TRAINS"; db.Update(trainsAreUs); Assert.That(db.SingleById(trainsAreUs.Id).Phone, Is.EqualTo("666-TRAINS")); - //Then make it dissappear + //Then make it disappear db.Delete(trainsAreUs); Assert.That(db.SingleById(trainsAreUs.Id), Is.Null); @@ -124,21 +125,23 @@ public void Shippers_UseCase() var partialColumns = db.Select(db.From().Where(q => q.ShipperTypeId == planesType.Id)); Assert.That(partialColumns, Has.Count.EqualTo(2)); - partialColumns = db.SelectFmt(typeof(Shipper), "ShipperTypeId".SqlColumn() + " = {0}", planesType.Id); + partialColumns = db.Select(typeof(Shipper), "ShipperTypeId".SqlColumn(DialectProvider) + " = @Id".PreNormalizeSql(db), new { planesType.Id }); Assert.That(partialColumns, Has.Count.EqualTo(2)); //Select into another POCO class that matches sql - var rows = db.SqlList( - "SELECT {0}, COUNT(*) AS Total FROM Shippers GROUP BY {0} ORDER BY Total".Fmt("ShipperTypeId".SqlColumn())); + var rows = db.SqlList( + "SELECT {0}, COUNT(*) AS Total FROM Shippers GROUP BY {0} ORDER BY Total".Fmt("ShipperTypeId".SqlColumn(DialectProvider))); + + Assert.That(rows, Has.Count.EqualTo(2)); + Assert.That(rows[0].ShipperTypeId, Is.EqualTo(trainsType.Id)); + Assert.That(rows[0].Total, Is.EqualTo(1)); + Assert.That(rows[1].ShipperTypeId, Is.EqualTo(planesType.Id)); + Assert.That(rows[1].Total, Is.EqualTo(2)); - Assert.That(rows, Has.Count.EqualTo(2)); - Assert.That(rows[0].ShipperTypeId, Is.EqualTo(trainsType.Id)); - Assert.That(rows[0].Total, Is.EqualTo(1)); - Assert.That(rows[1].ShipperTypeId, Is.EqualTo(planesType.Id)); - Assert.That(rows[1].Total, Is.EqualTo(2)); + TestCustomGroupBy(db, trainsType, planesType); - //And finally lets quickly clean up the mess we've made: + //And finally lets quickly clean up the mess we've made: db.DeleteAll(); db.DeleteAll(); @@ -146,6 +149,32 @@ public void Shippers_UseCase() Assert.That(db.Select(), Has.Count.EqualTo(0)); } } + + private static void TestCustomGroupBy(IDbConnection db, ShipperType trainsType, ShipperType planesType) + { + var rows = db.SqlList( + db.From() + .GroupBy(x => x.ShipperTypeId) + .OrderBy("Total") + .Select(x => new {x.ShipperTypeId, Total = Sql.As(Sql.Count("*"), "Total")})); + + Assert.That(rows, Has.Count.EqualTo(2)); + Assert.That(rows[0].ShipperTypeId, Is.EqualTo(trainsType.Id)); + Assert.That(rows[0].Total, Is.EqualTo(1)); + Assert.That(rows[1].ShipperTypeId, Is.EqualTo(planesType.Id)); + Assert.That(rows[1].Total, Is.EqualTo(2)); + + var qGroup = db.From() + .GroupBy(x => x.ShipperTypeId) + .OrderBy("2") + .Select(x => new {x.ShipperTypeId, Total = Sql.Count("*")}); + + var rowsGroup = db.Dictionary(qGroup); + + Assert.That(rowsGroup, Has.Count.EqualTo(2)); + Assert.That(rowsGroup[trainsType.Id], Is.EqualTo(1)); + Assert.That(rowsGroup[planesType.Id], Is.EqualTo(2)); + } } diff --git a/tests/ServiceStack.OrmLite.Tests/SoftDeleteTests.cs b/tests/ServiceStack.OrmLite.Tests/SoftDeleteTests.cs new file mode 100644 index 000000000..35a3851ee --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/SoftDeleteTests.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Data; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.UseCase; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public class Vendor : ISoftDelete + { + public Guid Id { get; set; } + public string Name { get; set; } + public bool IsDeleted { get; set; } + + [Reference] + public List Products { get; set; } + } + + public class Product : ISoftDelete + { + public Guid Id { get; set; } + public string Name { get; set; } + public bool IsDeleted { get; set; } + + [ForeignKey(typeof(Vendor))] + public Guid VendorId { get; set; } + } + + [TestFixtureOrmLite] + public class SoftDeleteTests : OrmLiteProvidersTestBase + { + public SoftDeleteTests(DialectContext context) : base(context) {} + + private static void InitData(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + db.Save(new Vendor + { + Id = Guid.NewGuid(), + Name = "Active Vendor", + Products = new List + { + new Product {Id = Guid.NewGuid(), Name = "Active Product"}, + new Product {Id = Guid.NewGuid(), Name = "Retired Product", IsDeleted = true}, + } + }, references:true); + + db.Save(new Vendor + { + Id = Guid.NewGuid(), + Name = "Retired Vendor", + IsDeleted = true, + Products = new List + { + new Product {Id = Guid.NewGuid(), Name = "Active Product"}, + new Product {Id = Guid.NewGuid(), Name = "Retired Product", IsDeleted = true}, + } + }, references: true); + } + + [Test] + public void Can_filter_deleted_products_reference_data() + { + using (var db = OpenDbConnection()) + { + InitData(db); + + var vendors = db.LoadSelect(x => !x.IsDeleted); + + Assert.That(vendors.Count, Is.EqualTo(1)); + Assert.That(vendors[0].Name, Is.EqualTo("Active Vendor")); + Assert.That(vendors[0].Products.Count, Is.EqualTo(2)); + } + } + + [Test] + public void Can_get_active_products_using_merge() + { + using (var db = OpenDbConnection()) + { + InitData(db); + + var vendors = db.Select(x => !x.IsDeleted); + var products = db.Select(db.From().Join() + .Where(p => !p.IsDeleted) + .And(v => !v.IsDeleted)); + + var merged = vendors.Merge(products); + + Assert.That(merged.Count, Is.EqualTo(1)); + Assert.That(merged[0].Name, Is.EqualTo("Active Vendor")); + Assert.That(merged[0].Products.Count, Is.EqualTo(1)); + Assert.That(merged[0].Products[0].Name, Is.EqualTo("Active Product")); + } + } + + [Test] + public void Can_get_active_products_using_SoftDelete_SqlExpression() + { + OrmLiteConfig.SqlExpressionSelectFilter = q => + { + if (q.ModelDef.ModelType.HasInterface(typeof(ISoftDelete))) + { + q.Where(x => !x.IsDeleted); + } + }; + + using (var db = OpenDbConnection()) + { + InitData(db); + + var vendors = db.LoadSelect(); + + Assert.That(vendors.Count, Is.EqualTo(1)); + Assert.That(vendors[0].Name, Is.EqualTo("Active Vendor")); + } + + OrmLiteConfig.SqlExpressionSelectFilter = null; + } + + [Test] + public void Can_get_active_vendor_and_active_references_using_SoftDelete_ref_filter() + { + OrmLiteConfig.SqlExpressionSelectFilter = q => + { + if (q.ModelDef.ModelType.HasInterface(typeof(ISoftDelete))) + { + q.Where(x => !x.IsDeleted); + } + }; + + OrmLiteConfig.LoadReferenceSelectFilter = (type, sql) => + { + var meta = type.GetModelMetadata(); + if (type.HasInterface(typeof(ISoftDelete))) + { + var sqlFalse = DialectProvider.SqlBool(false); + sql += $" AND ({meta.ModelName.SqlTable(DialectProvider)}.{"IsDeleted".SqlColumn(DialectProvider)} = {sqlFalse})"; + } + + return sql; + }; + + using (var db = OpenDbConnection()) + { + InitData(db); + + var vendors = db.LoadSelect(); + + Assert.That(vendors.Count, Is.EqualTo(1)); + Assert.That(vendors[0].Name, Is.EqualTo("Active Vendor")); + Assert.That(vendors[0].Products.Count, Is.EqualTo(1)); + } + + OrmLiteConfig.SqlExpressionSelectFilter = null; + OrmLiteConfig.LoadReferenceSelectFilter = null; + } + + [Test] + public void Can_get_single_vendor_and__load_active_references_using_soft_delete_ref_filter() + { + OrmLiteConfig.LoadReferenceSelectFilter = (type, sql) => + { + var meta = type.GetModelMetadata(); + if (type.HasInterface(typeof(ISoftDelete))) + { + var sqlFalse = DialectProvider.SqlBool(false); + sql += $" AND ({meta.ModelName.SqlTable(DialectProvider)}.{"IsDeleted".SqlColumn(DialectProvider)} = {sqlFalse})"; + } + + return sql; + }; + + using (var db = OpenDbConnection()) + { + InitData(db); + + + var vendor = db.Single(v=>v.Name == "Active Vendor"); + db.LoadReferences(vendor); + + Assert.That(vendor.Name, Is.EqualTo("Active Vendor")); + Assert.That(vendor.Products.Count, Is.EqualTo(1)); + } + + OrmLiteConfig.LoadReferenceSelectFilter = null; + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/SqlBuilderTests.cs b/tests/ServiceStack.OrmLite.Tests/SqlBuilderTests.cs index 779fbca4c..f695fb52c 100644 --- a/tests/ServiceStack.OrmLite.Tests/SqlBuilderTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/SqlBuilderTests.cs @@ -7,11 +7,15 @@ namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class SqlBuilderTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class + + SqlBuilderTests : OrmLiteProvidersTestBase { - [Alias("Users")] - public class User + public SqlBuilderTests(DialectContext context) : base(context) {} + + [Alias("UsersSqlBuilder")] + public class UsersSqlBuilder { [AutoIncrement] public int Id { get; set; } @@ -19,60 +23,60 @@ public class User public int Age { get; set; } } - private IDbConnection db; - - [SetUp] - public void SetUp() - { - db = Config.OpenDbConnection(); - db.DropAndCreateTable(); - } - - [TearDown] - public void TearDown() - { - } - [Test] public void BuilderSelectClause() { - var rand = new Random(8675309); - var data = new List(); - for (var i = 0; i < 100; i++) + using (var db = OpenDbConnection()) { - var nU = new User { Age = rand.Next(70), Id = i, Name = Guid.NewGuid().ToString() }; - data.Add(nU); - nU.Id = (int) db.Insert(nU, selectIdentity: true); - } + db.DropAndCreateTable(); + var rand = new Random(8675309); + var data = new List(); + for (var i = 0; i < 100; i++) + { + var nU = new UsersSqlBuilder {Age = rand.Next(70), Id = i, Name = Guid.NewGuid().ToString()}; + data.Add(nU); + nU.Id = (int) db.Insert(nU, selectIdentity: true); + } - var builder = new SqlBuilder(); - var justId = builder.AddTemplate("SELECT /**select**/ FROM Users"); - var all = builder.AddTemplate("SELECT /**select**/, Name, Age FROM Users"); + var table = db.GetDialectProvider().GetTableName(nameof(UsersSqlBuilder)); + var builder = new SqlBuilder(); + var justId = builder.AddTemplate($"SELECT /**select**/ FROM {table}"); + var all = builder.AddTemplate($"SELECT /**select**/, Name, Age FROM {table}"); - builder.Select("Id"); + builder.Select("Id"); - var ids = db.Column(justId.RawSql, justId.Parameters); - var users = db.Select(all.RawSql, all.Parameters); + var ids = db.Column(justId.RawSql, justId.Parameters); + var users = db.Select(all.RawSql, all.Parameters); - foreach (var u in data) - { - Assert.That(ids.Any(i => u.Id == i), "Missing ids in select"); - Assert.That(users.Any(a => a.Id == u.Id && a.Name == u.Name && a.Age == u.Age), "Missing users in select"); + foreach (var u in data) + { + Assert.That(ids.Any(i => u.Id == i), "Missing ids in select"); + Assert.That(users.Any(a => a.Id == u.Id && a.Name == u.Name && a.Age == u.Age), + "Missing users in select"); + } } } [Test] public void BuilderTemplateWOComposition() { - var builder = new SqlBuilder(); - var template = builder.AddTemplate("SELECT COUNT(*) FROM Users WHERE Age = {0}age".Fmt(OrmLiteConfig.DialectProvider.ParamString), new { age = 5 }); + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var builder = new SqlBuilder(); + var table = db.GetDialectProvider().GetTableName(nameof(UsersSqlBuilder)); + var template = builder.AddTemplate( + $"SELECT COUNT(*) FROM {table} WHERE Age = {DialectProvider.ParamString}age", + new {age = 5}); - if (template.RawSql == null) throw new Exception("RawSql null"); - if (template.Parameters == null) throw new Exception("Parameters null"); + if (template.RawSql == null) throw new Exception("RawSql null"); + if (template.Parameters == null) throw new Exception("Parameters null"); - db.Insert(new User { Age = 5, Name = "Testy McTestington" }); + db.Insert(new UsersSqlBuilder {Age = 5, Name = "Testy McTestington"}); - Assert.That(db.Scalar(template.RawSql, template.Parameters), Is.EqualTo(1)); + Assert.That(db.Scalar(template.RawSql, template.Parameters), Is.EqualTo(1)); + } } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/SqlDialectTests.cs b/tests/ServiceStack.OrmLite.Tests/SqlDialectTests.cs new file mode 100644 index 000000000..8ee85e825 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/SqlDialectTests.cs @@ -0,0 +1,25 @@ +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class SqlDialectTests : OrmLiteProvidersTestBase + { + public SqlDialectTests(DialectContext context) : base(context) { } + + [Test] + public void Does_spread_values() + { + using var db = OpenDbConnection(); + var dialect = db.GetDialectProvider(); + Assert.That(dialect.SqlSpread((int[])null), Is.EqualTo("")); + Assert.That(dialect.SqlSpread((string[])null), Is.EqualTo("")); + Assert.That(dialect.SqlSpread(new int[0]), Is.EqualTo("")); + Assert.That(dialect.SqlSpread(new string[0]), Is.EqualTo("")); + Assert.That(dialect.SqlSpread(1, 2, 3), Is.EqualTo("1,2,3")); + Assert.That(dialect.SqlSpread("A", "B", "C"), Is.EqualTo("'A','B','C'")); + Assert.That(dialect.SqlSpread("A'B", "C\"D"), + Is.EqualTo("'A''B','C\"D'").Or.EqualTo("'A\\'B','C\"D'")); //MySql + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/SqlFormatTests.cs b/tests/ServiceStack.OrmLite.Tests/SqlFormatTests.cs index 8697ad5df..ac17ce52b 100644 --- a/tests/ServiceStack.OrmLite.Tests/SqlFormatTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/SqlFormatTests.cs @@ -2,13 +2,11 @@ using System.Collections.Generic; using NUnit.Framework; using ServiceStack.DataAnnotations; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { [TestFixture] - public class SqlFormatTests - : OrmLiteTestBase + public class SqlFormatTests { [Test] public void SqlJoin_joins_int_ids() @@ -28,7 +26,7 @@ public void SqlJoin_joins_string_ids() public void SqlFormat_can_handle_null_args() { const string sql = "SELECT Id FROM FOO WHERE Bar = {0}"; - var sqlFormat = sql.SqlFmt(1, null); + var sqlFormat = sql.SqlFmt(SqliteDialect.Provider, 1, null); Assert.That(sqlFormat, Is.EqualTo("SELECT Id FROM FOO WHERE Bar = 1")); } diff --git a/tests/ServiceStack.OrmLite.Tests/SqlServerDialectTests.cs b/tests/ServiceStack.OrmLite.Tests/SqlServerDialectTests.cs new file mode 100644 index 000000000..e7d3cbb30 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/SqlServerDialectTests.cs @@ -0,0 +1,180 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests +{ + public class Sqltest + { + [AutoIncrement] + public int Id { get; set; } + public double Value { get; set; } + public bool Bool { get; set; } + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class SqlServerDialectTests : OrmLiteProvidersTestBase + { + public SqlServerDialectTests(DialectContext context) : base(context) {} + + [Test] + public void Does_concat_values() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Sqltest { Value = 123.456 }); + + var sqlConcat = DialectProvider.SqlConcat(new object[]{ "'a'", 2, "'c'" }); + var result = db.Scalar($"SELECT {sqlConcat} from sqltest"); + Assert.That(result, Is.EqualTo("a2c")); + + sqlConcat = DialectProvider.SqlConcat(new object[] { "'$'", "value" }); + result = db.Scalar($"SELECT {sqlConcat} from sqltest"); + Assert.That(result, Is.EqualTo("$123.456")); + } + } + + [Test] + public void Does_concat_values_in_SqlExpression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Sqltest { Value = 123.456, Bool = true }); + + var results = db.Select>(db.From() + .Select(x => new { + x.Id, + text = Sql.As(Sql.Cast(x.Id, Sql.VARCHAR) + " : " + Sql.Cast(x.Value, Sql.VARCHAR) + " : " + Sql.Cast(x.Bool, Sql.VARCHAR) + " string", "text") + })); + + Assert.That(results[0]["text"], Is.EqualTo("1 : 123.456 : 1 string") + .Or.EqualTo("1 : 123.456 : true string")); + } + } + + [Test] + public void Does_concat_values_in_SqlExpression_using_tuple() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Sqltest { Value = 123.456 }); + + var results = db.Select<(int id, string text)>(db.From() + .Select(x => new { + x.Id, + text = Sql.Cast(x.Id, Sql.VARCHAR) + " : " + Sql.Cast(x.Value, Sql.VARCHAR) + " : " + Sql.Cast("1 + 2", Sql.VARCHAR) + " string" + })); + + Assert.That(results[0].text, Is.EqualTo("1 : 123.456 : 3 string")); + } + } + + [Test] + public void Does_format_currency() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Sqltest { Value = 12 }); + + var sqlCurrency = DialectProvider.SqlCurrency("12.3456"); + var result = db.Scalar($"SELECT {sqlCurrency} from sqltest"); + Assert.That(result, Is.EqualTo("$12.35")); + + sqlCurrency = DialectProvider.SqlCurrency("12.3456", "£"); + result = db.Scalar($"SELECT {sqlCurrency} from sqltest"); + Assert.That(result, Is.EqualTo("£12.35")); + + db.Insert(new Sqltest { Value = 12.3 }); + db.Insert(new Sqltest { Value = 12.34 }); + db.Insert(new Sqltest { Value = 12.345 }); + + var sqlConcat = DialectProvider.SqlCurrency("value"); + var results = db.SqlList($"SELECT {sqlConcat} from sqltest"); + + Assert.That(results, Is.EquivalentTo(new[] + { + "$12.00", + "$12.30", + "$12.34", + "$12.35", + })); + + sqlConcat = DialectProvider.SqlCurrency("value", "£"); + results = db.SqlList($"SELECT {sqlConcat} from sqltest"); + + Assert.That(results, Is.EquivalentTo(new[] + { + "£12.00", + "£12.30", + "£12.34", + "£12.35", + })); + } + } + + [Test] + public void Does_handle_booleans() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new Sqltest { Value = 0, Bool = false }); + db.Insert(new Sqltest { Value = 1, Bool = true }); + + var sqlBool = DialectProvider.SqlBool(false); + var result = db.Scalar($"SELECT Value from sqltest where Bool = {sqlBool}"); + Assert.That(result, Is.EqualTo(0)); + + sqlBool = DialectProvider.SqlBool(true); + result = db.Scalar($"SELECT Value from sqltest where Bool = {sqlBool}"); + Assert.That(result, Is.EqualTo(1)); + } + } + + [Test] + public void Can_use_limit() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + 5.Times(i => db.Insert(new Sqltest { Value = i + 1 })); + + var sqlLimit = DialectProvider.SqlLimit(rows: 1); + var results = db.SqlList($"SELECT Value from sqltest ORDER BY Id {sqlLimit}").Sum(); + Assert.That(results, Is.EqualTo(1)); + + sqlLimit = DialectProvider.SqlLimit(rows: 3); + results = db.SqlList($"SELECT Value from sqltest ORDER BY Id {sqlLimit}").Sum(); + Assert.That(results, Is.EqualTo(6)); + + sqlLimit = DialectProvider.SqlLimit(offset: 1); + results = db.SqlList($"SELECT Value from sqltest ORDER BY Id {sqlLimit}").Sum(); + Assert.That(results, Is.EqualTo(14)); + + sqlLimit = DialectProvider.SqlLimit(offset: 4); + results = db.SqlList($"SELECT Value from sqltest ORDER BY Id {sqlLimit}").Sum(); + Assert.That(results, Is.EqualTo(5)); + + sqlLimit = DialectProvider.SqlLimit(offset: 1, rows: 1); + results = db.SqlList($"SELECT Value from sqltest ORDER BY Id {sqlLimit}").Sum(); + Assert.That(results, Is.EqualTo(2)); + + sqlLimit = DialectProvider.SqlLimit(offset: 2, rows: 2); + results = db.SqlList($"SELECT Value from sqltest ORDER BY Id {sqlLimit}").Sum(); + Assert.That(results, Is.EqualTo(7)); + } + } + + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/SqlServerProviderTests.cs b/tests/ServiceStack.OrmLite.Tests/SqlServerProviderTests.cs index 7afad6d10..ed2cc27c4 100644 --- a/tests/ServiceStack.OrmLite.Tests/SqlServerProviderTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/SqlServerProviderTests.cs @@ -1,9 +1,7 @@ -using System; using System.Collections.Generic; using System.Data; using System.Linq; using NUnit.Framework; -using ServiceStack.Common; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests @@ -14,18 +12,20 @@ public class DummyTable public string Name { get; set; } } - [TestFixture] - public class SqlServerProviderTests + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class SqlServerProviderTests : OrmLiteProvidersTestBase { + public SqlServerProviderTests(DialectContext context) : base(context) {} + private IDbConnection db; - [TestFixtureSetUp] + [OneTimeSetUp] public void TestFixtureSetUp() { - db = Config.OpenDbConnection(); + db = OpenDbConnection(); } - [TestFixtureTearDown] + [OneTimeTearDown] public void TearDown() { db.Dispose(); diff --git a/tests/ServiceStack.OrmLite.Tests/SqliteOrmLiteConnectionTests.cs b/tests/ServiceStack.OrmLite.Tests/SqliteOrmLiteConnectionTests.cs index 2278dad68..70cb6f756 100644 --- a/tests/ServiceStack.OrmLite.Tests/SqliteOrmLiteConnectionTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/SqliteOrmLiteConnectionTests.cs @@ -1,21 +1,14 @@ using System; using System.Data; -using System.IO; using NUnit.Framework; using ServiceStack.Common.Tests.Models; namespace ServiceStack.OrmLite.Tests { - [TestFixture] - public class SqliteOrmLiteConnectionTests - : OrmLiteTestBase + [TestFixtureOrmLiteDialects(Dialect.Sqlite)] + public class SqliteOrmLiteConnectionTests : OrmLiteProvidersTestBase { - [SetUp] - public void SetUp() - { - OrmLiteConfig.DialectProvider = SqliteDialect.Provider; - ConnectionString = "test.sqlite"; - } + public SqliteOrmLiteConnectionTests(DialectContext context) : base(context) {} [Test] public void Can_create_connection() @@ -28,7 +21,8 @@ public void Can_create_connection() [Test, Ignore("Not supported in latest sqlite")] public void Can_create_ReadOnly_connection() { - using (var db = ConnectionString.OpenReadOnlyDbConnection()) + var connectionString = OpenDbConnection().ConnectionString; + using (var db = connectionString.OpenReadOnlyDbConnection()) { } } @@ -36,7 +30,8 @@ public void Can_create_ReadOnly_connection() [Test, Ignore("Not supported in latest sqlite")] public void Can_create_table_with_ReadOnly_connection() { - using (var db = ConnectionString.OpenReadOnlyDbConnection()) + var connectionString = OpenDbConnection().ConnectionString; + using (var db = connectionString.OpenReadOnlyDbConnection()) { try { @@ -45,7 +40,7 @@ public void Can_create_table_with_ReadOnly_connection() } catch (Exception ex) { - Log(ex.Message); + Console.Write(ex); return; } Assert.Fail("Should not be able to create a table with a readonly connection"); diff --git a/tests/ServiceStack.OrmLite.Tests/StringSerializerTests.cs b/tests/ServiceStack.OrmLite.Tests/StringSerializerTests.cs index 8579e1564..6ce789515 100644 --- a/tests/ServiceStack.OrmLite.Tests/StringSerializerTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/StringSerializerTests.cs @@ -14,31 +14,32 @@ public class ModelWithComplexType public class ComplexType { public int Id { get; set; } - public SubType SubType { get; set; } + public ComplexSubType SubType { get; set; } } - public class SubType + public class ComplexSubType { public string Name { get; set; } } - [TestFixture] - public class StringSerializerTests - : OrmLiteTestBase + [TestFixtureOrmLite] + public class StringSerializerTests : OrmLiteProvidersTestBase { + public StringSerializerTests(DialectContext context) : base(context) {} + private static void InsertModelWithComplexType(IDbConnection db) { db.DropAndCreateTable(); db.Insert(new ModelWithComplexType { Id = 1, - ComplexType = new ComplexType { Id = 2, SubType = new SubType { Name = "Sub" } } + ComplexType = new ComplexType { Id = 2, SubType = new ComplexSubType { Name = "Sub" } } }); } public string TestSql { - get { return "SELECT {0} from {1}".Fmt("ComplexType".SqlColumn(), "ModelWithComplexType".SqlTable()); } + get { return "SELECT {0} from {1}".Fmt("ComplexType".SqlColumn(DialectProvider), "ModelWithComplexType".SqlTable(DialectProvider)); } } [Test] @@ -64,8 +65,8 @@ public void Can_use_JSV_StringSerializer() { using (var db = OpenDbConnection()) { - var hold = db.GetDialectProvider().StringSerializer; - db.GetDialectProvider().StringSerializer = new JsvStringSerializer(); + var hold = DialectProvider.StringSerializer; + DialectProvider.StringSerializer = new JsvStringSerializer(); InsertModelWithComplexType(db); @@ -75,7 +76,7 @@ public void Can_use_JSV_StringSerializer() var data = db.SingleById(1); Assert.That(data.ComplexType.SubType.Name, Is.EqualTo("Sub")); - db.GetDialectProvider().StringSerializer = hold; + DialectProvider.StringSerializer = hold; } } @@ -84,8 +85,8 @@ public void Can_use_JSON_StringSerializer() { using (var db = OpenDbConnection()) { - var hold = db.GetDialectProvider().StringSerializer; - db.GetDialectProvider().StringSerializer = new JsonStringSerializer(); + var hold = DialectProvider.StringSerializer; + DialectProvider.StringSerializer = new JsonStringSerializer(); InsertModelWithComplexType(db); @@ -95,7 +96,7 @@ public void Can_use_JSON_StringSerializer() var data = db.SingleById(1); Assert.That(data.ComplexType.SubType.Name, Is.EqualTo("Sub")); - db.GetDialectProvider().StringSerializer = hold; + DialectProvider.StringSerializer = hold; } } @@ -104,8 +105,8 @@ public void Can_use_JSON_DataContract_StringSerializer() { using (var db = OpenDbConnection()) { - var hold = db.GetDialectProvider().StringSerializer; - db.GetDialectProvider().StringSerializer = new JsonDataContractSerializer(); + var hold = DialectProvider.StringSerializer; + DialectProvider.StringSerializer = new JsonDataContractSerializer(); InsertModelWithComplexType(db); @@ -115,7 +116,7 @@ public void Can_use_JSON_DataContract_StringSerializer() var data = db.SingleById(1); Assert.That(data.ComplexType.SubType.Name, Is.EqualTo("Sub")); - db.GetDialectProvider().StringSerializer = hold; + DialectProvider.StringSerializer = hold; } } @@ -124,18 +125,19 @@ public void Can_use_Xml_DataContract_StringSerializer() { using (var db = OpenDbConnection()) { - var hold = db.GetDialectProvider().StringSerializer; - db.GetDialectProvider().StringSerializer = new DataContractSerializer(); + var hold = DialectProvider.StringSerializer; + DialectProvider.StringSerializer = new DataContractSerializer(); InsertModelWithComplexType(db); var str = db.SqlScalar(TestSql); - Assert.That(str, Is.EqualTo("2Sub")); + Assert.That(str, Is.EqualTo("2Sub") //.NET + .Or.EqualTo("2Sub")); //.NET Core var data = db.SingleById(1); Assert.That(data.ComplexType.SubType.Name, Is.EqualTo("Sub")); - db.GetDialectProvider().StringSerializer = hold; + DialectProvider.StringSerializer = hold; } } @@ -144,18 +146,21 @@ public void Can_use_XmlSerializer_StringSerializer() { using (var db = OpenDbConnection()) { - var hold = db.GetDialectProvider().StringSerializer; - db.GetDialectProvider().StringSerializer = new XmlSerializableSerializer(); + var hold = DialectProvider.StringSerializer; + DialectProvider.StringSerializer = new XmlSerializableSerializer(); InsertModelWithComplexType(db); var str = db.SqlScalar(TestSql); - Assert.That(str, Is.EqualTo("2Sub")); + Assert.That(str, Contains.Substring("2Sub")); var data = db.SingleById(1); Assert.That(data.ComplexType.SubType.Name, Is.EqualTo("Sub")); - db.GetDialectProvider().StringSerializer = hold; + DialectProvider.StringSerializer = hold; } } } diff --git a/src/ServiceStack.OrmLite/JoinSqlBuilder.cs b/tests/ServiceStack.OrmLite.Tests/Support/JoinSqlBuilder.cs similarity index 84% rename from src/ServiceStack.OrmLite/JoinSqlBuilder.cs rename to tests/ServiceStack.OrmLite.Tests/Support/JoinSqlBuilder.cs index 2f9d43392..ca7e27d96 100644 --- a/src/ServiceStack.OrmLite/JoinSqlBuilder.cs +++ b/tests/ServiceStack.OrmLite.Tests/Support/JoinSqlBuilder.cs @@ -1,643 +1,646 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace ServiceStack.OrmLite -{ - public class JoinSqlBuilder : ISqlExpression - { - private List joinList = new List(); - private List> whereList = new List>(); - private List columnList = new List(); - private List> orderByList = new List>(); - private bool isDistinct = false; - private bool isAggregateUsed = false; - - private int? Rows { get; set; } - private int? Offset { get; set; } - - private string baseSchema = ""; - private string baseTableName = ""; - private Type basePocoType; - private IOrmLiteDialectProvider dialectProvider; - - public JoinSqlBuilder(IOrmLiteDialectProvider dialectProvider=null) - { - this.dialectProvider = dialectProvider ?? OrmLiteConfig.DialectProvider; - basePocoType = typeof(TBasePoco); - baseSchema = GetSchema(basePocoType); - baseTableName = basePocoType.GetModelDefinition().ModelName; - } - - private string Column(string tableName, Expression> func, bool withTablePrefix) - { - var lst = ColumnList(tableName, func, withTablePrefix); - if (lst == null || lst.Count != 1) - throw new Exception("Expression should have only one column"); - return lst[0]; - } - - private List ColumnList(string tableName, Expression> func, bool withTablePrefix = true) - { - List result = new List(); - if (func == null || func.Body == null) - return result; - PropertyList(tableName, func.Body, result, withTablePrefix); - return result; - } - - private List ColumnList(bool withTablePrefix = true) - { - var pocoType = typeof(T); - var tableName = pocoType.GetModelDefinition().ModelName; - List result = new List(pocoType.GetModelDefinition().FieldDefinitions.Count); - foreach (var item in pocoType.GetModelDefinition().FieldDefinitions) - { - if (withTablePrefix) - result.Add(string.Format("{0}.{1}", dialectProvider.GetQuotedTableName(tableName), dialectProvider.GetQuotedColumnName(item.FieldName))); - else - result.Add(string.Format("{0}", dialectProvider.GetQuotedColumnName(item.FieldName))); - } - return result; - } - - private void ProcessUnary(string tableName, UnaryExpression u, List lst, bool withTablePrefix) - { - if (u.NodeType == ExpressionType.Convert) - { - if (u.Method != null) - { - throw new Exception("Invalid Expression provided"); - } - PropertyList(tableName, u.Operand, lst, withTablePrefix); - return; - } - throw new Exception("Invalid Expression provided"); - } - - protected void ProcessMemberAccess(string tableName, MemberExpression m, List lst, bool withTablePrefix, string alias = "") - { - if (m.Expression != null - && (m.Expression.NodeType == ExpressionType.Parameter || m.Expression.NodeType == ExpressionType.Convert)) - { - var pocoType = typeof(T); - var fieldName = pocoType.GetModelDefinition().FieldDefinitions.First(f => f.Name == m.Member.Name).FieldName; - - alias = string.IsNullOrEmpty(alias) ? string.Empty : string.Format(" AS {0}", dialectProvider.GetQuotedColumnName(alias)); - - if (withTablePrefix) - lst.Add(string.Format("{0}.{1}{2}", dialectProvider.GetQuotedTableName(tableName), dialectProvider.GetQuotedColumnName(fieldName), alias)); - else - lst.Add(string.Format("{0}{1}", dialectProvider.GetQuotedColumnName(fieldName), alias)); - return; - } - throw new Exception("Only Members are allowed"); - } - - private void ProcessNew(string tableName, NewExpression nex, List lst, bool withTablePrefix) - { - if (nex.Arguments == null || nex.Arguments.Count == 0) - throw new Exception("Only column list allowed"); - - var expressionProperties = nex.Type.GetProperties(); - for (int i = 0; i < nex.Arguments.Count; i++) - { - var arg = nex.Arguments[i]; - var alias = expressionProperties[i].Name; - - PropertyList(tableName, arg, lst, withTablePrefix, alias); - } - return; - } - - private void PropertyList(string tableName, Expression exp, List lst, bool withTablePrefix, string alias = "") - { - if (exp == null) - return; - - switch (exp.NodeType) - { - case ExpressionType.MemberAccess: - ProcessMemberAccess(tableName, exp as MemberExpression, lst, withTablePrefix, alias); - return; - - case ExpressionType.Convert: - var ue = exp as UnaryExpression; - ProcessUnary(tableName, ue, lst, withTablePrefix); - return; - - case ExpressionType.New: - ProcessNew(tableName, exp as NewExpression, lst, withTablePrefix); - return; - } - throw new Exception("Only columns are allowed"); - } - - public JoinSqlBuilder Select(Expression> selectColumns) - { - Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); - if (associatedType == null) - { - throw new Exception("Either the source or destination table should be associated "); - } - - this.columnList.AddRange(ColumnList(associatedType.GetModelDefinition().ModelName, selectColumns)); - return this; - } - - public JoinSqlBuilder SelectAll() - { - Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); - if (associatedType == null) - { - throw new Exception("Either the source or destination table should be associated "); - } - this.columnList.AddRange(ColumnList()); - return this; - } - - public JoinSqlBuilder SelectDistinct() - { - isDistinct = true; - return this; - } - - public JoinSqlBuilder SelectMax(Expression> selectColumn) - { - return SelectGenericAggregate(selectColumn, "MAX"); - } - - public JoinSqlBuilder SelectMin(Expression> selectColumn) - { - return SelectGenericAggregate(selectColumn, "MIN"); - } - - public JoinSqlBuilder SelectCount(Expression> selectColumn) - { - return SelectGenericAggregate(selectColumn, "COUNT"); - } - - public JoinSqlBuilder SelectAverage(Expression> selectColumn) - { - return SelectGenericAggregate(selectColumn, "AVG"); - } - - public JoinSqlBuilder SelectSum(Expression> selectColumn) - { - return SelectGenericAggregate(selectColumn, "SUM"); - } - - private JoinSqlBuilder SelectGenericAggregate(Expression> selectColumn, string functionName) - { - Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); - if (associatedType == null) - { - throw new Exception("Either the source or destination table should be associated "); - } - isAggregateUsed = true; - - CheckAggregateUsage(true); - - var columns = ColumnList(associatedType.GetModelDefinition().ModelName, selectColumn); - if ((columns.Count == 0) || (columns.Count > 1)) - { - throw new Exception("Expression should select only one Column "); - } - this.columnList.Add(string.Format(" {0}({1}) ", functionName.ToUpper(), columns[0])); - return this; - } - - public JoinSqlBuilder SelectMin() - { - isDistinct = true; - return this; - } - - public JoinSqlBuilder Where(Expression> where) - { - return WhereInternal(WhereType.AND, where); - } - - public JoinSqlBuilder Or(Expression> where) - { - return WhereInternal(WhereType.OR, where); - } - - public JoinSqlBuilder And(Expression> where) - { - return WhereInternal(WhereType.AND, where); - } - - private JoinSqlBuilder WhereInternal(WhereType whereType, Expression> where) - { - Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); - if (associatedType == null) - { - throw new Exception("Either the source or destination table should be associated "); - } - var ev = dialectProvider.SqlExpression(); - ev.WhereStatementWithoutWhereString = true; - ev.PrefixFieldWithTableName = true; - ev.Where(where); - var str = ev.WhereExpression; - if (String.IsNullOrEmpty(str) == false) - { - this.whereList.Add(new KeyValuePair(str, whereType)); - } - return this; - } - - private JoinSqlBuilder OrderByInternal(bool byDesc, Expression> orderByColumns) - { - Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); - if (associatedType == null) - { - throw new Exception("Either the source or destination table should be associated "); - } - - var lst = ColumnList(associatedType.GetModelDefinition().ModelName, orderByColumns); - foreach (var item in lst) - orderByList.Add(new KeyValuePair(item, !byDesc)); - return this; - } - - public JoinSqlBuilder Clear() - { - joinList.Clear(); - whereList.Clear(); - columnList.Clear(); - orderByList.Clear(); - return this; - } - - - public JoinSqlBuilder OrderBy(Expression> sourceColumn) - { - return OrderByInternal(false, sourceColumn); - } - - public JoinSqlBuilder OrderByDescending(Expression> sourceColumn) - { - return OrderByInternal(true, sourceColumn); - } - - public JoinSqlBuilder Join(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) - { - return JoinInternal(JoinType.INNER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); - } - - public JoinSqlBuilder LeftJoin(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) - { - return JoinInternal(JoinType.LEFTOUTER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); - } - - public JoinSqlBuilder RightJoin(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) - { - return JoinInternal(JoinType.RIGHTOUTER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); - } - - public JoinSqlBuilder FullJoin(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) - { - return JoinInternal(JoinType.FULLOUTER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); - } - - //Not ready yet - //public JoinSqlBuilder SelfJoin(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) - //{ - // return JoinInternal(JoinType.SELF, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); - //} - - public JoinSqlBuilder CrossJoin(Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) - { - return JoinInternal(JoinType.CROSS, joinList, null, null, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); - } - - private JoinSqlBuilder JoinInternal(JoinType joinType, List joinObjList, Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection, Expression> destinationTableColumnSelection, Expression> sourceWhere = null, Expression> destinationWhere = null) where TJoin : Join, new() - { - Type associatedType = this.PreviousAssociatedType(typeof(TSourceTable), typeof(TDestinationTable)); - if (associatedType == null) - { - throw new Exception("Either the source or destination table should be associated "); - } - - TJoin join = new TJoin(); - join.JoinType = joinType; - join.Class1Type = typeof(TSourceTable); - join.Class2Type = typeof(TDestinationTable); - - if (associatedType == join.Class1Type) - join.RefType = join.Class2Type; - else - join.RefType = join.Class1Type; - - join.Class1Schema = GetSchema(join.Class1Type); - join.Class1TableName = join.Class1Type.GetModelDefinition().ModelName; - join.Class2Schema = GetSchema(join.Class2Type); - join.Class2TableName = join.Class2Type.GetModelDefinition().ModelName; - join.RefTypeSchema = GetSchema(join.RefType); - join.RefTypeTableName = join.RefType.GetModelDefinition().ModelName; - - if (join.JoinType != JoinType.CROSS) - { - if (join.JoinType == JoinType.SELF) - { - join.Class1ColumnName = Column(join.Class1TableName, sourceColumn, false); - join.Class2ColumnName = Column(join.Class2TableName, destinationColumn, false); - } - else - { - join.Class1ColumnName = Column(join.Class1TableName, sourceColumn, true); - join.Class2ColumnName = Column(join.Class2TableName, destinationColumn, true); - } - } - - if (sourceTableColumnSelection != null) - { - columnList.AddRange(ColumnList(join.Class1TableName, sourceTableColumnSelection)); - } - - if (destinationTableColumnSelection != null) - { - columnList.AddRange(ColumnList(join.Class2TableName, destinationTableColumnSelection)); - } - - if (sourceWhere != null) - { - var ev = dialectProvider.SqlExpression(); - ev.WhereStatementWithoutWhereString = true; - ev.PrefixFieldWithTableName = true; - ev.Where(sourceWhere); - var where = ev.WhereExpression; - if (!String.IsNullOrEmpty(where)) - whereList.Add(new KeyValuePair(where, WhereType.AND)); - } - - if (destinationWhere != null) - { - var ev = dialectProvider.SqlExpression(); - ev.WhereStatementWithoutWhereString = true; - ev.PrefixFieldWithTableName = true; - ev.Where(destinationWhere); - var where = ev.WhereExpression; - if (!String.IsNullOrEmpty(where)) - whereList.Add(new KeyValuePair(where, WhereType.AND)); - } - - joinObjList.Add(join); - return this; - } - - private string GetSchema(Type type) - { - return string.IsNullOrEmpty(type.GetModelDefinition().Schema) ? string.Empty : string.Format("\"{0}\".", type.GetModelDefinition().Schema); - } - - private Type PreviousAssociatedType(Type sourceTableType, Type destinationTableType) - { - if (sourceTableType == basePocoType || destinationTableType == basePocoType) - { - return basePocoType; - } - - foreach (var j in joinList) - { - if (j.Class1Type == sourceTableType || j.Class2Type == sourceTableType) - { - return sourceTableType; - } - if (j.Class1Type == destinationTableType || j.Class2Type == destinationTableType) - { - return destinationTableType; - } - } - return null; - } - - private void CheckAggregateUsage(bool ignoreCurrentItem) - { - if ((columnList.Count > (ignoreCurrentItem ? 0 : 1)) && isAggregateUsed) - { - throw new Exception("Aggregate function cannot be used with non aggregate select columns"); - } - } - - /// - /// Offset of the first row to return. The offset of the initial row is 0 - /// - public virtual JoinSqlBuilder Skip(int? skip = null) - { - Offset = skip; - return this; - } - - /// - /// Number of rows returned by a SELECT statement - /// - public virtual JoinSqlBuilder Take(int? take = null) - { - Rows = take; - return this; - } - - /// - /// Set the specified offset and rows for SQL Limit clause. - /// - /// - /// Offset of the first row to return. The offset of the initial row is 0 - /// - /// - /// Number of rows returned by a SELECT statement - /// - public virtual JoinSqlBuilder Limit(int skip, int rows) - { - Offset = skip; - Rows = rows; - return this; - } - - /// - /// Set the specified offset and rows for SQL Limit clause where they exist. - /// - /// - /// Offset of the first row to return. The offset of the initial row is 0 - /// - /// - /// Number of rows returned by a SELECT statement - /// - public virtual JoinSqlBuilder Limit(int? skip, int? rows) - { - Offset = skip; - Rows = rows; - return this; - } - - /// - /// Set the specified rows for Sql Limit clause. - /// - /// - /// Number of rows returned by a SELECT statement - /// - public virtual JoinSqlBuilder Limit(int rows) - { - Offset = null; - Rows = rows; - return this; - } - - /// - /// Clear Sql Limit clause - /// - public virtual JoinSqlBuilder Limit() - { - Offset = null; - Rows = null; - return this; - } - - public string SelectInto() - { - var modelDef = typeof(T).GetModelDefinition(); - - CheckAggregateUsage(false); - - var sbSelect = new StringBuilder(); - sbSelect.Append("SELECT "); - - var dbColumns = new StringBuilder(); - - if (columnList.Count > 0) - { - if (isDistinct) - sbSelect.Append(" DISTINCT "); - - foreach (var col in columnList) - { - dbColumns.AppendFormat("{0}{1}", dbColumns.Length > 0 ? "," : "", col); - } - } - else - { - // improve performance avoiding multiple calls to GetModelDefinition() - if (isDistinct && modelDef.FieldDefinitions.Count > 0) - sbSelect.Append(" DISTINCT "); - - foreach (var fi in modelDef.FieldDefinitions) - { - dbColumns.AppendFormat("{0}{1}", dbColumns.Length > 0 ? "," : "", (String.IsNullOrEmpty(fi.BelongToModelName) ? (dialectProvider.GetQuotedTableName(modelDef.ModelName)) : (dialectProvider.GetQuotedTableName(fi.BelongToModelName))) + "." + dialectProvider.GetQuotedColumnName(fi.FieldName)); - } - if (dbColumns.Length == 0) - dbColumns.AppendFormat("\"{0}{1}\".*", baseSchema, dialectProvider.GetQuotedTableName(baseTableName)); - } - - sbSelect.Append(dbColumns + " \n"); - - var sbBody = new StringBuilder(); - sbBody.AppendFormat("FROM {0}{1} \n", baseSchema, dialectProvider.GetQuotedTableName(baseTableName)); - int i = 0; - foreach (var join in joinList) - { - i++; - if ((join.JoinType == JoinType.INNER) || (join.JoinType == JoinType.SELF)) - sbBody.Append(" INNER JOIN "); - else if (join.JoinType == JoinType.LEFTOUTER) - sbBody.Append(" LEFT OUTER JOIN "); - else if (join.JoinType == JoinType.RIGHTOUTER) - sbBody.Append(" RIGHT OUTER JOIN "); - else if (join.JoinType == JoinType.FULLOUTER) - sbBody.Append(" FULL OUTER JOIN "); - else if (join.JoinType == JoinType.CROSS) - { - sbBody.Append(" CROSS JOIN "); - } - - if (join.JoinType == JoinType.CROSS) - { - sbBody.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, dialectProvider.GetQuotedTableName(join.RefTypeTableName)); - } - else - { - if (join.JoinType != JoinType.SELF) - { - sbBody.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, dialectProvider.GetQuotedTableName(join.RefTypeTableName), join.Class1ColumnName, join.Class2ColumnName); - } - else - { - sbBody.AppendFormat(" {0}{1} AS {2} ON {2}.{3} = \"{1}\".{4} \n", join.RefTypeSchema, dialectProvider.GetQuotedTableName(join.RefTypeTableName), dialectProvider.GetQuotedTableName(join.RefTypeTableName) + "_" + i.ToString(), join.Class1ColumnName, join.Class2ColumnName); - } - } - } - - if (whereList.Count > 0) - { - var sbWhere = new StringBuilder(); - foreach (var where in whereList) - { - sbWhere.AppendFormat("{0}{1}", sbWhere.Length > 0 - ? (where.Value == WhereType.OR ? " OR " : " AND ") : "", where.Key); - } - sbBody.Append("WHERE " + sbWhere + " \n"); - } - - var sbOrderBy = new StringBuilder(); - if (orderByList.Count > 0) - { - foreach (var ob in orderByList) - { - sbOrderBy.AppendFormat("{0}{1} {2} ", sbOrderBy.Length > 0 ? "," : "", ob.Key, ob.Value ? "ASC" : "DESC"); - } - sbOrderBy.Insert(0, "ORDER BY "); - sbOrderBy.Append(" \n"); - } - - var sql = dialectProvider.ToSelectStatement( - modelDef, sbSelect.ToString(), sbBody.ToString(), sbOrderBy.ToString(), Offset, Rows); - - return sql; - } - - public string ToSql() - { - return SelectInto(); - } - - public string ToSelectStatement() - { - return SelectInto(); - } - } - - enum WhereType - { - AND, - OR - } - - - enum JoinType - { - INNER, - LEFTOUTER, - RIGHTOUTER, - FULLOUTER, - CROSS, - SELF - } - - class Join - { - public Type Class1Type { get; set; } - public Type Class2Type { get; set; } - public Type RefType { get; set; } - public JoinType JoinType { get; set; } - public string Class1Schema { get; set; } - public string Class2Schema { get; set; } - public string Class1TableName { get; set; } - public string Class2TableName { get; set; } - public string RefTypeSchema { get; set; } - public string RefTypeTableName { get; set; } - public string Class1ColumnName { get; set; } - public string Class2ColumnName { get; set; } - } -} +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite +{ + [Obsolete("Use SqlExpression")] + public class JoinSqlBuilder : ISqlExpression + { + private List joinList = new List(); + private List> whereList = new List>(); + private List columnList = new List(); + private List> orderByList = new List>(); + private bool isDistinct = false; + private bool isAggregateUsed = false; + + private int? Rows { get; set; } + private int? Offset { get; set; } + + private string baseSchema = ""; + private string baseTableName = ""; + private Type basePocoType; + private IOrmLiteDialectProvider dialectProvider; + + public JoinSqlBuilder(IOrmLiteDialectProvider dialectProvider=null) + { + this.dialectProvider = dialectProvider.ThrowIfNull(nameof(dialectProvider)); + basePocoType = typeof(TBasePoco); + baseSchema = GetSchema(basePocoType); + baseTableName = basePocoType.GetModelMetadata().ModelName; + } + + private string Column(string tableName, Expression> func, bool withTablePrefix) + { + var lst = ColumnList(tableName, func, withTablePrefix); + if (lst == null || lst.Count != 1) + throw new Exception("Expression should have only one column"); + return lst[0]; + } + + private List ColumnList(string tableName, Expression> func, bool withTablePrefix = true) + { + var result = new List(); + if (func == null) + return result; + PropertyList(tableName, func.Body, result, withTablePrefix); + return result; + } + + private List ColumnList(bool withTablePrefix = true) + { + var pocoType = typeof(T); + var tableName = pocoType.GetModelMetadata().ModelName; + List result = new List(pocoType.GetModelMetadata().FieldDefinitions.Count); + foreach (var item in pocoType.GetModelMetadata().FieldDefinitions) + { + if (withTablePrefix) + result.Add($"{dialectProvider.GetQuotedTableName(tableName)}.{dialectProvider.GetQuotedColumnName(item.FieldName)}"); + else + result.Add($"{dialectProvider.GetQuotedColumnName(item.FieldName)}"); + } + return result; + } + + private void ProcessUnary(string tableName, UnaryExpression u, List lst, bool withTablePrefix) + { + if (u.NodeType == ExpressionType.Convert) + { + if (u.Method != null) + { + throw new Exception("Invalid Expression provided"); + } + PropertyList(tableName, u.Operand, lst, withTablePrefix); + return; + } + throw new Exception("Invalid Expression provided"); + } + + protected void ProcessMemberAccess(string tableName, MemberExpression m, List lst, bool withTablePrefix, string alias = "") + { + if (m.Expression != null + && (m.Expression.NodeType == ExpressionType.Parameter || m.Expression.NodeType == ExpressionType.Convert)) + { + var pocoType = typeof(T); + var fieldName = pocoType.GetModelMetadata().FieldDefinitions.First(f => f.Name == m.Member.Name).FieldName; + + alias = string.IsNullOrEmpty(alias) ? string.Empty : string.Format(" AS {0}", dialectProvider.GetQuotedColumnName(alias)); + + if (withTablePrefix) + lst.Add($"{dialectProvider.GetQuotedTableName(tableName)}.{dialectProvider.GetQuotedColumnName(fieldName)}{alias}"); + else + lst.Add($"{dialectProvider.GetQuotedColumnName(fieldName)}{alias}"); + return; + } + throw new Exception("Only Members are allowed"); + } + + private void ProcessNew(string tableName, NewExpression nex, List lst, bool withTablePrefix) + { + if (nex.Arguments == null || nex.Arguments.Count == 0) + throw new Exception("Only column list allowed"); + + var expressionProperties = nex.Type.AllProperties(); + for (int i = 0; i < nex.Arguments.Count; i++) + { + var arg = nex.Arguments[i]; + var alias = expressionProperties[i].Name; + + PropertyList(tableName, arg, lst, withTablePrefix, alias); + } + return; + } + + private void PropertyList(string tableName, Expression exp, List lst, bool withTablePrefix, string alias = "") + { + if (exp == null) + return; + + switch (exp.NodeType) + { + case ExpressionType.MemberAccess: + ProcessMemberAccess(tableName, exp as MemberExpression, lst, withTablePrefix, alias); + return; + + case ExpressionType.Convert: + var ue = exp as UnaryExpression; + ProcessUnary(tableName, ue, lst, withTablePrefix); + return; + + case ExpressionType.New: + ProcessNew(tableName, exp as NewExpression, lst, withTablePrefix); + return; + } + throw new Exception("Only columns are allowed"); + } + + public JoinSqlBuilder Select(Expression> selectColumns) + { + Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); + if (associatedType == null) + { + throw new Exception("Either the source or destination table should be associated "); + } + + this.columnList.AddRange(ColumnList(associatedType.GetModelMetadata().ModelName, selectColumns)); + return this; + } + + public JoinSqlBuilder SelectAll() + { + Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); + if (associatedType == null) + { + throw new Exception("Either the source or destination table should be associated "); + } + this.columnList.AddRange(ColumnList()); + return this; + } + + public JoinSqlBuilder SelectDistinct() + { + isDistinct = true; + return this; + } + + public JoinSqlBuilder SelectMax(Expression> selectColumn) + { + return SelectGenericAggregate(selectColumn, "MAX"); + } + + public JoinSqlBuilder SelectMin(Expression> selectColumn) + { + return SelectGenericAggregate(selectColumn, "MIN"); + } + + public JoinSqlBuilder SelectCount(Expression> selectColumn) + { + return SelectGenericAggregate(selectColumn, "COUNT"); + } + + public JoinSqlBuilder SelectAverage(Expression> selectColumn) + { + return SelectGenericAggregate(selectColumn, "AVG"); + } + + public JoinSqlBuilder SelectSum(Expression> selectColumn) + { + return SelectGenericAggregate(selectColumn, "SUM"); + } + + private JoinSqlBuilder SelectGenericAggregate(Expression> selectColumn, string functionName) + { + Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); + if (associatedType == null) + { + throw new Exception("Either the source or destination table should be associated "); + } + isAggregateUsed = true; + + CheckAggregateUsage(true); + + var columns = ColumnList(associatedType.GetModelMetadata().ModelName, selectColumn); + if ((columns.Count == 0) || (columns.Count > 1)) + { + throw new Exception("Expression should select only one Column "); + } + this.columnList.Add($" {functionName.ToUpper()}({columns[0]}) "); + return this; + } + + public JoinSqlBuilder SelectMin() + { + isDistinct = true; + return this; + } + + public JoinSqlBuilder Where(Expression> where) + { + return WhereInternal(WhereType.AND, where); + } + + public JoinSqlBuilder Or(Expression> where) + { + return WhereInternal(WhereType.OR, where); + } + + public JoinSqlBuilder And(Expression> where) + { + return WhereInternal(WhereType.AND, where); + } + + private JoinSqlBuilder WhereInternal(WhereType whereType, Expression> where) + { + Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); + if (associatedType == null) + { + throw new Exception("Either the source or destination table should be associated "); + } + var ev = dialectProvider.SqlExpression(); + ev.WhereStatementWithoutWhereString = true; + ev.PrefixFieldWithTableName = true; + ev.Where(where); + var str = ev.WhereExpression; + if (String.IsNullOrEmpty(str) == false) + { + this.whereList.Add(new KeyValuePair(str, whereType)); + } + return this; + } + + private JoinSqlBuilder OrderByInternal(bool byDesc, Expression> orderByColumns) + { + Type associatedType = this.PreviousAssociatedType(typeof(T), typeof(T)); + if (associatedType == null) + { + throw new Exception("Either the source or destination table should be associated "); + } + + var lst = ColumnList(associatedType.GetModelMetadata().ModelName, orderByColumns); + foreach (var item in lst) + orderByList.Add(new KeyValuePair(item, !byDesc)); + return this; + } + + public JoinSqlBuilder Clear() + { + joinList.Clear(); + whereList.Clear(); + columnList.Clear(); + orderByList.Clear(); + return this; + } + + public JoinSqlBuilder OrderBy(Expression> sourceColumn) + { + return OrderByInternal(false, sourceColumn); + } + + public JoinSqlBuilder OrderByDescending(Expression> sourceColumn) + { + return OrderByInternal(true, sourceColumn); + } + + public JoinSqlBuilder Join(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) + { + return JoinInternal(JoinType.INNER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); + } + + public JoinSqlBuilder LeftJoin(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) + { + return JoinInternal(JoinType.LEFTOUTER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); + } + + public JoinSqlBuilder RightJoin(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) + { + return JoinInternal(JoinType.RIGHTOUTER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); + } + + public JoinSqlBuilder FullJoin(Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) + { + return JoinInternal(JoinType.FULLOUTER, joinList, sourceColumn, destinationColumn, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); + } + + public JoinSqlBuilder CrossJoin(Expression> sourceTableColumnSelection = null, Expression> destinationTableColumnSelection = null, Expression> sourceWhere = null, Expression> destinationWhere = null) + { + return JoinInternal(JoinType.CROSS, joinList, null, null, sourceTableColumnSelection, destinationTableColumnSelection, sourceWhere, destinationWhere); + } + + private JoinSqlBuilder JoinInternal(JoinType joinType, List joinObjList, Expression> sourceColumn, Expression> destinationColumn, Expression> sourceTableColumnSelection, Expression> destinationTableColumnSelection, Expression> sourceWhere = null, Expression> destinationWhere = null) where TJoin : Join, new() + { + Type associatedType = this.PreviousAssociatedType(typeof(TSourceTable), typeof(TDestinationTable)); + if (associatedType == null) + { + throw new Exception("Either the source or destination table should be associated "); + } + + TJoin join = new TJoin(); + join.JoinType = joinType; + join.Class1Type = typeof(TSourceTable); + join.Class2Type = typeof(TDestinationTable); + + if (associatedType == join.Class1Type) + join.RefType = join.Class2Type; + else + join.RefType = join.Class1Type; + + join.Class1Schema = GetSchema(join.Class1Type); + join.Class1TableName = join.Class1Type.GetModelMetadata().ModelName; + join.Class2Schema = GetSchema(join.Class2Type); + join.Class2TableName = join.Class2Type.GetModelMetadata().ModelName; + join.RefTypeSchema = GetSchema(join.RefType); + join.RefTypeTableName = join.RefType.GetModelMetadata().ModelName; + + if (join.JoinType != JoinType.CROSS) + { + if (join.JoinType == JoinType.SELF) + { + join.Class1ColumnName = Column(join.Class1TableName, sourceColumn, false); + join.Class2ColumnName = Column(join.Class2TableName, destinationColumn, false); + } + else + { + join.Class1ColumnName = Column(join.Class1TableName, sourceColumn, true); + join.Class2ColumnName = Column(join.Class2TableName, destinationColumn, true); + } + } + + if (sourceTableColumnSelection != null) + { + columnList.AddRange(ColumnList(join.Class1TableName, sourceTableColumnSelection)); + } + + if (destinationTableColumnSelection != null) + { + columnList.AddRange(ColumnList(join.Class2TableName, destinationTableColumnSelection)); + } + + if (sourceWhere != null) + { + var ev = dialectProvider.SqlExpression(); + ev.WhereStatementWithoutWhereString = true; + ev.PrefixFieldWithTableName = true; + ev.Where(sourceWhere); + var where = ev.WhereExpression; + if (!String.IsNullOrEmpty(where)) + whereList.Add(new KeyValuePair(where, WhereType.AND)); + } + + if (destinationWhere != null) + { + var ev = dialectProvider.SqlExpression(); + ev.WhereStatementWithoutWhereString = true; + ev.PrefixFieldWithTableName = true; + ev.Where(destinationWhere); + var where = ev.WhereExpression; + if (!String.IsNullOrEmpty(where)) + whereList.Add(new KeyValuePair(where, WhereType.AND)); + } + + joinObjList.Add(join); + return this; + } + + private string GetSchema(Type type) + { + return string.IsNullOrEmpty(type.GetModelMetadata().Schema) ? string.Empty : string.Format("\"{0}\".", type.GetModelMetadata().Schema); + } + + private Type PreviousAssociatedType(Type sourceTableType, Type destinationTableType) + { + if (sourceTableType == basePocoType || destinationTableType == basePocoType) + { + return basePocoType; + } + + foreach (var j in joinList) + { + if (j.Class1Type == sourceTableType || j.Class2Type == sourceTableType) + { + return sourceTableType; + } + if (j.Class1Type == destinationTableType || j.Class2Type == destinationTableType) + { + return destinationTableType; + } + } + return null; + } + + private void CheckAggregateUsage(bool ignoreCurrentItem) + { + if ((columnList.Count > (ignoreCurrentItem ? 0 : 1)) && isAggregateUsed) + { + throw new Exception("Aggregate function cannot be used with non aggregate select columns"); + } + } + + /// + /// Offset of the first row to return. The offset of the initial row is 0 + /// + public virtual JoinSqlBuilder Skip(int? skip = null) + { + Offset = skip; + return this; + } + + /// + /// Number of rows returned by a SELECT statement + /// + public virtual JoinSqlBuilder Take(int? take = null) + { + Rows = take; + return this; + } + + /// + /// Set the specified offset and rows for SQL Limit clause. + /// + /// + /// Offset of the first row to return. The offset of the initial row is 0 + /// + /// + /// Number of rows returned by a SELECT statement + /// + public virtual JoinSqlBuilder Limit(int skip, int rows) + { + Offset = skip; + Rows = rows; + return this; + } + + /// + /// Set the specified offset and rows for SQL Limit clause where they exist. + /// + /// + /// Offset of the first row to return. The offset of the initial row is 0 + /// + /// + /// Number of rows returned by a SELECT statement + /// + public virtual JoinSqlBuilder Limit(int? skip, int? rows) + { + Offset = skip; + Rows = rows; + return this; + } + + /// + /// Set the specified rows for Sql Limit clause. + /// + /// + /// Number of rows returned by a SELECT statement + /// + public virtual JoinSqlBuilder Limit(int rows) + { + Offset = null; + Rows = rows; + return this; + } + + /// + /// Clear Sql Limit clause + /// + public virtual JoinSqlBuilder Limit() + { + Offset = null; + Rows = null; + return this; + } + + public string SelectInto() => SelectInto(QueryType.Select); + public string SelectInto(QueryType queryType) + { + var modelDef = typeof(T).GetModelMetadata(); + + CheckAggregateUsage(false); + + var sbSelect = StringBuilderCache.Allocate(); + sbSelect.Append("SELECT "); + + var dbColumns = StringBuilderCache.Allocate(); + + if (columnList.Count > 0) + { + if (isDistinct) + sbSelect.Append(" DISTINCT "); + + foreach (var col in columnList) + { + dbColumns.AppendFormat("{0}{1}", dbColumns.Length > 0 ? "," : "", col); + } + } + else + { + // improve performance avoiding multiple calls to GetModelDefinition() + if (isDistinct && modelDef.FieldDefinitions.Count > 0) + sbSelect.Append(" DISTINCT "); + + foreach (var fieldDef in modelDef.FieldDefinitions) + { + dbColumns.AppendFormat("{0}{1}", dbColumns.Length > 0 ? "," : "", + (string.IsNullOrEmpty(fieldDef.BelongToModelName) + ? dialectProvider.GetQuotedTableName(modelDef.ModelName) + : dialectProvider.GetQuotedTableName(fieldDef.BelongToModelName)) + + "." + dialectProvider.GetQuotedColumnName(fieldDef.FieldName)); + } + if (dbColumns.Length == 0) + dbColumns.AppendFormat("\"{0}{1}\".*", baseSchema, dialectProvider.GetQuotedTableName(baseTableName)); + } + + sbSelect.Append(StringBuilderCache.ReturnAndFree(dbColumns) + " \n"); + + var sbBody = StringBuilderCacheAlt.Allocate(); + sbBody.AppendFormat("FROM {0}{1} \n", baseSchema, dialectProvider.GetQuotedTableName(baseTableName)); + int i = 0; + foreach (var join in joinList) + { + i++; + if (join.JoinType == JoinType.INNER || join.JoinType == JoinType.SELF) + sbBody.Append(" INNER JOIN "); + else if (join.JoinType == JoinType.LEFTOUTER) + sbBody.Append(" LEFT OUTER JOIN "); + else if (join.JoinType == JoinType.RIGHTOUTER) + sbBody.Append(" RIGHT OUTER JOIN "); + else if (join.JoinType == JoinType.FULLOUTER) + sbBody.Append(" FULL OUTER JOIN "); + else if (join.JoinType == JoinType.CROSS) + { + sbBody.Append(" CROSS JOIN "); + } + + if (join.JoinType == JoinType.CROSS) + { + sbBody.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, dialectProvider.GetQuotedTableName(join.RefTypeTableName)); + } + else + { + if (join.JoinType != JoinType.SELF) + { + sbBody.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, dialectProvider.GetQuotedTableName(join.RefTypeTableName), join.Class1ColumnName, join.Class2ColumnName); + } + else + { + sbBody.AppendFormat(" {0}{1} AS {2} ON {2}.{3} = \"{1}\".{4} \n", join.RefTypeSchema, dialectProvider.GetQuotedTableName(join.RefTypeTableName), dialectProvider.GetQuotedTableName(join.RefTypeTableName) + "_" + i.ToString(), join.Class1ColumnName, join.Class2ColumnName); + } + } + } + + if (whereList.Count > 0) + { + var sbWhere = new StringBuilder(); + foreach (var where in whereList) + { + sbWhere.AppendFormat("{0}{1}", sbWhere.Length > 0 + ? (where.Value == WhereType.OR ? " OR " : " AND ") : "", where.Key); + } + sbBody.Append("WHERE " + sbWhere + " \n"); + } + + var sbOrderBy = new StringBuilder(); + if (orderByList.Count > 0) + { + foreach (var ob in orderByList) + { + sbOrderBy.AppendFormat("{0}{1} {2} ", sbOrderBy.Length > 0 ? "," : "", ob.Key, ob.Value ? "ASC" : "DESC"); + } + sbOrderBy.Insert(0, "ORDER BY "); + sbOrderBy.Append(" \n"); + } + + var sql = dialectProvider.ToSelectStatement(QueryType.Select, modelDef, StringBuilderCache.ReturnAndFree(sbSelect), StringBuilderCacheAlt.ReturnAndFree(sbBody), sbOrderBy.ToString(), offset: Offset, rows: Rows); + + return sql; + } + + public string ToSql() + { + return SelectInto(QueryType.Select); + } + + public List Params { get; private set; } + + public string ToSelectStatement() => ToSelectStatement(QueryType.Select); + public string ToSelectStatement(QueryType forType) + { + return SelectInto(forType); + } + } + + enum WhereType + { + AND, + OR + } + + + enum JoinType + { + INNER, + LEFTOUTER, + RIGHTOUTER, + FULLOUTER, + CROSS, + SELF + } + + class Join + { + public Type Class1Type { get; set; } + public Type Class2Type { get; set; } + public Type RefType { get; set; } + public JoinType JoinType { get; set; } + public string Class1Schema { get; set; } + public string Class2Schema { get; set; } + public string Class1TableName { get; set; } + public string Class2TableName { get; set; } + public string RefTypeSchema { get; set; } + public string RefTypeTableName { get; set; } + public string Class1ColumnName { get; set; } + public string Class2ColumnName { get; set; } + } +} diff --git a/tests/ServiceStack.OrmLite.Tests/TemporaryNamingStrategy.cs b/tests/ServiceStack.OrmLite.Tests/TemporaryNamingStrategy.cs new file mode 100644 index 000000000..ec1c8f51e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/TemporaryNamingStrategy.cs @@ -0,0 +1,39 @@ +using System; +using System.Diagnostics; + +namespace ServiceStack.OrmLite.Tests +{ + public class TemporaryNamingStrategy : IDisposable + { + private readonly IOrmLiteDialectProvider _dialectProvider; + private readonly INamingStrategy _previous; + private bool _disposed; + + public TemporaryNamingStrategy(IOrmLiteDialectProvider dialectProvider, INamingStrategy temporary) + { + _dialectProvider = dialectProvider; + _previous = _dialectProvider.NamingStrategy; + _dialectProvider.NamingStrategy = temporary; + } + +#if DEBUG + ~TemporaryNamingStrategy() + { + Debug.Assert(_disposed, "TemporaryNamingStrategy was not disposed of - previous naming strategy was not restored"); + } +#endif + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + _dialectProvider.NamingStrategy = _previous; + +#if DEBUG + GC.SuppressFinalize(this); +#endif + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/TestHelpers.cs b/tests/ServiceStack.OrmLite.Tests/TestHelpers.cs index 3c0028353..d93421288 100644 --- a/tests/ServiceStack.OrmLite.Tests/TestHelpers.cs +++ b/tests/ServiceStack.OrmLite.Tests/TestHelpers.cs @@ -1,16 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Data; + namespace ServiceStack.OrmLite.Tests { - public enum Dialect - { - Sqlite, - SqlServer, - PostgreSql, - MySql, - SqlServerMdf, - Oracle, - VistaDb, - } - public static class TestHelpers { public static string NormalizeSql(this string sql) @@ -23,5 +16,31 @@ public static string NormalizeSql(this string sql) .Replace("\n", " ") .TrimEnd(); } + + public static string NormalizeQuotes(this string sql) + { + return sql.ToLower() + .Replace("\"", "'") + .Replace("`", "'") + .Replace("[", "'") + .Replace("]", "'") + .TrimEnd(); + } + + public static string PreNormalizeSql(this string sql, IDbConnection db) + { + var paramString = db.GetDialectProvider().ParamString; + if (paramString.Equals("@")) + return sql; + return sql.Replace("@", paramString); + } + + public static List AdjustIds(this IEnumerable ids, int initialId) + { + var result = new List(); + foreach (var id in ids) + result.Add(id + initialId); + return result; + } } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs new file mode 100644 index 000000000..b686cc8c4 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/ToInsertAndUpdateStatementTests.cs @@ -0,0 +1,100 @@ +using NUnit.Framework; +using ServiceStack.OrmLite.Tests.Shared; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + [TestFixtureOrmLite] + public class ToInsertAndUpdateStatementTests : OrmLiteProvidersTestBase + { + public ToInsertAndUpdateStatementTests(DialectContext context) : base(context) {} + + [Test] + public void Can_use_ToUpdateStatement_to_generate_inline_SQL() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + db.InsertAll(Person.Rockstars); + + var row = db.SingleById(1); + row.Age = 42; + + var sql = db.ToUpdateStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var updatedRow = db.SingleById(1); + Assert.That(updatedRow.Equals(row)); + } + } + + [Test] + public void Can_use_ToInsertStatement_to_generate_inline_SQL() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var row = Person.Rockstars[0]; + + var sql = db.ToInsertStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var insertedRow = db.SingleById(row.Id); + Assert.That(insertedRow.Equals(row)); + } + } + + [Test] + public void Correct_DbNull_in_ToInsertStatement() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var row = PersonWithReferenceType.TestValues[0]; + + var sql = db.ToInsertStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var insertedRow = db.SingleById(row.Id); + Assert.That(insertedRow.Equals(row)); + } + } + + [Test] + public void Correct_Ref_in_ToInsertStatement() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var row = PersonWithReferenceType.TestValues[1]; + + var sql = db.ToInsertStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var insertedRow = db.SingleById(row.Id); + Assert.That(insertedRow.Equals(row)); + } + } + + [Test] + public void Correct_nullable_in_ToInsertStatement() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + var row = TestProduct.TestValues[0]; + + var sql = db.ToInsertStatement(row); + sql.Print(); + db.ExecuteSql(sql); + + var insertedRow = db.SingleById(row.Id); + Assert.AreEqual(insertedRow, row); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/TypeDescriptorMetadataTests.cs b/tests/ServiceStack.OrmLite.Tests/TypeDescriptorMetadataTests.cs index d58dad93b..6dab1b6d9 100644 --- a/tests/ServiceStack.OrmLite.Tests/TypeDescriptorMetadataTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/TypeDescriptorMetadataTests.cs @@ -1,12 +1,9 @@ -// Copyright (c) Service Stack LLC. All Rights Reserved. +// Copyright (c) ServiceStack, Inc. All Rights Reserved. // License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt using System; -using System.Data; -using NUnit.Framework; using ServiceStack.DataAnnotations; -using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests { @@ -18,79 +15,6 @@ public class PersonDescriptor public int Age { get; set; } } - [TestFixture] - public class TypeDescriptorMetadataTests - : OrmLiteTestBase - { - private IDbConnection db; - - [TestFixtureSetUp] - public new void TestFixtureSetUp() - { - db = OpenDbConnection(); - } - - [TestFixtureTearDown] - public void TestFixtureTearDown() - { - db.Dispose(); - } - - - [Test] - public void Can_add_AutoIncrement_Id_at_runtime() - { - var model = new PersonDescriptor { FirstName = "Jimi", LastName = "Hendrix", Age = 27 }; - - typeof(PersonDescriptor).GetProperty("Id") - .AddAttributes(new AutoIncrementAttribute()); - - db.DropAndCreateTable(); - - var oldRows = db.Select(); - - db.Insert(model); - db.Insert(model); - model.Id = 0; // Oracle provider currently updates the id field so force it back to get an insert operation - db.Save(model); - - var allRows = db.Select(); - Assert.That(allRows.Count - oldRows.Count, Is.EqualTo(3)); - } - - [Test] - public void Can_change_column_definition() - { - SuppressIfOracle("Test assert fails with Oracle because Oracle does not allow 64000 character fields and uses VARCHAR2 not VARCHAR"); - if (Dialect == Dialect.PostgreSql) return; //Uses 'text' for strings by default - - typeof(DynamicCacheEntry) - .GetProperty("Data") - .AddAttributes(new StringLengthAttribute(7000)); - - db.DropAndCreateTable(); - - Assert.That(db.GetLastSql().NormalizeSql(), - Is.StringContaining("Data VARCHAR(7000)".NormalizeSql())); - db.GetLastSql().Print(); - } - - [Test] - public void Can_Create_Table_with_MaxText_column() - { - try - { - db.DropAndCreateTable(); - - } - catch (Exception) - { - db.DropAndCreateTable(); - } - db.GetLastSql().Print(); - } - } - public class DynamicCacheEntry { public string Id { get; set; } diff --git a/tests/ServiceStack.OrmLite.Tests/TypeWithByteArrayFieldTests.cs b/tests/ServiceStack.OrmLite.Tests/TypeWithByteArrayFieldTests.cs index 1c2daef10..650fc5d3e 100644 --- a/tests/ServiceStack.OrmLite.Tests/TypeWithByteArrayFieldTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/TypeWithByteArrayFieldTests.cs @@ -5,8 +5,11 @@ namespace ServiceStack.OrmLite.Tests { - public class TypeWithByteArrayFieldTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class TypeWithByteArrayFieldTests : OrmLiteProvidersTestBase { + public TypeWithByteArrayFieldTests(DialectContext context) : base(context) {} + [Test] public void CanInsertAndSelectByteArray() { @@ -55,7 +58,8 @@ public void Can_add_attachment() [Test, Explicit] public void Can_upload_attachment_via_sp() { - SuppressIfOracle("Oracle does not like this procedure definition"); + if (Dialect != Dialect.SqlServer) + return; using (var db = OpenDbConnection()) { @@ -65,7 +69,7 @@ public void Can_upload_attachment_via_sp() { db.ExecuteSql("DROP PROCEDURE dbo.[SP_upload_file]"); } - catch (System.Exception ex) {} + catch (System.Exception) {} db.ExecuteSql(@" CREATE PROCEDURE dbo.[SP_upload_file]( @@ -76,7 +80,7 @@ @filecontent varbinary(MAX)) begin INSERT INTO [Attachment]([FileName], [Type], [Data], [Description]) VALUES ({0}filename, {0}filetype, {0}filecontent, {0}filename) -end".Fmt(OrmLiteConfig.DialectProvider.ParamString)); +end".Fmt(DialectProvider.ParamString)); var bytes = "https://www.google.com/images/srpr/logo11w.png".GetBytesFromUrl(); db.ExecuteNonQuery("EXEC SP_upload_file @filename, @filetype, @filecontent", @@ -95,7 +99,8 @@ INSERT INTO [Attachment]([FileName], [Type], [Data], [Description]) [Test, Explicit] public void Can_upload_attachment_via_sp_with_ADONET() { - SuppressIfOracle("Oracle does not like this procedure definition"); + if (Dialect != Dialect.SqlServer) + return; using (var db = OpenDbConnection()) { @@ -105,7 +110,7 @@ public void Can_upload_attachment_via_sp_with_ADONET() { db.ExecuteSql("DROP PROCEDURE dbo.[SP_upload_file]"); } - catch (System.Exception ex) { } + catch (System.Exception) { } db.ExecuteSql(@" CREATE PROCEDURE dbo.[SP_upload_file]( @@ -116,7 +121,7 @@ @filecontent varbinary(MAX)) begin INSERT INTO [Attachment]([FileName], [Type], [Data], [Description]) VALUES ({0}filename, {0}filetype, {0}filecontent, {0}filename) -end".Fmt(OrmLiteConfig.DialectProvider.ParamString)); +end".Fmt(DialectProvider.ParamString)); var bytes = "https://www.google.com/images/srpr/logo11w.png".GetBytesFromUrl(); using (var dbCmd = db.CreateCommand()) diff --git a/tests/ServiceStack.OrmLite.Tests/UniqueConstraintTests.cs b/tests/ServiceStack.OrmLite.Tests/UniqueConstraintTests.cs new file mode 100644 index 000000000..7afa95d97 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UniqueConstraintTests.cs @@ -0,0 +1,211 @@ +using System; +using System.Text; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Model; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + public class UniqueTest + { + [AutoIncrement] + public int Id { get; set; } + + [Unique] + public string Field { get; set; } + } + + [UniqueConstraint(nameof(Field2), nameof(Field3))] + public class UniqueTest2 + { + [AutoIncrement] + public int Id { get; set; } + + public string Field2 { get; set; } + public string Field3 { get; set; } + } + + [UniqueConstraint(nameof(Field4), nameof(Field5), nameof(Field6), Name = "UC_CUSTOM")] + public class UniqueTest3 + { + [AutoIncrement] + public int Id { get; set; } + + public string Field4 { get; set; } + public string Field5 { get; set; } + public string Field6 { get; set; } + } + + [TestFixtureOrmLite] + public class UniqueConstraintTests : OrmLiteProvidersTestBase + { + public UniqueConstraintTests(DialectContext context) : base(context) {} + + [Test] + public void Does_add_individual_Constraints() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new UniqueTest { Field = "A" }); + db.Insert(new UniqueTest { Field = "B" }); + + try + { + db.Insert(new UniqueTest { Field = "B" }); + Assert.Fail("Should throw"); + } + catch (Exception ex) + { + ex.Message.Print(); + Assert.That(ex.Message.ToLower().Contains("unique") || ex.Message.ToLower().Contains("duplicate")); + } + } + } + + [Test] + public void Does_add_multiple_column_unique_constraint() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new UniqueTest2 { Field2 = "A", Field3 = "A" }); + db.Insert(new UniqueTest2 { Field2 = "A", Field3 = "B" }); + + try + { + db.Insert(new UniqueTest2 { Field2 = "A", Field3 = "B" }); + Assert.Fail("Should throw"); + } + catch (Exception ex) + { + ex.Message.Print(); + Assert.That(ex.Message.ToLower().Contains("unique") || ex.Message.ToLower().Contains("duplicate")); + } + } + } + + [Test] + public void Does_add_multiple_column_unique_constraint_with_custom_name() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var createSql = DialectProvider.ToCreateTableStatement(typeof(UniqueTest3)); + Assert.That(createSql.ToUpper(), Does.Contain("CONSTRAINT UC_CUSTOM UNIQUE")); + + db.Insert(new UniqueTest3 { Field4 = "A", Field5 = "A", Field6 = "A" }); + db.Insert(new UniqueTest3 { Field4 = "A", Field5 = "A", Field6 = "B" }); + + try + { + db.Insert(new UniqueTest3 { Field4 = "A", Field5 = "A", Field6 = "B" }); + Assert.Fail("Should throw"); + } + catch (Exception ex) + { + ex.Message.Print(); + Assert.That(ex.Message.ToLower().Contains("unique") || ex.Message.ToLower().Contains("duplicate")); + } + } + } + + [UniqueConstraint(nameof(Environment), nameof(Name))] + public class User + { + [AutoId] + public Guid Id { get; set; } + public Guid Environment { get; set; } + public string Name { get; set; } + } + + [Test] + public void Can_create_User_table_with_Unique_constraints() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.CreateTableIfNotExists(); + } + } + } + + + public class UniqueTest4 : IHasId + { + [AutoIncrement, Index(NonClustered = true)] + public int Id { get; set; } + + [Index(Unique = true)] + [Required] + [StringLength(100)] + public string UniqueDefault { get; set; } + + [Index(Unique = true, Clustered = true)] + [Required] + [StringLength(200)] + public string UniqueClustered { get; set; } + + [Index(Unique = true, NonClustered = true)] + [Required] + [StringLength(300)] + public string UniqueNonClustered { get; set; } + } + + public class SqlServer2012UniqueTests : OrmLiteTestBase + { + public SqlServer2012UniqueTests() : base(Dialect.SqlServer2012) { } + + [Test] + public void Does_create_unique_non_null_constraint() + { + var sb = new StringBuilder(); + OrmLiteConfig.BeforeExecFilter = cmd => sb.AppendLine(cmd.GetDebugString()); + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + } + +// sb.ToString().Print(); + var sql = sb.ToString(); + Assert.That(sql, Does.Contain("PRIMARY KEY NONCLUSTERED")); + Assert.That(sql, Does.Contain("VARCHAR(100) NOT NULL,")); + Assert.That(sql, Does.Contain("VARCHAR(200) NOT NULL,")); + Assert.That(sql, Does.Contain("VARCHAR(300) NOT NULL")); + Assert.That(sql, Does.Contain("CREATE UNIQUE INDEX ")); + Assert.That(sql, Does.Contain("CREATE UNIQUE CLUSTERED INDEX ")); + Assert.That(sql, Does.Contain("CREATE UNIQUE NONCLUSTERED INDEX ")); + } + } + + public class SqlServer2014UniqueTests : OrmLiteTestBase + { + public SqlServer2014UniqueTests() : base(Dialect.SqlServer2014) { } + + [Test] + public void Does_create_unique_non_null_constraint() + { + var sb = new StringBuilder(); + OrmLiteConfig.BeforeExecFilter = cmd => sb.AppendLine(cmd.GetDebugString()); + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + } + +// sb.ToString().Print(); + var sql = sb.ToString(); + Assert.That(sql, Does.Contain("PRIMARY KEY NONCLUSTERED")); + Assert.That(sql, Does.Contain("VARCHAR(100) NOT NULL,")); + Assert.That(sql, Does.Contain("VARCHAR(200) NOT NULL,")); + Assert.That(sql, Does.Contain("VARCHAR(300) NOT NULL")); + Assert.That(sql, Does.Contain("CREATE UNIQUE INDEX ")); + Assert.That(sql, Does.Contain("CREATE UNIQUE CLUSTERED INDEX ")); + Assert.That(sql, Does.Contain("CREATE UNIQUE NONCLUSTERED INDEX ")); + } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UntypedApiTests.cs b/tests/ServiceStack.OrmLite.Tests/UntypedApiTests.cs index a010b2984..7c7b5b4ff 100644 --- a/tests/ServiceStack.OrmLite.Tests/UntypedApiTests.cs +++ b/tests/ServiceStack.OrmLite.Tests/UntypedApiTests.cs @@ -1,4 +1,7 @@ -using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; using ServiceStack.Text; namespace ServiceStack.OrmLite.Tests @@ -13,9 +16,11 @@ public class Target : BaseClass public string Name { get; set; } } - [TestFixture] - public class UntypedApiTests : OrmLiteTestBase + [TestFixtureOrmLite] + public class UntypedApiTests : OrmLiteProvidersTestBase { + public UntypedApiTests(DialectContext context) : base(context) {} + [Test] public void Can_create_table_and_insert_with_untyped_Api() { @@ -57,5 +62,80 @@ public void Can_create_table_and_insert_with_untyped_Api() Assert.That(typedRow.Name, Is.EqualTo("Foo")); } } + + public class UserEntity + { + public long Id { get; set; } + + [DataAnnotations.Ignore] + public AnimalEntity MyPrimaryAnimal + { + get => AnimalEntity.FromObjectDictionary(AnimalRef); + set => AnimalRef = value.ToObjectDictionary(); + } + + public Dictionary AnimalRef { get; set; } + } + + public class AnimalEntity + { + public string Type => GetType().Name; + + public static AnimalEntity FromObjectDictionary(Dictionary props) + { + if (props == null) return null; + var type = props[nameof(Type)]; + switch (type) + { + case nameof(DogEntity): + return props.FromObjectDictionary(); + case nameof(CatEntity): + return props.FromObjectDictionary(); + case nameof(BirdEntity): + return props.FromObjectDictionary(); + default: + throw new NotSupportedException($"Unknown Animal '{type}'"); + } + } + } + + public class CatEntity : AnimalEntity + { + public int Id { get; set; } + public string Cat { get; set; } + } + + public class DogEntity : AnimalEntity + { + public int Id { get; set; } + public string Dog { get; set; } + } + + public class BirdEntity : AnimalEntity + { + public int Id { get; set; } + public string Bird { get; set; } + } + + [Test] + public void Can_store_different_entities_in_single_field() + { + using (var db = OpenDbConnection()) + { + OrmLiteUtils.PrintSql(); + db.DropAndCreateTable(); + + db.Insert(new UserEntity {Id = 1, MyPrimaryAnimal = new BirdEntity {Id = 1, Bird = "B"}}); + db.Insert(new UserEntity {Id = 2, MyPrimaryAnimal = new CatEntity {Id = 1, Cat = "C"}}); + db.Insert(new UserEntity {Id = 3, MyPrimaryAnimal = new DogEntity {Id = 1, Dog = "D"}}); + + var results = db.Select(); + var animals = results.OrderBy(x => x.Id).Map(x => x.MyPrimaryAnimal); + Assert.That(animals[0] is BirdEntity b && b.Bird == "B"); + Assert.That(animals[1] is CatEntity c && c.Cat == "C"); + Assert.That(animals[2] is DogEntity d && d.Dog == "D"); + } + } + } } \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/AliasedFieldUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/AliasedFieldUseCase.cs index 6f09c231b..793203b12 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/AliasedFieldUseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/AliasedFieldUseCase.cs @@ -1,14 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Data; +using System.Collections.Generic; using NUnit.Framework; using ServiceStack.DataAnnotations; namespace ServiceStack.OrmLite.Tests.UseCase { - [TestFixture] - public class AliasedFieldUseCase : OrmLiteTestBase + [TestFixtureOrmLite] + public class AliasedFieldUseCase : OrmLiteProvidersTestBase { + public AliasedFieldUseCase(DialectContext context) : base(context) {} + public class Foo { [Alias("SOME_COLUMN_NAME")] @@ -36,7 +36,7 @@ public class User [Test] public void CanResolveAliasedFieldNameInAnonymousType() { - using (IDbConnection db = OpenDbConnection()) + using (var db = OpenDbConnection()) { db.CreateTable(true); @@ -59,7 +59,7 @@ public void CanResolveAliasedFieldNameInAnonymousType() [Test] public void CanResolveAliasedFieldNameInJoinedTable() { - using (IDbConnection db = OpenDbConnection()) + using (var db = OpenDbConnection()) { db.DropAndCreateTable(); db.DropAndCreateTable(); diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/ArtistTrackSqlExpressions.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/ArtistTrackSqlExpressions.cs new file mode 100644 index 000000000..68189f33e --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/ArtistTrackSqlExpressions.cs @@ -0,0 +1,143 @@ +using System.Data; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using System.Collections.Generic; + +namespace ServiceStack.OrmLite.Tests.UseCase +{ + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer)] + public class ArtistTrackSqlExpressions : OrmLiteProvidersTestBase + { + public ArtistTrackSqlExpressions(DialectContext context) : base(context) {} + + [Test] + public void Can_OrderBy_Column_Index() + { + var hold = OrmLiteConfig.StripUpperInLike; + OrmLiteConfig.StripUpperInLike = false; + using (var db = CreateArtistAndTrackTablesWithData(OpenDbConnection())) + { + var q = db.From() + .Where(x => x.Year > 1991) + .And(x => x.Name.Contains("A")) + .GroupBy(x => x.Year) + .OrderByDescending(2) + .ThenBy(x => x.Year) + .Take(1) + .Select(x => new { x.Year, Count = Sql.Count("*") }); + + var result = db.Dictionary(q); + Assert.That(result[1993], Is.EqualTo(2)); + } + OrmLiteConfig.StripUpperInLike = hold; + } + + [Test] + public void Can_Order_by_Property_Alias() + { + var hold = OrmLiteConfig.StripUpperInLike; + OrmLiteConfig.StripUpperInLike = false; + using (var db = CreateArtistAndTrackTablesWithData(OpenDbConnection())) + { + var q = db.From() + .Where(x => x.Year > 1991) + .And(x => x.Name.Contains("A")) + .GroupBy(x => x.Year) + .OrderByDescending("Count") + .ThenBy(x => x.Year) + .Take(1) + .Select(x => new { x.Year, Count = Sql.Count("*") }); + + var result = db.Dictionary(q); + Assert.That(result[1993], Is.EqualTo(2)); + } + OrmLiteConfig.StripUpperInLike = hold; + } + + [Test] + public void Can_Select_joined_table_with_Alias() + { + using (var db = CreateArtistAndTrackTablesWithData(OpenDbConnection())) + { + var tracksByYear = db.Dictionary(db.From() + .Join() + .GroupBy(x => x.Name) + .Select(x => new { x.Name, Count = Sql.Count("*") })); + + Assert.That(tracksByYear.Count, Is.EqualTo(4)); + Assert.That(tracksByYear.Map(x => x.Value).Sum(), Is.EqualTo(8)); + } + } + + [Test] + public void Can_Count_Distinct() + { + using (var db = CreateArtistAndTrackTablesWithData(OpenDbConnection())) + { + var differentArtistsCount = db.Scalar(db.From() + .Select(x => Sql.CountDistinct(x.ArtistId))); + + Assert.That(differentArtistsCount, Is.EqualTo(4)); + } + } + + static readonly Artist[] Artists = new [] { + new Artist { + Id = 1, Name = "Faith No More", + Tracks = new List { + new Track { Name = "Everythings Ruined", Album = "Angel Dust", Year = 1992 }, + new Track { Name = "Ashes to Ashes", Album = "Album of the Year", Year = 1997 }, + } + }, + new Artist { + Id = 2, Name = "Live", + Tracks = new List { + new Track { Name = "Lightning Crashes", Album = "Throwing Copper", Year = 1994 }, + new Track { Name = "Lakini's Juice", Album = "Secret Samadhi", Year = 1997 }, + } + }, + new Artist { + Id = 3, Name = "Nirvana", + Tracks = new List { + new Track { Name = "Smells Like Teen Spirit", Album = "Nevermind", Year = 1991 }, + new Track { Name = "Heart-Shaped Box", Album = "In Utero", Year = 1993 }, + } + }, + new Artist { + Id = 4, Name = "Pearl Jam", + Tracks = new List { + new Track { Name = "Alive", Album = "Ten", Year = 1991 }, + new Track { Name = "Daughter", Album = "Vs", Year = 1993 }, + } + }, + }; + + public IDbConnection CreateArtistAndTrackTablesWithData(IDbConnection db) + { + db.DropAndCreateTable(); + db.DropAndCreateTable(); + Artists.Each(x => db.Save(x, references: true)); + return db; + } + } + + public class Artist + { + public int Id { get; set; } + public string Name { get; set; } + + [Reference] + public List Tracks { get; set; } + } + + public class Track + { + [AutoIncrement] + public int Id { get; set; } + public string Name { get; set; } + public int ArtistId { get; set; } + public string Album { get; set; } + public int Year { get; set; } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCase.cs index f81746ce4..f06dcc54d 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCase.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using ServiceStack.DataAnnotations; -using ServiceStack.Logging; namespace ServiceStack.OrmLite.Tests.UseCase { @@ -116,28 +115,17 @@ public class Product public decimal UnitPrice { get; set; } } - [TestFixture] - public class CustomerOrdersUseCase : OrmLiteTestBase + [TestFixtureOrmLite] + public class CustomerOrdersUseCase : OrmLiteProvidersTestBase { + public CustomerOrdersUseCase(DialectContext context) : base(context) {} + //Stand-alone class, No other configs, nothing but POCOs. [Test] public void Run() { - LogManager.LogFactory = new ConsoleLogFactory(); - - //var dbFactory = new OrmLiteConnectionFactory( - // @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\App_Data\Database1.mdf;Integrated Security=True;User Instance=True", - // SqlServerDialect.Provider); - - //Use in-memory Sqlite DB instead - //var dbFactory = new OrmLiteConnectionFactory( - // ":memory:", false, SqliteDialect.Provider); - - //If you are trying to get this to build as a standalone example, use one of the dbFactory methods - // above, instead of Config.OpenDbConnection in the using statement below. - //Non-intrusive: All extension methods hang off System.Data.* interfaces - using (IDbConnection db = Config.OpenDbConnection()) + using (var db = OpenDbConnection()) { //Re-Create all table schemas: RecreateTables(db); @@ -170,7 +158,7 @@ public void Run() Assert.That(customer.Id, Is.EqualTo(customerId)); //Direct access to System.Data.Transactions: - using (IDbTransaction trans = db.OpenTransaction(IsolationLevel.ReadCommitted)) + using (var trans = db.OpenTransaction(IsolationLevel.ReadCommitted)) { var order = new Order { CustomerId = customer.Id, diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCaseAsync.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCaseAsync.cs new file mode 100644 index 000000000..0e22f7e0a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/CustomerOrdersUseCaseAsync.cs @@ -0,0 +1,114 @@ +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using NUnit.Framework; + +namespace ServiceStack.OrmLite.Tests.UseCase +{ + /// + /// Stand-alone class, No other configs, nothing but POCOs. + /// + [TestFixtureOrmLite] + public class CustomerOrdersUseCaseAsync : OrmLiteProvidersTestBase + { + public CustomerOrdersUseCaseAsync(DialectContext context) : base(context) {} + + [Test] + public async Task Can_run_Customer_Orders_UseCase() + { + using (IDbConnection db = OpenDbConnection()) + { + //Re-Create all table schemas: + RecreateTables(db); + + await db.InsertAsync(new Employee { Id = 1, Name = "Employee 1" }); + await db.InsertAsync(new Employee { Id = 2, Name = "Employee 2" }); + var product1 = new Product { Id = 1, Name = "Product 1", UnitPrice = 10 }; + var product2 = new Product { Id = 2, Name = "Product 2", UnitPrice = 20 }; + await db.SaveAsync(product1, product2); + + var customer = new Customer { + FirstName = "Orm", + LastName = "Lite", + Email = "ormlite@servicestack.net", + PhoneNumbers = + { + { PhoneType.Home, "555-1234" }, + { PhoneType.Work, "1-800-1234" }, + { PhoneType.Mobile, "818-123-4567" }, + }, + Addresses = + { + { AddressType.Work, new Address { Line1 = "1 Street", Country = "US", State = "NY", City = "New York", ZipCode = "10101" } }, + }, + CreatedAt = DateTime.UtcNow, + }; + + var customerId = await db.InsertAsync(customer, selectIdentity: true); //Get Auto Inserted Id + customer = await db.SingleAsync(new { customer.Email }); //Query + Assert.That(customer.Id, Is.EqualTo(customerId)); + + //Direct access to System.Data.Transactions: + using (IDbTransaction trans = db.OpenTransaction(IsolationLevel.ReadCommitted)) + { + var order = new Order { + CustomerId = customer.Id, + EmployeeId = 1, + OrderDate = DateTime.UtcNow, + Freight = 10.50m, + ShippingAddress = new Address { Line1 = "3 Street", Country = "US", State = "NY", City = "New York", ZipCode = "12121" }, + }; + await db.SaveAsync(order); //Inserts 1st time + + //order.Id populated on Save(). + + var orderDetails = new[] { + new OrderDetail { + OrderId = order.Id, + ProductId = product1.Id, + Quantity = 2, + UnitPrice = product1.UnitPrice, + }, + new OrderDetail { + OrderId = order.Id, + ProductId = product2.Id, + Quantity = 2, + UnitPrice = product2.UnitPrice, + Discount = .15m, + } + }; + + await db.SaveAsync(orderDetails); + + order.Total = orderDetails.Sum(x => x.UnitPrice * x.Quantity * x.Discount) + order.Freight; + + await db.SaveAsync(order); //Updates 2nd Time + + trans.Commit(); + } + } + } + + public static void RecreateTables(IDbConnection db) + { + DropTables(db); + + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + } + + public static void DropTables(IDbConnection db) + { + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + } + } + +} diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/ExpressionsAuthorTests.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/ExpressionsAuthorTests.cs new file mode 100644 index 000000000..3b6727381 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/ExpressionsAuthorTests.cs @@ -0,0 +1,434 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ServiceStack.DataAnnotations; +using NUnit.Framework; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.UseCase +{ + public class Author + { + [AutoIncrement] + [Alias("AuthorID")] + public int Id { get; set; } + [Index(Unique = true)] + [StringLength(40)] + public string Name { get; set; } + public DateTime Birthday { get; set; } + public DateTime? LastActivity { get; set; } + public decimal? Earnings { get; set; } + public bool Active { get; set; } + [StringLength(80)] + [Alias("JobCity")] + public string City { get; set; } + [StringLength(80)] + [Alias("Comment")] + public string Comments { get; set; } + public short Rate { get; set; } + } + + [TestFixtureOrmLite] + public class ExpressionsAuthorTests : OrmLiteProvidersTestBase + { + public ExpressionsAuthorTests(DialectContext context) : base(context) {} + + [Test] + public void Run_Expressions_Author_tests() + { + var hold = OrmLiteConfig.StripUpperInLike; + OrmLiteConfig.StripUpperInLike = false; + + using (var db = OpenDbConnection()) + { + var dialect = DialectProvider; + var q = db.From(); + + db.DropTable(); + + var tableName = dialect.NamingStrategy.GetTableName(nameof(Author)); + var tableExists = dialect.DoesTableExist(db, tableName); + Assert.That(tableExists, Is.False); + + db.CreateTable(); + + tableExists = dialect.DoesTableExist(db, tableName); + Assert.That(tableExists); + + db.DeleteAll(); + + "Inserting...".Print(); + var t1 = DateTime.Now; + var authors = GetAuthors(); + db.InsertAll(authors); + var t2 = DateTime.Now; + "Inserted {0} rows in {1}".Print(authors.Count, t2 - t1); + + "Selecting.....".Print(); + var year = DateTime.Today.AddYears(-20).Year; + var lastDay = new DateTime(year, 12, 31); + var expected = 5; + + q.Where().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + q.ToSelectStatement().Print(); + + var result = db.Select(q); + q.WhereExpression.Print(); + Assert.That(result.Count, Is.EqualTo(expected)); + + result = db.Select(db.From().Where(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay)); + Assert.That(result.Count, Is.EqualTo(expected)); + result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= lastDay); + Assert.That(result.Count, Is.EqualTo(expected)); + var a = new Author { Birthday = lastDay }; + result = db.Select(rn => rn.Birthday >= new DateTime(year, 1, 1) && rn.Birthday <= a.Birthday); + Assert.That(result.Count, Is.EqualTo(expected)); + + // select authors from London, Berlin and Madrid : 6 + expected = 6; + //Sql.In can take params object[] + var city = "Berlin"; + q.Where().Where(rn => Sql.In(rn.City, "London", "Madrid", city)); //clean prev + result = db.Select(q); + q.WhereExpression.Print(); + Assert.That(result.Count, Is.EqualTo(expected)); + result = db.Select(rn => Sql.In(rn.City, "London", "Madrid", "Berlin")); + Assert.That(result.Count, Is.EqualTo(expected)); + + // select authors from Bogota and Cartagena : 7 + expected = 7; + //... or Sql.In can take List + city = "Bogota"; + var cities = new List { city, "Cartagena" }; + q.Where().Where(rn => Sql.In(rn.City, cities)); + result = db.Select(q); + q.WhereExpression.Print(); + Assert.That(result.Count, Is.EqualTo(expected)); + result = db.Select(rn => Sql.In(rn.City, "Bogota", "Cartagena")); + Assert.That(result.Count, Is.EqualTo(expected)); + + + // select authors which name starts with A + expected = 3; + q.Where().Where(rn => rn.Name.StartsWith("A")); + result = db.Select(q); + q.WhereExpression.Print(); + Assert.That(result.Count, Is.EqualTo(expected)); + result = db.Select(rn => rn.Name.StartsWith("A")); + Assert.That(result.Count, Is.EqualTo(expected)); + + // select authors which name ends with Garzon o GARZON o garzon ( no case sensitive ) + expected = 3; + var name = "GARZON"; + q.Where().Where(rn => rn.Name.ToUpper().EndsWith(name)); + result = db.Select(q); + q.WhereExpression.Print(); + Assert.That(result.Count, Is.EqualTo(expected)); + result = db.Select(rn => rn.Name.ToUpper().EndsWith(name)); + Assert.That(result.Count, Is.EqualTo(expected)); + + // select authors which name ends with garzon + //A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters + //in the string. + //An underscore ("_") in the LIKE pattern matches any single character in the string. + //Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). + expected = 3; + q.Where().Where(rn => rn.Name.EndsWith("garzon")); + result = db.Select(q); + q.WhereExpression.Print(); + Assert.That(result.Count, Is.EqualTo(expected)); + result = db.Select(rn => rn.Name.EndsWith("garzon")); + Assert.That(result.Count, Is.EqualTo(expected)); + + + // select authors which name contains Benedict + expected = 2; + name = "Benedict"; + q.Where().Where(rn => rn.Name.Contains(name)); + result = db.Select(q); + q.WhereExpression.Print(); + Assert.That(result.Count, Is.EqualTo(expected)); + result = db.Select(rn => rn.Name.Contains("Benedict")); + Assert.That(result.Count, Is.EqualTo(expected)); + a.Name = name; + result = db.Select(rn => rn.Name.Contains(a.Name)); + Assert.That(result.Count, Is.EqualTo(expected)); + + + // select authors with Earnings <= 50 + expected = 3; + var earnings = 50; + q.Where().Where(rn => rn.Earnings <= earnings); + result = db.Select(q); + q.WhereExpression.Print(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + result = db.Select(rn => rn.Earnings <= 50); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + + // select authors with Rate = 10 and city=Mexio + expected = 1; + city = "Mexico"; + q.Where().Where(rn => rn.Rate == 10 && rn.City == city); + result = db.Select(q); + q.WhereExpression.Print(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + result = db.Select(rn => rn.Rate == 10 && rn.City == "Mexico"); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + + a.City = city; + result = db.Select(rn => rn.Rate == 10 && rn.City == a.City); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + + // enough selecting, lets update; + // set Active=false where rate =0 + expected = 2; + var rate = 0; + q.Where().Where(rn => rn.Rate == rate).Update(rn => rn.Active); + var rows = db.UpdateOnlyFields(new Author { Active = false }, q); + q.WhereExpression.Print(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); + + // insert values only in Id, Name, Birthday, Rate and Active fields + expected = 4; + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Victor Grozny", Birthday = DateTime.Today.AddYears(-18) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + db.InsertOnly(new Author() { Active = false, Rate = 0, Name = "Ivan Chorny", Birthday = DateTime.Today.AddYears(-19) }, rn => new { rn.Id, rn.Name, rn.Birthday, rn.Active, rn.Rate }); + q.Where().Where(rn => !rn.Active); + result = db.Select(q); + q.WhereExpression.Print(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + + //update comment for City == null + expected = 2; + q.Where().Where(rn => rn.City == null).Update(rn => rn.Comments); + rows = db.UpdateOnlyFields(new Author() { Comments = "No comments" }, q); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); + + // delete where City is null + expected = 2; + rows = db.Delete(q); + q.WhereExpression.Print(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, rows, expected == rows ? "OK" : "************** FAILED ***************"); + + + // lets select all records ordered by Rate Descending and Name Ascending + expected = 14; + q.Where().OrderBy(rn => new { at = Sql.Desc(rn.Rate), rn.Name }); // clear where condition + result = db.Select(q); + q.WhereExpression.Print(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + Console.WriteLine(q.OrderByExpression); + var author = result.FirstOrDefault(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel", author.Name, "Claudia Espinel" == author.Name ? "OK" : "************** FAILED ***************"); + + // select only first 5 rows .... + + expected = 5; + q.Limit(5); // note: order is the same as in the last sentence + result = db.Select(q); + q.WhereExpression.Print(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + + + // and finally lets select only Name and City (name will be "UPPERCASED" ) + + q.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), "Name"), rn.City }); + q.SelectExpression.Print(); + result = db.Select(q); + author = result.FirstOrDefault(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); + + q.Select(rn => new { at = Sql.As(rn.Name.ToUpper(), rn.Name), rn.City }); + q.SelectExpression.Print(); + result = db.Select(q); + author = result.FirstOrDefault(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); + + //paging : + q.Limit(0, 4);// first page, page size=4; + result = db.Select(q); + author = result.FirstOrDefault(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", "Claudia Espinel".ToUpper(), author.Name, "Claudia Espinel".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); + + q.Limit(4, 4);// second page + result = db.Select(q); + author = result.FirstOrDefault(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", "Jorge Garzon".ToUpper(), author.Name, "Jorge Garzon".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); + + q.Limit(8, 4);// third page + result = db.Select(q); + author = result.FirstOrDefault(); + Console.WriteLine("Expected:{0} Selected:{1} {2}", "Rodger Contreras".ToUpper(), author.Name, "Rodger Contreras".ToUpper() == author.Name ? "OK" : "************** FAILED ***************"); + + // select distinct.. + q.Limit().OrderBy(); // clear limit, clear order for postres + q.SelectDistinct(r => r.City); + expected = 6; + result = db.Select(q); + Console.WriteLine("Expected:{0} Selected:{1} {2}", expected, result.Count, expected == result.Count ? "OK" : "************** FAILED ***************"); + + q.Select(r => Sql.As(Sql.Max(r.Birthday), "Birthday")); + result = db.Select(q); + var expectedResult = authors.Max(r => r.Birthday); + Assert.That(result[0].Birthday, Is.EqualTo(expectedResult)); + + q.Select(r => Sql.As(Sql.Max(r.Birthday), r.Birthday)); + result = db.Select(q); + expectedResult = authors.Max(r => r.Birthday); + Assert.That(result[0].Birthday, Is.EqualTo(expectedResult)); + + var r1 = db.Single(q); + Assert.That(r1.Birthday, Is.EqualTo(expectedResult)); + + var r2 = db.Scalar(e => Sql.Max(e.Birthday)); + Assert.That(r2, Is.EqualTo(expectedResult)); + + q.Select(r => Sql.As(Sql.Min(r.Birthday), "Birthday")); + result = db.Select(q); + expectedResult = authors.Min(r => r.Birthday); + Assert.That(result[0].Birthday, Is.EqualTo(expectedResult)); + + q.Select(r => Sql.As(Sql.Min(r.Birthday), r.Birthday)); + result = db.Select(q); + expectedResult = authors.Min(r => r.Birthday); + Assert.That(result[0].Birthday, Is.EqualTo(expectedResult)); + + q.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), "Birthday") }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + result = db.Select(q); + var expectedStringResult = "Berlin"; + Assert.That(result[0].City, Is.EqualTo(expectedStringResult)); + + q.Select(r => new { r.City, MaxResult = Sql.As(Sql.Min(r.Birthday), r.Birthday) }) + .GroupBy(r => r.City) + .OrderBy(r => r.City); + result = db.Select(q); + expectedStringResult = "Berlin"; + Assert.That(result[0].City, Is.EqualTo(expectedStringResult)); + + r1 = db.Single(q); + Assert.That(r1.City, Is.EqualTo(expectedStringResult)); + + var expectedDecimal = authors.Max(e => e.Earnings); + var r3 = db.Scalar(e => Sql.Max(e.Earnings)); + Assert.That(r3.Value, Is.EqualTo(expectedDecimal)); + + var expectedString = authors.Max(e => e.Name); + var r4 = db.Scalar(e => Sql.Max(e.Name)); + Assert.That(r4, Is.EqualTo(expectedString)); + + var expectedDate = authors.Max(e => e.LastActivity); + var r5 = db.Scalar(e => Sql.Max(e.LastActivity)); + Assert.That(r5, Is.EqualTo(expectedDate)); + + var expectedDate51 = authors.Where(e => e.City == "Bogota").Max(e => e.LastActivity); + var r51 = db.Scalar( + e => Sql.Max(e.LastActivity), + e => e.City == "Bogota"); + Assert.That(r51, Is.EqualTo(expectedDate51)); + + try + { + var expectedBool = authors.Max(e => e.Active); + var r6 = db.Scalar(e => Sql.Max(e.Active)); + Assert.That(r6, Is.EqualTo(expectedBool)); + } + catch (Exception e) + { + if (Dialect.HasFlag(Dialect.AnyPostgreSql)) + Console.WriteLine("OK PostgreSQL: " + e.Message); + else + Console.WriteLine("************** FAILED *************** " + e.Message); + } + + + + // Tests for predicate overloads that make use of the expression visitor + "First author by name (exists)".Print(); + author = db.Single(x => x.Name == "Jorge Garzon"); + Assert.That(author.Name, Is.EqualTo("Jorge Garzon")); + + "First author by name (does not exist)".Print(); + author = db.Single(x => x.Name == "Does not exist"); + Assert.That(author, Is.Null); + + "First author or default (does not exist)".Print(); + author = db.Single(x => x.Name == "Does not exist"); + Assert.That(author, Is.Null); + + "First author or default by city (multiple matches)".Print(); + author = db.Single(x => x.City == "Bogota"); + Assert.That(author.Name, Is.EqualTo("Angel Colmenares")); + + a.City = "Bogota"; + author = db.Single(x => x.City == a.City); + Assert.That(author.Name, Is.EqualTo("Angel Colmenares")); + + // count test + var expectedCount = authors.Count; + var r7 = db.Scalar(e => Sql.Count(e.Id)); + Assert.That(r7, Is.EqualTo(expectedCount)); + + expectedCount = authors.Count(e => e.City == "Bogota"); + r7 = db.Scalar( + e => Sql.Count(e.Id), + e => e.City == "Bogota"); + Assert.That(r7, Is.EqualTo(expectedCount)); + + // more updates..... + Console.WriteLine("more updates....................."); + q.Update();// all fields will be updated + // select and update + expected = 1; + var rr = db.Single(rn => rn.Name == "Luis garzon"); + rr.City = "Madrid"; + rr.Comments = "Updated"; + q.Where().Where(r => r.Id == rr.Id); // if omit, then all records will be updated + rows = db.UpdateOnlyFields(rr, q); // == dbCmd.Update(rr) but it returns void + Assert.That(rows, Is.EqualTo(expected)); + + expected = 0; + q.Where().Where(r => r.City == "Ciudad Gotica"); + rows = db.UpdateOnlyFields(rr, q); + Assert.That(rows, Is.EqualTo(expected)); + + expected = db.Select(x => x.City == "Madrid").Count; + author = new Author { Active = false }; + rows = db.UpdateOnlyFields(author, x => x.Active, x => x.City == "Madrid"); + Assert.That(rows, Is.EqualTo(expected)); + + expected = db.Select(x => x.Active == false).Count; + rows = db.Delete(x => x.Active == false); + Assert.That(rows, Is.EqualTo(expected)); + + var t3 = DateTime.Now; + "Expressions test in: {0}".Print(t3 - t2); + "All test in : {0}".Print(t3 - t1); + } + + OrmLiteConfig.StripUpperInLike = hold; + } + + public List GetAuthors() + { + return new List + { + new Author { Name = "Demis Bellot", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 99.9m, Comments = "CSharp books", Rate = 10, City = "London" }, + new Author { Name = "Angel Colmenares", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 50.0m, Comments = "CSharp books", Rate = 5, City = "Bogota" }, + new Author { Name = "Adam Witco", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 80.0m, Comments = "Math Books", Rate = 9, City = "London" }, + new Author { Name = "Claudia Espinel", Birthday = DateTime.Today.AddYears(-23), Active = true, Earnings = 60.0m, Comments = "Cooking books", Rate = 10, City = "Bogota" }, + new Author { Name = "Libardo Pajaro", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 80.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }, + new Author { Name = "Jorge Garzon", Birthday = DateTime.Today.AddYears(-28), Active = true, Earnings = 70.0m, Comments = "CSharp books", Rate = 9, City = "Bogota" }, + new Author { Name = "Alejandro Isaza", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 70.0m, Comments = "Java books", Rate = 0, City = "Bogota" }, + new Author { Name = "Wilmer Agamez", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 30.0m, Comments = "Java books", Rate = 0, City = "Cartagena" }, + new Author { Name = "Rodger Contreras", Birthday = DateTime.Today.AddYears(-25), Active = true, Earnings = 90.0m, Comments = "CSharp books", Rate = 8, City = "Cartagena" }, + new Author { Name = "Chuck Benedict", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "CSharp books", Rate = 8, City = "London" }, + new Author { Name = "James Benedict II", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.5m, Comments = "Java books", Rate = 5, City = "Berlin" }, + new Author { Name = "Ethan Brown", Birthday = DateTime.Today.AddYears(-20), Active = true, Earnings = 45.0m, Comments = "CSharp books", Rate = 5, City = "Madrid" }, + new Author { Name = "Xavi Garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 75.0m, Comments = "CSharp books", Rate = 9, City = "Madrid" }, + new Author { Name = "Luis garzon", Birthday = DateTime.Today.AddYears(-22), Active = true, Earnings = 85.0m, Comments = "CSharp books", Rate = 10, City = "Mexico" }, + }; + } + + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/FieldFromInterfaceImplementationUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/FieldFromInterfaceImplementationUseCase.cs index b5f55879c..17723b795 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/FieldFromInterfaceImplementationUseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/FieldFromInterfaceImplementationUseCase.cs @@ -40,9 +40,11 @@ public class EntityAttribute public string AttributeValue { get; set; } } - [TestFixture] - public class FieldFromInterfaceImplementationUseCase : OrmLiteTestBase + [TestFixtureOrmLite] + public class FieldFromInterfaceImplementationUseCase : OrmLiteProvidersTestBase { + public FieldFromInterfaceImplementationUseCase(DialectContext context) : base(context) {} + [Test] public void Can_select_on_generic_interface_implementation_properties_with_PrefixFieldWithTableName() { diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/ImageBlobDto.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/ImageBlobDto.cs index d37aae023..60118ea1e 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/ImageBlobDto.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/ImageBlobDto.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using ServiceStack.DataAnnotations; namespace ServiceStack.OrmLite.Tests.UseCase diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/ImageBlobResource.resx b/tests/ServiceStack.OrmLite.Tests/UseCase/ImageBlobResource.resx deleted file mode 100644 index 7a9e6984c..000000000 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/ImageBlobResource.resx +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Bild.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - Bild2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - Bild3.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/NestedComplexTypeUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/NestedComplexTypeUseCase.cs index c334b4579..eef9298c5 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/NestedComplexTypeUseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/NestedComplexTypeUseCase.cs @@ -4,9 +4,11 @@ namespace ServiceStack.OrmLite.Tests.UseCase { - [TestFixture] - public class NestedComplexTypeUseCase : OrmLiteTestBase + [TestFixtureOrmLite] + public class NestedComplexTypeUseCase : OrmLiteProvidersTestBase { + public NestedComplexTypeUseCase(DialectContext context) : base(context) {} + public class Location { [AutoIncrement] diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/ParentChildCyclicalExample.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/ParentChildCyclicalExample.cs new file mode 100644 index 000000000..93bdd0a42 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/ParentChildCyclicalExample.cs @@ -0,0 +1,73 @@ +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.UseCase +{ + public class Parent + { + [AutoIncrement] + public int Id { get; set; } + + public string Name { get; set; } + + // the item currently published, modelled like an EF navigation property + [Reference] + public Child ActiveChild { get; set; } + + public int? ActiveChildId { get; set; } + + // all items mapped to this Parent + [Reference] + public List AllChildren { get; set; } + } + + public class Child + { + [AutoIncrement] + public int Id { get; set; } + + public int ParentId { get; set; } + + public string Description { get; set; } + } + + [TestFixtureOrmLite] + public class ParentChildCyclicalExample : OrmLiteProvidersTestBase + { + public ParentChildCyclicalExample(DialectContext context) : base(context) {} + + [Test] + public void Can_create_Parent_Child_Tables() + { + using (var db = OpenDbConnection()) + { + db.DropTable(); + db.DropTable(); + + db.CreateTable(); + db.CreateTable(); + + var parent = new Parent + { + Name = "Parent", + ActiveChild = new Child { Description = "Active" }, + AllChildren = new List + { + new Child { Description = "Child 1" }, + new Child { Description = "Child 2" }, + } + }; + + db.Save(parent, references:true); + + var dbParent = db.LoadSelect()[0]; + dbParent.PrintDump(); + + Assert.That(dbParent.ActiveChild, Is.Not.Null); + Assert.That(dbParent.AllChildren.Count, Is.EqualTo(3)); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/PlayerCreateTableUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/PlayerCreateTableUseCase.cs new file mode 100644 index 000000000..2dabb90cd --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/PlayerCreateTableUseCase.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests.UseCase +{ + public class Player + { + public int Id { get; set; } // 'Id' is PrimaryKey by convention + + [Required] + public string FirstName { get; set; } // Creates NOT NULL Column + + [Alias("Surname")] // Maps to [Surname] RDBMS column + public string LastName { get; set; } + + [Index(Unique = true)] // Creates Unique Index + public string Email { get; set; } + + public List PhoneNumbers { get; set; } // Complex Types blobbed by default + + [Reference] + public List GameItems { get; set; } // 1:M Reference Type saved separately + + [Reference] + public Profile Profile { get; set; } // 1:1 Reference Type saved separately + public int ProfileId { get; set; } // 1:1 Self Ref Id on Parent Table + + [ForeignKey(typeof(Level), OnDelete="CASCADE")] // Creates ON DELETE CASCADE Constraint + public Guid SavedLevelId { get; set; } // Creates Foreign Key Reference + + public ulong RowVersion { get; set; } // Optimistic Concurrency Updates + } + + public class Phone // Blobbed Type only + { + public PhoneKind Kind { get; set; } + + public string Number { get; set; } + + public string Ext { get; set; } + } + + public enum PhoneKind + { + Home, + Mobile, + Work, + } + + [Alias("PlayerProfile")] // Maps to [PlayerProfile] RDBMS Table + [CompositeIndex(nameof(Username), nameof(Region))] // Creates Composite Index + public class Profile + { + [AutoIncrement] // Auto Insert Id assigned by RDBMS + public int Id { get; set; } + + public PlayerRole Role { get; set; } // Native support for Enums + + public Region Region { get; set; } + + public string Username { get; set; } + + public long HighScore { get; set; } + + [Default(1)] // Created in RDBMS with DEFAULT (1) + public long GamesPlayed { get; set; } + + [CheckConstraint("Energy BETWEEN 0 AND 100")] // Creates RDBMS Check Constraint + public short Energy { get; set; } + + public string ProfileUrl { get; set; } + + public Dictionary Meta { get; set; } + } + + public enum PlayerRole // Enums saved as strings by default + { + Leader, + Player, + NonPlayer, + } + + [EnumAsInt] // Enum Saved as int + public enum Region + { + Africa = 1, + Americas = 2, + Asia = 3, + Australasia = 4, + Europe = 5, + } + + public class GameItem + { + [PrimaryKey] // Specify field to use as Primary Key + [StringLength(50)] // Creates VARCHAR COLUMN + public string Name { get; set; } + + public int PlayerId { get; set; } // Foreign Table Reference Id + + [StringLength(StringLengthAttribute.MaxText)] // Creates "TEXT" RDBMS Column + public string Description { get; set; } + + [Default(OrmLiteVariables.SystemUtc)] // Populated with UTC Date by RDBMS + public DateTime DateAdded { get; set; } + } + + public class Level + { + public Guid Id { get; set; } // Unique Identifer/GUID Primary Key + + public byte[] Data { get; set; } // Saved as BLOB/Binary where possible + } + + + [TestFixtureOrmLite] + public class PlayerCreateTableUseCase : OrmLiteProvidersTestBase + { + public PlayerCreateTableUseCase(DialectContext context) : base(context) {} + + [Test] + public void Can_Create_Player_Tables_and_Save_Data() + { +// OrmLiteConfig.BeforeExecFilter = cmd => cmd.GetDebugString().Print(); + + using (var db = OpenDbConnection()) + { + if (db.TableExists()) + db.DeleteAll(); // Delete ForeignKey data if exists + + //DROP and CREATE Foreign Key Tables in dependent order + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + + //DROP and CREATE tables without Foreign Keys in any order + db.DropAndCreateTable(); + db.DropAndCreateTable(); + + var savedLevel = new Level + { + Id = Guid.NewGuid(), + Data = new byte[]{ 1, 2, 3, 4, 5 }, + }; + db.Insert(savedLevel); + + var player = new Player + { + Id = 1, + FirstName = "North", + LastName = "West", + Email = "north@west.com", + PhoneNumbers = new List + { + new Phone { Kind = PhoneKind.Mobile, Number = "123-555-5555"}, + new Phone { Kind = PhoneKind.Home, Number = "555-555-5555", Ext = "123"}, + }, + GameItems = new List + { + new GameItem { Name = "WAND", Description = "Golden Wand of Odyssey"}, + new GameItem { Name = "STAFF", Description = "Staff of the Magi"}, + }, + Profile = new Profile + { + Username = "north", + Role = PlayerRole.Leader, + Region = Region.Australasia, + HighScore = 100, + GamesPlayed = 10, + ProfileUrl = "https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50.jpg", + Meta = new Dictionary + { + {"Quote", "I am gamer"} + }, + }, + SavedLevelId = savedLevel.Id, + }; + db.Save(player, references: true); + + var dbPlayer = db.LoadSingleById(player.Id); + + dbPlayer.PrintDump(); + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/PostPerfTests.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/PostPerfTests.cs new file mode 100644 index 000000000..600356f37 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/PostPerfTests.cs @@ -0,0 +1,276 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Linq; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Dapper; + +namespace ServiceStack.OrmLite.Tests.UseCase +{ + class Post + { + public int Id { get; set; } + public string Text { get; set; } + public DateTime CreationDate { get; set; } + public DateTime LastChangeDate { get; set; } + public int? Counter1 { get; set; } + public int? Counter2 { get; set; } + public int? Counter3 { get; set; } + public int? Counter4 { get; set; } + public int? Counter5 { get; set; } + public int? Counter6 { get; set; } + public int? Counter7 { get; set; } + public int? Counter8 { get; set; } + public int? Counter9 { get; set; } + + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer), NUnit.Framework.Ignore("Integration Test")] + public class PostPerfTests : OrmLiteProvidersTestBase + { + public PostPerfTests(DialectContext context) : base(context) {} + +// public PostPerfTests() +// { +// Dialect = Dialect.SqlServer2012; +// } + + private void EnsureDBSetup() + { + using (var cnn = OpenDbConnection().ToDbConnection()) + { + var cmd = cnn.CreateCommand(); + cmd.CommandText = @" +if (OBJECT_ID('Post') is null) +begin + create table Post + ( + Id int identity primary key, + [Text] varchar(max) not null, + CreationDate datetime not null, + LastChangeDate datetime not null, + Counter1 int, + Counter2 int, + Counter3 int, + Counter4 int, + Counter5 int, + Counter6 int, + Counter7 int, + Counter8 int, + Counter9 int + ) + + set nocount on + + declare @i int + declare @c int + + declare @id int + + set @i = 0 + + while @i < 5000 + begin + + insert Post ([Text],CreationDate, LastChangeDate) values (replicate('x', 2000), GETDATE(), GETDATE()) + set @id = @@IDENTITY + + set @i = @i + 1 + end +end +"; + cmd.Connection = cnn; + cmd.ExecuteNonQuery(); + } + } + [Test] + public void Run_single_select_Dapper() + { + var tester = new Tester(); + + var db = OpenDbConnection(); + tester.Add(id => db.Query("select * from Post where Id = @Id", new { Id = id }).ToList(), "Mapper Query"); + + tester.Run(500); + } + + [Test] + public void Run_single_select_OrmLite() + { + var tester = new Tester(); + + var db = OpenDbConnection(); + tester.Add(id => db.Select("select * from Post where Id = @id", new { id = id }), "OrmLite Query"); + + tester.Run(500); + } + + [Test] + public void Run_multi_select_Dapper() + { + var tester = new Tester(); + + var db = OpenDbConnection(); + tester.Add(id => db.Query("select top 1000 * from Post").ToList(), "Mapper Query"); + + tester.Run(50); + } + + [Test] + public void Run_multi_select_OrmLite() + { + var tester = new Tester(); + + var db = OpenDbConnection(); + tester.Add(id => db.Select("select top 1000 * from Post"), "OrmLite Query"); + + tester.Run(50); + } + + [Test] + public void Run_multi_select_OrmLite_SqlExpression() + { + var tester = new Tester(); + + var db = OpenDbConnection(); + tester.Add(id => db.Select(db.From().Limit(1000)), "OrmLite Query Expression"); + + tester.Run(50); + } + } + + [TestFixtureOrmLiteDialects(Dialect.AnySqlServer), Explicit, NUnit.Framework.Ignore("Integration Test")] + public class AdventureWorksPerfTests : OrmLiteProvidersTestBase + { + public AdventureWorksPerfTests(DialectContext context) : base(context) {} + + private IDbConnection db; + +// public AdventureWorksPerfTests() +// { +// var dbFactory = new OrmLiteConnectionFactory( +// "data source=localhost;initial catalog=AdventureWorks;integrated security=SSPI;persist security info=False;packet size=4096", +// SqlServer2012Dialect.Provider); +// +// db = dbFactory.Open(); +// } + + [SetUp] + public void Setup() + { + db = OpenDbConnection(); + } + + [TearDown] + public void TearDown() + { + db.Dispose(); + } + + private static string SqlSelectCommandText = @"SELECT [SalesOrderID],[RevisionNumber],[OrderDate],[DueDate],[ShipDate],[Status],[OnlineOrderFlag],[SalesOrderNumber],[PurchaseOrderNumber],[AccountNumber],[CustomerID],[SalesPersonID],[TerritoryID],[BillToAddressID],[ShipToAddressID],[ShipMethodID],[CreditCardID],[CreditCardApprovalCode],[CurrencyRateID],[SubTotal],[TaxAmt],[Freight],[TotalDue],[Comment],[rowguid],[ModifiedDate] FROM [Sales].[SalesOrderHeader]"; + + [Test] + public void Select_all_SalesOrderHeader_Dapper() + { + db.Query(SqlSelectCommandText).AsList(); + + var tester = new Tester(); + + tester.Add(id => db.Query(SqlSelectCommandText).AsList(), "Dapper Query"); + + tester.Run(10); + } + + [Test] + public void Select_all_SalesOrderHeader_OrmLite() + { + var tester = new Tester(); + + tester.Add(id => db.SqlList(SqlSelectCommandText), "OrmLite Query"); + + tester.Run(10); + } + } + + [Schema("Sales")] + public class SalesOrderHeader + { + public string AccountNumber { get; set; } + public string Comment { get; set; } + public string CreditCardApprovalCode { get; set; } + public DateTime DueDate { get; set; } + public decimal Freight { get; set; } + public DateTime ModifiedDate { get; set; } + public bool OnlineOrderFlag { get; set; } + public DateTime OrderDate { get; set; } + public string PurchaseOrderNumber { get; set; } + public byte RevisionNumber { get; set; } + public Guid Rowguid { get; set; } + public int SalesOrderId { get; set; } + public string SalesOrderNumber { get; set; } + public DateTime? ShipDate { get; set; } + public byte Status { get; set; } + public decimal SubTotal { get; set; } + public decimal TaxAmt { get; set; } + public decimal TotalDue { get; set; } + + public int CustomerID { get; set; } + public int? SalesPersonID { get; set; } + public int? TerritoryID { get; set; } + public int BillToAddressID { get; set; } + public int ShipToAddressID { get; set; } + public int ShipMethodID { get; set; } + public int? CreditCardID { get; set; } + public int? CurrencyRateID { get; set; } + } + + class Test + { + public static Test Create(Action iteration, string name) + { + return new Test { Iteration = iteration, Name = name }; + } + + public Action Iteration { get; set; } + public string Name { get; set; } + public Stopwatch Watch { get; set; } + } + + class Tester : List + { + public void Add(Action iteration, string name) + { + Add(Test.Create(iteration, name)); + } + + public void Run(int iterations) + { + // warmup + foreach (var test in this) + { + test.Iteration(iterations + 1); + test.Watch = new Stopwatch(); + test.Watch.Reset(); + } + + var rand = new Random(); + for (int i = 1; i <= iterations; i++) + { + foreach (var test in this.OrderBy(ignore => rand.Next())) + { + test.Watch.Start(); + test.Iteration(i); + test.Watch.Stop(); + } + } + + foreach (var test in this.OrderBy(t => t.Watch.ElapsedMilliseconds)) + { + Console.WriteLine(test.Name + " took " + test.Watch.ElapsedMilliseconds + "ms"); + } + } + } + +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/SchemaUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/SchemaUseCase.cs index 7f529ec89..a9acb53a4 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/SchemaUseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/SchemaUseCase.cs @@ -6,9 +6,21 @@ namespace ServiceStack.OrmLite.Tests.UseCase { - [TestFixture] - public class SchemaUseCase + [TestFixtureOrmLite] + public class SchemaUseCase : OrmLiteProvidersTestBase { + public SchemaUseCase(DialectContext context) : base(context) {} + + [OneTimeSetUp] + public void OneTimeSetup() + { + using (var db = OpenDbConnection()) + { + if(!Dialect.Sqlite.HasFlag(Dialect)) + db.CreateSchema(); + } + } + [Alias("Users")] [Schema("Security")] public class User @@ -23,57 +35,21 @@ public class User } [Test] - public void Can_Create_Tables_With_Schema_In_Sqlite() + public void Can_Create_Tables_With_Schema() { - OrmLiteConfig.DialectProvider = SqliteDialect.Provider; - - using (IDbConnection db = ":memory:".OpenDbConnection()) + using (var db = OpenDbConnection()) { db.CreateTable(true); - - var tables = - db.ColumnFmt - (@"SELECT name FROM sqlite_master WHERE type='table';"); - - //sqlite dialect should just concatenate the schema and table name to create a unique table name - Assert.That(tables.Contains("Security_Users")); - } - } - - private void CreateSchemaIfNotExists(IDbConnection db) - { - //in Sql2008, CREATE SCHEMA must be the first statement in a batch - const string createSchemaSQL = @"IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'Security') - BEGIN - EXEC( 'CREATE SCHEMA Security' ); - END"; - db.ExecuteSql(createSchemaSQL); - } - - [Test] - public void Can_Create_Tables_With_Schema_in_SqlServer() - { - var dbFactory = OrmLiteTestBase.CreateSqlServerDbFactory(); - using (IDbConnection db = dbFactory.OpenDbConnection()) - { - CreateSchemaIfNotExists(db); - db.DropAndCreateTable(); - - var tables = db.ColumnFmt - (@"SELECT '['+SCHEMA_NAME(schema_id)+'].['+name+']' AS SchemaTable FROM sys.tables"); - - //sql server dialect should create the table in the schema - Assert.That(tables.Contains("[Security].[Users]")); + + Assert.That(db.TableExists()); } } [Test] public void Can_Perform_CRUD_Operations_On_Table_With_Schema() { - var dbFactory = OrmLiteTestBase.CreateSqlServerDbFactory(); - using (IDbConnection db = dbFactory.OpenDbConnection()) + using (var db = OpenDbConnection()) { - CreateSchemaIfNotExists(db); db.CreateTable(true); db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now }); @@ -84,7 +60,7 @@ public void Can_Perform_CRUD_Operations_On_Table_With_Schema() Assert.That(user.Id, Is.GreaterThan(0)); - var rowsB = db.SelectFmt("Name = {0}", "B"); + var rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(2)); var rowIds = rowsB.ConvertAll(x => x.Id); @@ -92,7 +68,7 @@ public void Can_Perform_CRUD_Operations_On_Table_With_Schema() rowsB.ForEach(x => db.Delete(x)); - rowsB = db.SelectFmt("Name = {0}", "B"); + rowsB = db.Select("Name = @name", new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(0)); var rowsLeft = db.Select(); diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/ServiceStack_OrmLite_UseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/ServiceStack_OrmLite_UseCase.cs index a4e5bf96d..be42c5286 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/ServiceStack_OrmLite_UseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/ServiceStack_OrmLite_UseCase.cs @@ -14,9 +14,11 @@ public class Todo public bool Done { get; set; } } - [TestFixture] - public class ServiceStack_OrmLite_UseCase : OrmLiteTestBase + [TestFixtureOrmLite] + public class ServiceStack_OrmLite_UseCase : OrmLiteProvidersTestBase { + public ServiceStack_OrmLite_UseCase(DialectContext context) : base(context) {} + [Test] public void Can_Add_Update_and_Delete_Todo_item() { diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/SimpleUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/SimpleUseCase.cs index 287f53171..c6fb8ea66 100644 --- a/tests/ServiceStack.OrmLite.Tests/UseCase/SimpleUseCase.cs +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/SimpleUseCase.cs @@ -5,9 +5,11 @@ namespace ServiceStack.OrmLite.Tests.UseCase { - [TestFixture] - public class SimpleUseCase : OrmLiteTestBase + [TestFixtureOrmLite] + public class SimpleUseCase : OrmLiteProvidersTestBase { + public SimpleUseCase(DialectContext context) : base(context) {} + public class User { public long Id { get; set; } @@ -21,7 +23,7 @@ public class User [Test] public void Simple_CRUD_example() { - using (IDbConnection db = OpenDbConnection()) + using (var db = OpenDbConnection()) { db.DropAndCreateTable(); @@ -29,7 +31,7 @@ public void Simple_CRUD_example() db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now }); db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now }); - var rowsB = db.SelectFmt("Name = {0}", "B"); + var rowsB = db.Select("Name = @name".PreNormalizeSql(db), new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(2)); @@ -38,7 +40,7 @@ public void Simple_CRUD_example() rowsB.ForEach(x => db.Delete(x)); - rowsB = db.SelectFmt("Name = {0}", "B"); + rowsB = db.Select("Name = @name".PreNormalizeSql(db), new { name = "B" }); Assert.That(rowsB, Has.Count.EqualTo(0)); var rowsLeft = db.Select(); diff --git a/tests/ServiceStack.OrmLite.Tests/UseCase/SoftDeleteUseCase.cs b/tests/ServiceStack.OrmLite.Tests/UseCase/SoftDeleteUseCase.cs new file mode 100644 index 000000000..de723a77b --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/UseCase/SoftDeleteUseCase.cs @@ -0,0 +1,232 @@ +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.OrmLite.Tests.Shared; + +namespace ServiceStack.OrmLite.Tests.UseCase +{ + public interface ISoftDelete + { + bool IsDeleted { get; set; } + } + + public class ModelWithSoftDelete : ISoftDelete + { + [AutoIncrement] + public int Id { get; set; } + public string Name { get; set; } + public bool IsDeleted { get; set; } + } + + public class ModelWithSoftDeleteJoin : ISoftDelete + { + [AutoIncrement] + public int Id { get; set; } + public string Name { get; set; } + public bool IsDeleted { get; set; } + } + + public static class SqlExpressionExtensions + { + public static SqlExpression OnlyActive(this SqlExpression q) + where T : ISoftDelete + { + return q.Where(x => x.IsDeleted != true); + } + } + + [TestFixtureOrmLite] + public class SoftDeleteUseCase : OrmLiteProvidersTestBase + { + public SoftDeleteUseCase(DialectContext context) : base(context) {} + + [Test] + public void Can_add_generic_soft_delete_filter_to_SqlExpression() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + db.Insert(new ModelWithSoftDelete { Name = "foo" }); + db.Insert(new ModelWithSoftDelete { Name = "bar", IsDeleted = true }); + + var results = db.Select(db.From().OnlyActive()); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("foo")); + + var result = db.Single(db.From().Where(x => x.Name == "foo").OnlyActive()); + Assert.That(result.Name, Is.EqualTo("foo")); + result = db.Single(db.From().Where(x => x.Name == "bar").OnlyActive()); + Assert.That(result, Is.Null); + } + } + + [Test] + public void Can_add_generic_soft_delete_filter_to_SqlExpression_using_SelectFilter() + { + using (var db = OpenDbConnection()) + { + SqlExpression.SelectFilter = q => q.Where(x => x.IsDeleted != true); + + db.DropAndCreateTable(); + + db.Insert(new ModelWithSoftDelete { Name = "foo" }); + db.Insert(new ModelWithSoftDelete { Name = "bar", IsDeleted = true }); + + var results = db.Select(db.From()); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("foo")); + + results = db.Select(x => x.Id > 0); + Assert.That(results.Count, Is.EqualTo(1)); + + var result = db.Single(db.From().Where(x => x.Name == "foo")); + Assert.That(result.Name, Is.EqualTo("foo")); + result = db.Single(db.From().Where(x => x.Name == "bar")); + Assert.That(result, Is.Null); + + result = db.Single(x => x.Name == "bar"); + Assert.That(result, Is.Null); + + SqlExpression.SelectFilter = null; + } + } + + [Test] + public void Can_get_RowCount_with_generic_soft_delete_filter_using_SelectFilter() + { + using (var db = OpenDbConnection()) + { + SqlExpression.SelectFilter = q => q.Where(x => x.IsDeleted != true); + + db.DropAndCreateTable(); + + db.Insert(new ModelWithSoftDelete { Name = "foo" }); + db.Insert(new ModelWithSoftDelete { Name = "bar", IsDeleted = true }); + + Assert.DoesNotThrow(() => + { + var count = db.RowCount(db.From()); + }); + + SqlExpression.SelectFilter = null; + } + } + + [Test] + public void Can_add_generic_soft_delete_filter_to_SqlExpression_using_SqlExpressionSelectFilter() + { + using (var db = OpenDbConnection()) + { + OrmLiteConfig.SqlExpressionSelectFilter = q => + { + if (q.ModelDef.ModelType.HasInterface(typeof(ISoftDelete))) + { + q.Where(x => x.IsDeleted != true); + } + }; + + db.DropAndCreateTable(); + db.Insert(new ModelWithSoftDelete { Name = "foo" }); + db.Insert(new ModelWithSoftDelete { Name = "bar", IsDeleted = true }); + + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.Insert(new Table1 { Id = 1, String = "foo" }); + db.Insert(new Table1 { Id = 2, String = "bar" }); + + var results = db.Select(db.From()); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("foo")); + + results = db.Select(x => x.Id > 0); + Assert.That(results.Count, Is.EqualTo(1)); + + var result = db.Single(db.From().Where(x => x.Name == "foo")); + Assert.That(result.Name, Is.EqualTo("foo")); + result = db.Single(db.From().Where(x => x.Name == "bar")); + Assert.That(result, Is.Null); + + result = db.Single(x => x.Name == "bar"); + Assert.That(result, Is.Null); + + result = db.Single(db.From() + .Join((m, t) => m.Name == t.String) + .Where(x => x.Name == "foo")); + Assert.That(result.Name, Is.EqualTo("foo")); + + result = db.Single(db.From() + .Join((m, t) => m.Name == t.String) + .Where(x => x.Name == "bar")); + Assert.That(result, Is.Null); + + OrmLiteConfig.SqlExpressionSelectFilter = null; + } + } + + [Test] + public void Can_get_RowCount_with_generic_soft_delete_filter_using_SqlExpressionSelectFilter() + { + using (var db = OpenDbConnection()) + { + OrmLiteConfig.SqlExpressionSelectFilter = q => + { + if (q.ModelDef.ModelType.HasInterface(typeof(ISoftDelete))) + { + q.Where(x => x.IsDeleted != true); + } + }; + + db.DropAndCreateTable(); + + db.Insert(new ModelWithSoftDelete { Name = "foo" }); + db.Insert(new ModelWithSoftDelete { Name = "bar", IsDeleted = true }); + + Assert.DoesNotThrow(() => + { + var count = db.RowCount(db.From()); + }); + + OrmLiteConfig.SqlExpressionSelectFilter = null; + } + } + + [Test] + public void Can_use_interface_condition_on_table_with_join() + { + using (var db = OpenDbConnection()) + { + OrmLiteConfig.SqlExpressionSelectFilter = q => + { + if (q.ModelDef.ModelType.HasInterface(typeof(ISoftDelete))) + { + q.Where(x => x.IsDeleted != true); + } + }; + + db.DropAndCreateTable(); + db.Insert(new ModelWithSoftDelete { Name = "foo" }); + db.Insert(new ModelWithSoftDelete { Name = "bar", IsDeleted = true }); + db.DropAndCreateTable(); + db.Insert(new ModelWithSoftDeleteJoin { Name = "foo" }); + db.Insert(new ModelWithSoftDeleteJoin { Name = "bar", IsDeleted = true }); + + var result = db.Single(db.From() + .Join((m, j) => m.Name == j.Name) + .Where(x => x.Name == "foo")); + Assert.That(result.Name, Is.EqualTo("foo")); + + result = db.Single(db.From() + .Join((m, j) => m.Name == j.Name) + .Where(x => x.Name == "bar")); + Assert.That(result, Is.Null); + + OrmLiteConfig.SqlExpressionSelectFilter = null; + } + } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/_Adhoc.cs b/tests/ServiceStack.OrmLite.Tests/_Adhoc.cs new file mode 100644 index 000000000..de444401a --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/_Adhoc.cs @@ -0,0 +1,11 @@ +using System; +using NUnit.Framework; +using ServiceStack.DataAnnotations; + +namespace ServiceStack.OrmLite.Tests +{ + public class _Adhoc : OrmLiteTestBase + { + public _Adhoc() : base(Dialect.PostgreSql11) { } + } +} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLite.Tests/_TypeDescriptorMetadataTests.cs b/tests/ServiceStack.OrmLite.Tests/_TypeDescriptorMetadataTests.cs new file mode 100644 index 000000000..5398652e3 --- /dev/null +++ b/tests/ServiceStack.OrmLite.Tests/_TypeDescriptorMetadataTests.cs @@ -0,0 +1,238 @@ +using System; +using System.Data; +using System.Text; +using NUnit.Framework; +using ServiceStack.DataAnnotations; +using ServiceStack.Text; + +namespace ServiceStack.OrmLite.Tests +{ + // Needs to be run first + [TestFixtureOrmLite] + public class _TypeDescriptorMetadataTests : OrmLiteProvidersTestBase + { + public _TypeDescriptorMetadataTests(DialectContext context) : base(context) {} + + [Test] + public void Can_add_AutoIncrement_Id_at_runtime() + { + using (var db = OpenDbConnection()) + { + var model = new PersonDescriptor {FirstName = "Jimi", LastName = "Hendrix", Age = 27}; + + typeof(PersonDescriptor).GetProperty("Id") + .AddAttributes(new AutoIncrementAttribute()); + + db.DropAndCreateTable(); + + var oldRows = db.Select(); + + db.Insert(model); + db.Insert(model); + model.Id = 0; // Oracle provider currently updates the id field so force it back to get an insert operation + db.Save(model); + + var allRows = db.Select(); + Assert.That(allRows.Count - oldRows.Count, Is.EqualTo(3)); + } + } + + [Test] + [IgnoreDialect(Dialect.AnyOracle, "Test assert fails with Oracle because Oracle does not allow 64000 character fields and uses VARCHAR2 not VARCHAR")] + [IgnoreDialect(Dialect.AnyPostgreSql, "Uses 'text' for strings by default")] + public void Can_change_column_definition() + { + using (var db = OpenDbConnection()) + { + typeof(DynamicCacheEntry) + .GetProperty("Data") + .AddAttributes(new StringLengthAttribute(7000)); + + db.DropAndCreateTable(); + + Assert.That(db.GetLastSql().NormalizeSql(), + Does.Contain("Data VARCHAR(7000)".NormalizeSql())); + db.GetLastSql().Print(); + } + } + + [Test] + public void Can_Create_Table_with_MaxText_column() + { + using (var db = OpenDbConnection()) + { + db.DropAndCreateTable(); + + var sql = db.GetLastSql(); + sql.Print(); + + if (Dialect == Dialect.Sqlite) + { + Assert.That(sql, Does.Contain(" VARCHAR(1000000)")); + } + else if (Dialect == Dialect.AnyPostgreSql) + { + Assert.That(sql, Does.Contain(" TEXT")); + } + else if (Dialect == Dialect.AnyMySql) + { + Assert.That(sql, Does.Contain(" LONGTEXT")); + } + else if (Dialect == Dialect.AnyOracle) + { + Assert.That(sql, Does.Contain(" VARCHAR2(4000)")); + } + else if (Dialect == Dialect.SqlServer) + { + Assert.That(sql, Does.Contain(" VARCHAR(MAX)")); + } + } + } + + [Test] + public void Can_Create_Table_with_MaxText_column_Unicode() + { + using (var db = OpenDbConnection()) + { + var stringConverter = DialectProvider.GetStringConverter(); + var hold = stringConverter.UseUnicode; + stringConverter.UseUnicode = true; + + try + { + db.DropAndCreateTable(); + } + catch (Exception) + { + db.DropAndCreateTable(); + } + finally + { + stringConverter.UseUnicode = hold; + } + + var sql = db.GetLastSql(); + sql.Print(); + + if (Dialect.Sqlite.HasFlag(Dialect)) + { + Assert.That(sql, Does.Contain(" NVARCHAR(1000000)")); + } + else if (Dialect.AnyPostgreSql.HasFlag(Dialect)) + { + Assert.That(sql, Does.Contain(" TEXT")); + } + else if (Dialect.AnyMySql.HasFlag(Dialect)) + { + Assert.That(sql, Does.Contain(" LONGTEXT")); + } + else if (Dialect.AnyOracle.HasFlag(Dialect)) + { + Assert.That(sql, Does.Contain(" NVARCHAR2(4000)")); + } + else if (Dialect.Firebird.HasFlag(Dialect)) + { + Assert.That(sql, Does.Contain(" VARCHAR(10000)")); + } + else + { + Assert.That(sql, Does.Contain(" NVARCHAR(MAX)")); + } + } + } + + [Test] + public void Does_save_cache_data_when_data_exceeds_StringConverter_max_size() + { + IDbDataParameter GetParam(IDbCommand cmd, string name) + { + for (var i = 0; i < cmd.Parameters.Count; i++) + { + if (cmd.Parameters[i] is IDbDataParameter p + && p.ParameterName.Substring(1).EqualsIgnoreCase(name)) + { + return p; + } + } + return null; + } + + using (var db = OpenDbConnection()) + { + var stringConverter = db.GetDialectProvider().GetStringConverter(); + var hold = stringConverter.StringLength; + stringConverter.StringLength = 255; + + try + { + db.DropAndCreateTable(); + } + catch (Exception) + { + db.DropAndCreateTable(); + } + + var sb = new StringBuilder(); + 30.Times(i => sb.Append("0123456789")); + Assert.That(sb.Length, Is.EqualTo(300)); + + var id = "key"; + + var original = new CacheEntry { + Id = id, + Data = sb.ToString(), + CreatedDate = DateTime.Now, + ModifiedDate = DateTime.Now, + }; + db.Insert(original, cmd => { + var idParam = GetParam(cmd, nameof(CacheEntry.Id)); + var dataParam = GetParam(cmd, nameof(CacheEntry.Data)); + + //MySql auto sets param size based on value + Assert.That(idParam.Size, Is.EqualTo(stringConverter.StringLength) + .Or.EqualTo(Math.Min((idParam.Value as string).Length, stringConverter.StringLength)) + ); + Assert.That(dataParam.Size, Is.EqualTo(300) + .Or.EqualTo(Math.Min((dataParam.Value as string).Length, stringConverter.StringLength)) + ); + }); + + var key = db.SingleById(id); + Assert.That(key.Data, Is.EqualTo(original.Data)); + + var updatedData = key.Data + "0123456789"; + + var exists = db.UpdateOnlyFields(new CacheEntry + { + Id = id, + Data = updatedData, + ModifiedDate = DateTime.UtcNow, + }, + onlyFields: q => new { q.Data, q.ModifiedDate }, + @where: q => q.Id == id, + cmd => { + var idParam = cmd.Parameters[0] as IDbDataParameter; + var dataParam = cmd.Parameters[1] as IDbDataParameter; + + //MySql auto sets param size based on value + Assert.That(idParam.Size, Is.EqualTo(stringConverter.StringLength) + .Or.EqualTo(Math.Min((idParam.Value as string).Length, stringConverter.StringLength)) + ); + Assert.That(dataParam.Size, Is.EqualTo(310) + .Or.EqualTo(Math.Min((dataParam.Value as string).Length, stringConverter.StringLength)) + ); + }) == 1; + + Assert.That(exists); + + key = db.SingleById(id); + Assert.That(key.Data, Is.EqualTo(updatedData)); + + stringConverter.StringLength = hold; + } + } + } + + +} + diff --git a/tests/ServiceStack.OrmLite.Tests/app.config b/tests/ServiceStack.OrmLite.Tests/app.config deleted file mode 100644 index 32b55ead0..000000000 --- a/tests/ServiceStack.OrmLite.Tests/app.config +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/ServiceStack.OrmLite.TestsPerf/PerfTests/NorthwindPerfTests.cs b/tests/ServiceStack.OrmLite.TestsPerf/PerfTests/NorthwindPerfTests.cs index f33dc6aa7..e174ab218 100644 --- a/tests/ServiceStack.OrmLite.TestsPerf/PerfTests/NorthwindPerfTests.cs +++ b/tests/ServiceStack.OrmLite.TestsPerf/PerfTests/NorthwindPerfTests.cs @@ -4,7 +4,7 @@ namespace ServiceStack.OrmLite.TestsPerf.PerfTests { - [Ignore] + [Ignore("")] [TestFixture] public class NorthwindPerfTests : OrmLitePerfTests diff --git a/tests/ServiceStack.OrmLite.TestsPerf/ServiceStack.OrmLite.TestsPerf.csproj b/tests/ServiceStack.OrmLite.TestsPerf/ServiceStack.OrmLite.TestsPerf.csproj index f8b942378..e38a313bb 100644 --- a/tests/ServiceStack.OrmLite.TestsPerf/ServiceStack.OrmLite.TestsPerf.csproj +++ b/tests/ServiceStack.OrmLite.TestsPerf/ServiceStack.OrmLite.TestsPerf.csproj @@ -1,216 +1,47 @@ - - + + - Debug - AnyCPU - 9.0.30729 - 2.0 - {24E0D2DB-1F1E-43BE-83DB-B999ACE5A700} - Exe - Properties - ServiceStack.OrmLite.TestsPerf + net45 ServiceStack.OrmLite.TestsPerf - v4.0 - 512 - - - 3.5 - - false - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - + ServiceStack.OrmLite.TestsPerf + false + false + false + false + false + false + false + false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - AllRules.ruleset - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - AllRules.ruleset - - - bin\Signed\ - TRACE - true - pdbonly - x86 - prompt - AllRules.ruleset - - - - - 3.5 - - - 3.5 - - - - 3.0 - - - 3.5 - - - 3.5 - - - - - ..\..\lib\tests\Mono.Data.Sqlite.dll - - - ..\..\lib\tests\Northwind.Common.dll - - - ..\..\lib\tests\Northwind.Perf.dll - - - ..\..\lib\tests\nunit.framework.dll - - - ..\..\lib\tests\Platform.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\tests\ServiceStack.Common.Tests.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - Code - - - - Code - - - - - - True - True - Settings.settings - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - + - - {CF68A37D-D071-469D-AE04-68594CB95382} - ServiceStack.OrmLite.Sqlite - - - {1887DC99-9139-43E3-A7AA-6D74714B3A5D} - ServiceStack.OrmLite.SqlServer - - - {96179AC6-F6F1-40C3-9FDD-4F6582F54C5C} - ServiceStack.OrmLite - + + + + + - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - SQL Server 2008 Express - true - - - False - Windows Installer 3.1 - true - - - False - Windows Installer 4.5 - true - - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - + + + $(DefineConstants);NET45 + + + + + + + + + + + + + + + + + + - - - \ No newline at end of file + + diff --git a/tests/ServiceStack.OrmLiteV45.Tests/ApiMySqlTestsAsync.cs b/tests/ServiceStack.OrmLiteV45.Tests/ApiMySqlTestsAsync.cs deleted file mode 100644 index 2307e3c03..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/ApiMySqlTestsAsync.cs +++ /dev/null @@ -1,355 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests.Shared; - -namespace ServiceStack.OrmLite.Tests -{ - public class ApiMySqlTestsAsync - : OrmLiteTestBase - { - private IDbConnection db; - - [SetUp] - public void SetUp() - { - SuppressIfOracle("MySql tests"); - db = CreateMySqlDbFactory().OpenDbConnection(); - db.DropAndCreateTable(); - db.DropAndCreateTable(); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - - [Test] - public async Task API_MySql_Examples_Async() - { - await db.InsertAsync(Person.Rockstars); - - await db.SelectAsync(x => x.Age > 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > 40)")); - - await db.SelectAsync(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > 40)\nORDER BY `Id`")); - - await db.SelectAsync(q => q.Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > 40)")); - - await db.SelectAsync(db.From().Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` > 40)")); - - await db.SingleAsync(x => x.Age == 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` = 42)\nLIMIT 1")); - - await db.SingleAsync(q => q.Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` = 42)\nLIMIT 1")); - - await db.SingleAsync(db.From().Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` \nFROM `Person`\nWHERE (`Age` = 42)\nLIMIT 1")); - - await db.ScalarAsync(x => Sql.Max(x.Age)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(`Age`) \nFROM `Person`")); - - await db.ScalarAsync(x => Sql.Max(x.Age), x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(`Age`) \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.CountAsync(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.CountAsync(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < 50)")); - - - await db.SelectAsync("Age > 40"); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > 40")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > 40"); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - - await db.SelectAsync("Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @age")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - - await db.SelectAsync("Age > @age", new Dictionary { { "age", 40 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @age")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - - await db.SelectFmtAsync("Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > 40")); - - await db.SelectFmtAsync("SELECT * FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - - await db.SelectAsync(typeof(Person)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id` FROM `Person`")); - - await db.SelectFmtAsync(typeof(Person), "Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id` FROM `Person` WHERE Age > 40")); - - await db.WhereAsync("Age", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); - - await db.WhereAsync(new { Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); - - await db.SelectByIdsAsync(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` IN (1,2,3)")); - - await db.SelectNonDefaultsAsync(new Person { Id = 1 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` = @Id")); - - await db.SelectNonDefaultsAsync("Age > @Age", new Person { Age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @Age")); - - //await db.SelectLazy().ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person`")); - - //db.SelectLazy("Age > @age", new { age = 40 }).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > @age")); - - //db.SelectLazyFmt("Age > {0}", 40).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age > 40")); - - //db.WhereLazy(new { Age = 27 }).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); - - await db.SingleByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` = @Id")); - - await db.SingleAsync(new { Age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); - - await db.SingleAsync("Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = @age")); - - await db.SingleFmtAsync("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = 42")); - - await db.SingleByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Id` = @Id")); - - await db.SingleWhereAsync("Age", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); - - await db.ScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` > 40)")); - await db.ScalarAsync(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM `Person`\nWHERE (`Age` > 40)")); - - await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); - - await db.ScalarFmtAsync("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); - - await db.ColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `LastName` \nFROM `Person`\nWHERE (`Age` = 27)")); - - await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); - - await db.ColumnFmtAsync("SELECT LastName FROM Person WHERE Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); - - await db.ColumnDistinctAsync(db.From().Select(x => x.Age).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Age` \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); - - await db.ColumnDistinctFmtAsync("SELECT Age FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); - - await db.LookupAsync(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Age`,`LastName` \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); - - await db.LookupFmtAsync("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); - - await db.DictionaryAsync(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`,`LastName` \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); - - await db.DictionaryFmtAsync("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); - - await db.ExistsAsync(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.ExistsAsync(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.ExistsAsync(new { Age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE `Age` = @Age")); - - await db.ExistsAsync("Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = @age")); - await db.ExistsAsync("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); - - await db.ExistsFmtAsync("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `Id`, `FirstName`, `LastName`, `Age` FROM `Person` WHERE Age = 42")); - await db.ExistsFmtAsync("SELECT * FROM Person WHERE Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); - - await db.SqlListAsync(db.From().Select("*").Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); - - await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); - - await db.SqlColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT `LastName` \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); - - await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); - - await db.SqlScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM `Person`\nWHERE (`Age` < 50)")); - - await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - - await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - - var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); - - rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); - - - await db.InsertAsync(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); - - await db.InsertAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, - new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); - - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); - - - await db.InsertAllAsync(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); - - await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `PersonWithAutoId` (`FirstName`,`Age`) VALUES ('Amy',27)")); - - await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => db.From().Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `PersonWithAutoId` (`FirstName`,`Age`) VALUES ('Amy',27)")); - - await db.UpdateAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); - - await db.UpdateAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur3", Age = 27 }, - new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur4", Age = 28 }); - - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); - - await db.UpdateAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); - - await db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); - - await db.UpdateAsync(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `Id`=1, `FirstName`='JJ', `LastName`=NULL, `Age`=27 WHERE (`LastName` = 'Hendrix')")); - - await db.UpdateAsync(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`='JJ' WHERE (`LastName` = 'Hendrix')")); - - await db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`='JJ' WHERE (`LastName` = 'Hendrix')")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`='JJ'")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`='JJ' WHERE (`LastName` = 'Hendrix')")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`='JJ'")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`='JJ' WHERE (`FirstName` = 'Jimi')")); - - await db.UpdateFmtAsync(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); - - await db.UpdateFmtAsync(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); - - await db.DeleteAsync(new { FirstName = "Jimi", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `FirstName`=@FirstName AND `Age`=@Age")); - - await db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `Id`=@Id AND `FirstName`=@FirstName AND `LastName`=@LastName AND `Age`=@Age")); - - await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `FirstName`=@FirstName AND `Age`=@Age")); - - await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, - new Person { FirstName = "Janis", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `FirstName`=@FirstName AND `Age`=@Age")); - - await db.DeleteByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `Id` = @0")); - - await db.DeleteByIdsAsync(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE `Id` IN (1,2,3)")); - - await db.DeleteFmtAsync("Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); - - await db.DeleteFmtAsync(typeof(Person), "Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); - - await db.DeleteAsync(p => p.Age == 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE (`Age` = 27)")); - - await db.DeleteAsync(q => q.Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE (`Age` = 27)")); - - await db.DeleteAsync(db.From().Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE (`Age` = 27)")); - - await db.DeleteFmtAsync(where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); - - await db.DeleteFmtAsync(table: "Person", where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM `Person` WHERE Age = 27")); - - await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO `Person` (`Id`,`FirstName`,`LastName`,`Age`) VALUES (@Id,@FirstName,@LastName,@Age)")); - await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE `Person` SET `FirstName`=@FirstName, `LastName`=@LastName, `Age`=@Age WHERE `Id`=@Id")); - - await db.SaveAsync(new Person { Id = 12, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, - new Person { Id = 13, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - - await db.SaveAllAsync(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, - new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); - } - - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/ApiSqlServerTestsAsync.cs b/tests/ServiceStack.OrmLiteV45.Tests/ApiSqlServerTestsAsync.cs deleted file mode 100644 index 0a0706c2f..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/ApiSqlServerTestsAsync.cs +++ /dev/null @@ -1,355 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests.Shared; - -namespace ServiceStack.OrmLite.Tests -{ - public class ApiSqlServerTestsAsync - : OrmLiteTestBase - { - private IDbConnection db; - - [SetUp] - public void SetUp() - { - SuppressIfOracle("SQL Server tests"); - db = CreateSqlServerDbFactory().OpenDbConnection(); - db.DropAndCreateTable(); - db.DropAndCreateTable(); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - - [Test] - public async Task API_SqlServer_Examples_Async() - { - await db.InsertAsync(Person.Rockstars); - - await db.SelectAsync(x => x.Age > 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.SelectAsync(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)\nORDER BY \"Id\"")); - - await db.SelectAsync(q => q.Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.SelectAsync(db.From().Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.SingleAsync(x => x.Age == 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)")); - - await db.SingleAsync(q => q.Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)")); - - await db.SingleAsync(db.From().Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT TOP 1 \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)")); - - await db.ScalarAsync(x => Sql.Max(x.Age)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"")); - - await db.ScalarAsync(x => Sql.Max(x.Age), x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.CountAsync(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.CountAsync(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - - await db.SelectAsync("Age > 40"); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > 40"); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - - await db.SelectAsync("Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - - await db.SelectAsync("Age > @age", new Dictionary { { "age", 40 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - - await db.SelectFmtAsync("Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - await db.SelectFmtAsync("SELECT * FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - - await db.SelectAsync(typeof(Person)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\"")); - - await db.SelectFmtAsync(typeof(Person), "Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); - - await db.WhereAsync("Age", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.WhereAsync(new { Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.SelectByIdsAsync(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); - - await db.SelectNonDefaultsAsync(new Person { Id = 1 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); - - await db.SelectNonDefaultsAsync("Age > @Age", new Person { Age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @Age")); - - //await db.SelectLazy().ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\"")); - - //db.SelectLazy("Age > @age", new { age = 40 }).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - - //db.SelectLazyFmt("Age > {0}", 40).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - //db.WhereLazy(new { Age = 27 }).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.SingleByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); - - await db.SingleAsync(new { Age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.SingleAsync("Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); - - await db.SingleFmtAsync("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); - - await db.SingleByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); - - await db.SingleWhereAsync("Age", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.ScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - await db.ScalarAsync(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); - - await db.ScalarFmtAsync("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); - - await db.ColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = 27)")); - - await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); - - await db.ColumnFmtAsync("SELECT LastName FROM Person WHERE Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); - - await db.ColumnDistinctAsync(db.From().Select(x => x.Age).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); - - await db.ColumnDistinctFmtAsync("SELECT Age FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); - - await db.LookupAsync(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); - - await db.LookupFmtAsync("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); - - await db.DictionaryAsync(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); - - await db.DictionaryFmtAsync("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); - - await db.ExistsAsync(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.ExistsAsync(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.ExistsAsync(new { Age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.ExistsAsync("Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); - await db.ExistsAsync("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); - - await db.ExistsFmtAsync("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); - await db.ExistsFmtAsync("SELECT * FROM Person WHERE Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); - - await db.SqlListAsync(db.From().Select("*").Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); - - await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); - - await db.SqlColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); - - await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); - - await db.SqlScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - - await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - - var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); - - rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); - - - await db.InsertAsync(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - - await db.InsertAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, - new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); - - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - - - await db.InsertAllAsync(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - - await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); - - await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => db.From().Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); - - await db.UpdateAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur3", Age = 27 }, - new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur4", Age = 28 }); - - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAsync(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=1, \"FirstName\"='JJ', \"LastName\"=NULL, \"Age\"=27 WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateAsync(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"FirstName\" = 'Jimi')")); - - await db.UpdateFmtAsync(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); - - await db.UpdateFmtAsync(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); - - await db.DeleteAsync(new { FirstName = "Jimi", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); - - await db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\"=@Id AND \"FirstName\"=@FirstName AND \"LastName\"=@LastName AND \"Age\"=@Age")); - - await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); - - await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, - new Person { FirstName = "Janis", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); - - await db.DeleteByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" = @0")); - - await db.DeleteByIdsAsync(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); - - await db.DeleteFmtAsync("Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.DeleteFmtAsync(typeof(Person), "Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.DeleteAsync(p => p.Age == 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - await db.DeleteAsync(q => q.Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - await db.DeleteAsync(db.From().Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - await db.DeleteFmtAsync(where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.DeleteFmtAsync(table: "Person", where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.SaveAsync(new Person { Id = 12, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, - new Person { Id = 13, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - - await db.SaveAllAsync(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, - new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); - } - - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/ApiSqliteTestsAsync.cs b/tests/ServiceStack.OrmLiteV45.Tests/ApiSqliteTestsAsync.cs deleted file mode 100644 index 47a45ef35..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/ApiSqliteTestsAsync.cs +++ /dev/null @@ -1,354 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests.Shared; - -namespace ServiceStack.OrmLite.Tests -{ - public class ApiSqliteTestsAsync - : OrmLiteTestBase - { - private IDbConnection db; - - [SetUp] - public void SetUp() - { - db = CreateSqliteMemoryDbFactory().OpenDbConnection(); - db.DropAndCreateTable(); - db.DropAndCreateTable(); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - - [Test] - public async Task API_Sqlite_Examples_Async() - { - await db.InsertAsync(Person.Rockstars); - - await db.SelectAsync(x => x.Age > 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.SelectAsync(q => q.Where(x => x.Age > 40).OrderBy(x => x.Id)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)\nORDER BY \"Id\"")); - - await db.SelectAsync(q => q.Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.SelectAsync(db.From().Where(x => x.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.SingleAsync(x => x.Age == 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)\nLIMIT 1")); - - await db.SingleAsync(q => q.Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)\nLIMIT 1")); - - await db.SingleAsync(db.From().Where(x => x.Age == 42)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" = 42)\nLIMIT 1")); - - await db.ScalarAsync(x => Sql.Max(x.Age)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"")); - - await db.ScalarAsync(x => Sql.Max(x.Age), x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Max(\"Age\") \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.CountAsync(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.CountAsync(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - - await db.SelectAsync("Age > 40"); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > 40"); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - - await db.SelectAsync("Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - - await db.SelectAsync("Age > @age", new Dictionary { { "age", 40 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - - await db.SelectAsync("SELECT * FROM Person WHERE Age > @age", new Dictionary { { "age", 40 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > @age")); - - await db.SelectFmtAsync("Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - await db.SelectFmtAsync("SELECT * FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age > 40")); - - await db.SelectAsync(typeof(Person)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\"")); - - await db.SelectFmtAsync(typeof(Person), "Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\" FROM \"Person\" WHERE Age > 40")); - - await db.WhereAsync("Age", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.WhereAsync(new { Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.SelectByIdsAsync(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); - - await db.SelectNonDefaultsAsync(new Person { Id = 1 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); - - await db.SelectNonDefaultsAsync("Age > @Age", new Person { Age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @Age")); - - //await db.SelectLazy().ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\"")); - - //db.SelectLazy("Age > @age", new { age = 40 }).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > @age")); - - //db.SelectLazyFmt("Age > {0}", 40).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age > 40")); - - //db.WhereLazy(new { Age = 27 }).ToList(); - //Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.SingleByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); - - await db.SingleAsync(new { Age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.SingleAsync("Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); - - await db.SingleFmtAsync("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); - - await db.SingleByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Id\" = @Id")); - - await db.SingleWhereAsync("Age", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.ScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - await db.ScalarAsync(db.From().Select(x => Sql.Count("*")).Where(q => q.Age > 40)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Count(*) \nFROM \"Person\"\nWHERE (\"Age\" > 40)")); - - await db.ScalarAsync("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > @age")); - - await db.ScalarFmtAsync("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age > 40")); - - await db.ColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" = 27)")); - - await db.ColumnAsync("SELECT LastName FROM Person WHERE Age = @age", new { age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = @age")); - - await db.ColumnFmtAsync("SELECT LastName FROM Person WHERE Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age = 27")); - - await db.ColumnDistinctAsync(db.From().Select(x => x.Age).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.ColumnDistinctAsync("SELECT Age FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < @age")); - - await db.ColumnDistinctFmtAsync("SELECT Age FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age FROM Person WHERE Age < 50")); - - await db.LookupAsync(db.From().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Age\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.LookupAsync("SELECT Age, LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < @age")); - - await db.LookupFmtAsync("SELECT Age, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Age, LastName FROM Person WHERE Age < 50")); - - await db.DictionaryAsync(db.From().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\",\"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.DictionaryAsync("SELECT Id, LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < @age")); - - await db.DictionaryFmtAsync("SELECT Id, LastName FROM Person WHERE Age < {0}", 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT Id, LastName FROM Person WHERE Age < 50")); - - await db.ExistsAsync(x => x.Age < 50); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.ExistsAsync(db.From().Where(x => x.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.ExistsAsync(new { Age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE \"Age\" = @Age")); - - await db.ExistsAsync("Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = @age")); - await db.ExistsAsync("SELECT * FROM Person WHERE Age = @age", new { age = 42 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = @age")); - - await db.ExistsFmtAsync("Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"Id\", \"FirstName\", \"LastName\", \"Age\" FROM \"Person\" WHERE Age = 42")); - await db.ExistsFmtAsync("SELECT * FROM Person WHERE Age = {0}", 42); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age = 42")); - - await db.SqlListAsync(db.From().Select("*").Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); - - await db.SqlListAsync("SELECT * FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT * FROM Person WHERE Age < @age")); - - await db.SqlColumnAsync(db.From().Select(x => x.LastName).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT \"LastName\" \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); - - await db.SqlColumnAsync("SELECT LastName FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT LastName FROM Person WHERE Age < @age")); - - await db.SqlScalarAsync(db.From().Select(Sql.Count("*")).Where(q => q.Age < 50)); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) \nFROM \"Person\"\nWHERE (\"Age\" < 50)")); - - await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - - await db.SqlScalarAsync("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary { { "age", 50 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("SELECT COUNT(*) FROM Person WHERE Age < @age")); - - var rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName='WaterHouse' WHERE Id=7")); - - rowsAffected = await db.ExecuteNonQueryAsync("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE Person SET LastName=@name WHERE Id=@id")); - - - await db.InsertAsync(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - - await db.InsertAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur", Age = 25 }, - new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur2", Age = 26 }); - - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - - - await db.InsertAllAsync(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - - await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => q.Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); - - await db.InsertOnlyAsync(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, q => db.From().Insert(p => new { p.FirstName, p.Age })); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"PersonWithAutoId\" (\"FirstName\",\"Age\") VALUES ('Amy',27)")); - - await db.UpdateAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAsync(new Person { Id = 8, FirstName = "Tupac", LastName = "Shakur3", Age = 27 }, - new Person { Id = 9, FirstName = "Tupac", LastName = "Shakur4", Age = 28 }); - - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAllAsync(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.UpdateAsync(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"Id\"=1, \"FirstName\"='JJ', \"LastName\"=NULL, \"Age\"=27 WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateAsync(new { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateNonDefaultsAsync(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix"); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"LastName\" = 'Hendrix')")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ", LastName = "Hendo" }, q => q.Update(p => p.FirstName)); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ'")); - - await db.UpdateOnlyAsync(new Person { FirstName = "JJ" }, q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"='JJ' WHERE (\"FirstName\" = 'Jimi')")); - - await db.UpdateFmtAsync(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); - - await db.UpdateFmtAsync(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix")); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET FirstName = 'JJ' WHERE LastName = 'Hendrix'")); - - await db.DeleteAsync(new { FirstName = "Jimi", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); - - await db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\"=@Id AND \"FirstName\"=@FirstName AND \"LastName\"=@LastName AND \"Age\"=@Age")); - - await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); - - await db.DeleteNonDefaultsAsync(new Person { FirstName = "Jimi", Age = 27 }, - new Person { FirstName = "Janis", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"FirstName\"=@FirstName AND \"Age\"=@Age")); - - await db.DeleteByIdAsync(1); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" = @0")); - - await db.DeleteByIdsAsync(new[] { 1, 2, 3 }); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE \"Id\" IN (1,2,3)")); - - await db.DeleteFmtAsync("Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.DeleteFmtAsync(typeof(Person), "Age = {0}", 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.DeleteAsync(p => p.Age == 27); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - await db.DeleteAsync(q => q.Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - await db.DeleteAsync(db.From().Where(p => p.Age == 27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE (\"Age\" = 27)")); - - await db.DeleteFmtAsync(where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.DeleteFmtAsync(table: "Person", where: "Age = {0}".SqlFmt(27)); - Assert.That(db.GetLastSql(), Is.EqualTo("DELETE FROM \"Person\" WHERE Age = 27")); - - await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("INSERT INTO \"Person\" (\"Id\",\"FirstName\",\"LastName\",\"Age\") VALUES (@Id,@FirstName,@LastName,@Age)")); - await db.SaveAsync(new Person { Id = 11, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - Assert.That(db.GetLastSql(), Is.EqualTo("UPDATE \"Person\" SET \"FirstName\"=@FirstName, \"LastName\"=@LastName, \"Age\"=@Age WHERE \"Id\"=@Id")); - - await db.SaveAsync(new Person { Id = 12, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, - new Person { Id = 13, FirstName = "Amy", LastName = "Winehouse", Age = 27 }); - - await db.SaveAllAsync(new[]{ new Person { Id = 14, FirstName = "Amy", LastName = "Winehouse", Age = 27 }, - new Person { Id = 15, FirstName = "Amy", LastName = "Winehouse", Age = 27 } }); - } - - } -} diff --git a/tests/ServiceStack.OrmLiteV45.Tests/App.config b/tests/ServiceStack.OrmLiteV45.Tests/App.config deleted file mode 100644 index 5bc1578a3..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/App.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/AsyncTests.cs b/tests/ServiceStack.OrmLiteV45.Tests/AsyncTests.cs deleted file mode 100644 index fb2945a56..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/AsyncTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; -using ServiceStack.Text; - -using ServiceStack.OrmLite.Tests.Shared; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class AsyncTests - : OrmLiteTestBase - { - [Test] - public async Task Can_Insert_and_SelectAsync() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - for (var i = 0; i < 3; i++) - { - await db.InsertAsync(new Poco { Name = ((char)('A' + i)).ToString() }); - } - - var results = (await db.SelectAsync()).Map(x => x.Name); - Assert.That(results, Is.EqualTo(new[] { "A", "B", "C" })); - - results = (await db.SelectAsync(x => x.Name == "A")).Map(x => x.Name); - Assert.That(results, Is.EqualTo(new[] { "A" })); - - results = (await db.SelectAsync(q => q.Where(x => x.Name == "A"))).Map(x => x.Name); - Assert.That(results, Is.EqualTo(new[] { "A" })); - } - } - - [Test] - public async Task Test_Thread_Affinity() - { - var delayMs = 100; - var db = OpenDbConnection(); - - "Root: {0}".Print(Thread.CurrentThread.ManagedThreadId); - var task = Task.Factory.StartNew(() => - { - "Before Delay: {0}".Print(Thread.CurrentThread.ManagedThreadId); - return Task.Delay(delayMs); - }) - .Then(async t => - { - "After Delay: {0}".Print(Thread.CurrentThread.ManagedThreadId); - await Task.Delay(delayMs); - }) - .Then(async t => - { - "Before SQL: {0}".Print(Thread.CurrentThread.ManagedThreadId); - await db.ExistsAsync(x => x.Age < 50) - .Then(t1 => { - "After SQL: {0}".Print(Thread.CurrentThread.ManagedThreadId); - return Task.Delay(delayMs); - }); - }) - .Then(async inner => - { - "Before Inner: {0}".Print(Thread.CurrentThread.ManagedThreadId); - await Task.Delay(delayMs); - "After Inner: {0}".Print(Thread.CurrentThread.ManagedThreadId); - }); - - await task; - "Await t: {0}".Print(Thread.CurrentThread.ManagedThreadId); - } - } -} diff --git a/tests/ServiceStack.OrmLiteV45.Tests/LoadReferencesTests.cs b/tests/ServiceStack.OrmLiteV45.Tests/LoadReferencesTests.cs deleted file mode 100644 index 5b1a0497e..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/LoadReferencesTests.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.OrmLite.Tests.UseCase; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.Tests -{ - public class Customer - { - [AutoIncrement] - public int Id { get; set; } - public string Name { get; set; } - - [Reference] - public CustomerAddress PrimaryAddress { get; set; } - - [Reference] - public List Orders { get; set; } - } - - public class CustomerAddress - { - [AutoIncrement] - public int Id { get; set; } - public int CustomerId { get; set; } - public string AddressLine1 { get; set; } - public string AddressLine2 { get; set; } - public string City { get; set; } - public string State { get; set; } - public string Country { get; set; } - } - - public class Order - { - [AutoIncrement] - public int Id { get; set; } - public int CustomerId { get; set; } - public string LineItem { get; set; } - public int Qty { get; set; } - public decimal Cost { get; set; } - } - - public class Country - { - [AutoIncrement] - public int Id { get; set; } - public string CountryName { get; set; } - public string CountryCode { get; set; } - } - - public class LoadReferencesTests - : OrmLiteTestBase - { - private IDbConnection db; - - [TestFixtureSetUp] - public new void TestFixtureSetUp() - { - db = base.OpenDbConnection(); - CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table - - db.DropAndCreateTable(); - db.DropAndCreateTable(); - db.DropAndCreateTable(); - db.DropAndCreateTable(); - } - - [SetUp] - public void SetUp() - { - db.DeleteAll(); - db.DeleteAll(); - db.DeleteAll(); - } - - [TestFixtureTearDown] - public void TestFixtureTearDown() - { - db.Dispose(); - } - - public static Customer GetCustomerWithOrders(string id = "1") - { - var customer = new Customer - { - Name = "Customer " + id, - PrimaryAddress = new CustomerAddress - { - AddressLine1 = id + " Humpty Street", - City = "Humpty Doo", - State = "Northern Territory", - Country = "Australia" - }, - Orders = new[] - { - new Order {LineItem = "Line 1", Qty = 1, Cost = 1.99m}, - new Order {LineItem = "Line 2", Qty = 2, Cost = 2.99m}, - }.ToList(), - }; - return customer; - } - - [Test] - public async Task Can_Save_and_Load_References_Async() - { - var customer = new Customer - { - Name = "Customer 1", - PrimaryAddress = new CustomerAddress - { - AddressLine1 = "1 Humpty Street", - City = "Humpty Doo", - State = "Northern Territory", - Country = "Australia" - }, - Orders = new[] { - new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m }, - new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m }, - }.ToList(), - }; - - await db.SaveAsync(customer); - - Assert.That(customer.Id, Is.GreaterThan(0)); - Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(0)); - - await db.SaveReferencesAsync(customer, customer.PrimaryAddress); - Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(customer.Id)); - - await db.SaveReferencesAsync(customer, customer.Orders); - Assert.That(customer.Orders.All(x => x.CustomerId == customer.Id)); - - var dbCustomer = await db.LoadSingleByIdAsync(customer.Id); - - dbCustomer.PrintDump(); - - Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null); - Assert.That(dbCustomer.Orders.Count, Is.EqualTo(2)); - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/OrmLiteContextTests.cs b/tests/ServiceStack.OrmLiteV45.Tests/OrmLiteContextTests.cs deleted file mode 100644 index b769fd897..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/OrmLiteContextTests.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.Common.Tests.Models; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.Tests -{ - [TestFixture] - public class OrmLiteContextTests - : OrmLiteTestBase - { - [Test] - public void Can_set_and_get_TS_ContextItems() - { - OrmLiteConfig.ResultsFilter = new CaptureSqlFilter(); - OrmLiteConfig.ResultsFilter = null; - } - - [Test] - public void Can_override_timeout_for_specific_command() - { - base.DbFactory.AutoDisposeConnection = true; //Turn off :memory: re-use of dbConn - - OrmLiteConfig.CommandTimeout = 100; - - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); - - db.SetCommandTimeout(666); - - "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); - - ThreadPool.QueueUserWorkItem(_ => - { - using (var dbInner = OpenDbConnection()) - { - "inner {0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); - dbInner.SetCommandTimeout(1); - } - }); - Thread.Sleep(10); - - "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); - - db.Insert(new Poco { Name = "Foo" }); - db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(666))); - } - - using (var db = OpenDbConnection()) - { - db.CreateTableIfNotExists(); //Sqlite :memory: AutoDisposeConnection = true - db.Select().PrintDump(); - db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); - } - } - - [Test] - public async Task Can_override_timeout_for_specific_command_Async() - { - base.DbFactory.AutoDisposeConnection = true; //Turn off :memory: re-use of dbConn - - OrmLiteConfig.CommandTimeout = 100; - - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); - - db.SetCommandTimeout(666); - - "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); - - ThreadPool.QueueUserWorkItem(_ => - { - using (var dbInner = OpenDbConnection()) - { - "inner {0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); - dbInner.SetCommandTimeout(1); - } - }); - Thread.Sleep(10); - - "{0}:{1}".Print(OrmLiteContext.OrmLiteState, Thread.CurrentThread.ManagedThreadId); - - await db.InsertAsync(new Poco { Name = "Foo" }); - db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(666))); - } - - using (var db = OpenDbConnection()) - { - db.CreateTableIfNotExists(); //Sqlite :memory: AutoDisposeConnection = true - (await db.SelectAsync()).PrintDump(); - db.Exec(cmd => Assert.That(cmd.CommandTimeout, Is.EqualTo(100))); - } - } - - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/OrmLiteTestBase.cs b/tests/ServiceStack.OrmLiteV45.Tests/OrmLiteTestBase.cs deleted file mode 100644 index 127008d85..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/OrmLiteTestBase.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Data; -using System.Data.Common; -using System.IO; -using NUnit.Framework; -using ServiceStack.Logging; - -namespace ServiceStack.OrmLite.Tests -{ - public class Config - { - public static string SqliteMemoryDb = ":memory:"; - public static string SqliteFileDir = "~/App_Data/".MapAbsolutePath(); - public static string SqliteFileDb = "~/App_Data/db.sqlite".MapAbsolutePath(); - public static string SqlServerDb = "~/App_Data/Database1.mdf".MapAbsolutePath(); - public static string SqlServerBuildDb = "Server={0};Database=test;User Id=test;Password=test;".Fmt(Environment.GetEnvironmentVariable("CI_HOST")); - //public static string SqlServerBuildDb = "Data Source=localhost;Initial Catalog=TestDb;Integrated Security=SSPI;Connect Timeout=120;MultipleActiveResultSets=True"; - - public static string MySqlDb = "Server={0};Database=test;UID=root;Password=test".Fmt(Environment.GetEnvironmentVariable("CI_HOST")); - - public static IOrmLiteDialectProvider DefaultProvider = SqlServerDialect.Provider; - public static string DefaultConnection = SqlServerBuildDb; - - public static string GetDefaultConnection() - { - OrmLiteConfig.DialectProvider = DefaultProvider; - return DefaultConnection; - } - - public static IDbConnection OpenDbConnection() - { - return GetDefaultConnection().OpenDbConnection(); - } - } - - public class OrmLiteTestBase - { - protected virtual string ConnectionString { get; set; } - - public OrmLiteTestBase() {} - - public OrmLiteTestBase(Dialect dialect) - { - Dialect = dialect; - Init(); - } - - protected string GetConnectionString() - { - return GetFileConnectionString(); - } - - public static OrmLiteConnectionFactory CreateSqliteMemoryDbFactory() - { - var dbFactory = new OrmLiteConnectionFactory(Config.SqliteMemoryDb, SqliteDialect.Provider); - return dbFactory; - } - - public static OrmLiteConnectionFactory CreateSqlServerDbFactory() - { - var dbFactory = new OrmLiteConnectionFactory(Config.SqlServerBuildDb, SqlServerDialect.Provider); - return dbFactory; - } - - public static OrmLiteConnectionFactory CreateMySqlDbFactory() - { - var dbFactory = new OrmLiteConnectionFactory(Config.MySqlDb, MySqlDialect.Provider); - return dbFactory; - } - - protected virtual string GetFileConnectionString() - { - var connectionString = Config.SqliteFileDb; - if (File.Exists(connectionString)) - File.Delete(connectionString); - - return connectionString; - } - - protected void CreateNewDatabase() - { - if (ConnectionString.Contains(".sqlite")) - ConnectionString = GetFileConnectionString(); - } - - public Dialect Dialect = Dialect.SqlServer; - protected OrmLiteConnectionFactory DbFactory; - - OrmLiteConnectionFactory Init(string connStr, IOrmLiteDialectProvider dialectProvider) - { - ConnectionString = connStr; - OrmLiteConfig.DialectProvider = dialectProvider; - DbFactory = new OrmLiteConnectionFactory(ConnectionString, dialectProvider); - return DbFactory; - } - - [TestFixtureSetUp] - public void TestFixtureSetUp() - { - Init(); - } - - private OrmLiteConnectionFactory Init() - { - LogManager.LogFactory = new ConsoleLogFactory(debugEnabled: false); - - switch (Dialect) - { - case Dialect.Sqlite: - var dbFactory = Init(Config.SqliteMemoryDb, SqliteDialect.Provider); - dbFactory.AutoDisposeConnection = false; - return dbFactory; - case Dialect.SqlServer: - return Init(Config.SqlServerBuildDb, SqlServerDialect.Provider); - case Dialect.MySql: - return Init(Config.MySqlDb, MySqlDialect.Provider); - } - - throw new NotImplementedException("{0}".Fmt(Dialect)); - } - - public void Log(string text) - { - Console.WriteLine(text); - } - - public IDbConnection InMemoryDbConnection { get; set; } - - public virtual IDbConnection OpenDbConnection() - { - if (ConnectionString == ":memory:") - { - if (InMemoryDbConnection == null || DbFactory.AutoDisposeConnection) - { - InMemoryDbConnection = new OrmLiteConnection(DbFactory); - InMemoryDbConnection.Open(); - } - return InMemoryDbConnection; - } - - return DbFactory.OpenDbConnection(); - } - - protected void SuppressIfOracle(string reason, params object[] args) - { - // Not Oracle if this base class used - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/Properties/AssemblyInfo.cs b/tests/ServiceStack.OrmLiteV45.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 018795b45..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ServiceStack.OrmLiteV45.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ServiceStack.OrmLiteV45.Tests")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("67b8c26d-1df2-43f1-98b4-a70a3470f405")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/ServiceStack.OrmLiteV45.Tests/SelectAsyncTests.cs b/tests/ServiceStack.OrmLiteV45.Tests/SelectAsyncTests.cs deleted file mode 100644 index 4330af6c5..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/SelectAsyncTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Threading.Tasks; -using AppDb; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace ServiceStack.OrmLite.Tests -{ - public class PocoWithBytes : IHasGuidId - { - [PrimaryKey] - public Guid Id { get; set; } - - public byte[] Image { get; set; } - - public string ContentType { get; set; } - } - - [TestFixture] - public class SelectAsyncTests - : OrmLiteTestBase - { - [Test] - public async Task Can_SELECT_SingleAsync() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - await db.InsertAsync(new Poco { Id = "foo" }); - - var row = await db.SingleAsync(db.From().Where(x => x.Id == "foo")); - - Assert.That(row.Id, Is.EqualTo("foo")); - } - } - - [Test] - public async Task Can_SELECT_SingleAsyncForStrangeClass() - { - using (var db = OpenDbConnection()) - { - db.DropAndCreateTable(); - - var bar = new PocoWithBytes { Id = Guid.NewGuid(), Image = new byte[1024 * 1024], ContentType = "image/jpeg" }; - await db.InsertAsync(bar); - - var blah = await db.SingleAsync(db.From().Where(x => x.Id == bar.Id)); - Assert.That(blah, Is.Not.Null); - } - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/ServiceStack.OrmLiteV45.Tests.csproj b/tests/ServiceStack.OrmLiteV45.Tests/ServiceStack.OrmLiteV45.Tests.csproj deleted file mode 100644 index 4177ac952..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/ServiceStack.OrmLiteV45.Tests.csproj +++ /dev/null @@ -1,152 +0,0 @@ - - - - - Debug - AnyCPU - {01ABABFF-FA2C-492A-9217-E83658BF6971} - Library - Properties - ServiceStack.OrmLite.Tests - ServiceStack.OrmLite.Tests - v4.5 - 512 - ..\..\src\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - - - - ..\..\lib\Mono.Security.dll - - - ..\..\src\packages\NUnit.2.6.3\lib\nunit.framework.dll - - - ..\..\lib\ServiceStack.dll - - - ..\..\lib\ServiceStack.Client.dll - - - ..\..\lib\ServiceStack.Common.dll - - - ..\..\lib\ServiceStack.Interfaces.dll - - - ..\..\lib\ServiceStack.Text.dll - - - - - - - - - - - - - - - - - - - - - - Code - - - Code - - - - True - True - OrmLite.Poco.tt - - - True - True - OrmLite.SP.tt - - - - - - - - {d1858737-fc4f-4432-8725-e5b79a13d5f6} - ServiceStack.OrmLite.MySqlV45 - - - {30c0c876-abcb-441b-bfd4-aa9f688d9e54} - ServiceStack.OrmLite.SqliteV45 - - - {6f851563-08f6-4692-89f8-f1d6c86f0069} - ServiceStack.OrmLite.SqlServerV45 - - - {fdc37335-9ecc-413b-bec5-16b466b0e689} - ServiceStack.OrmLiteV45 - - - - - - - - TextTemplatingFileGenerator - OrmLite.Poco.cs - - - TextTemplatingFileGenerator - OrmLite.SP.cs - - - - - sqlite3.dll - PreserveNewest - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/Shared/Person.cs b/tests/ServiceStack.OrmLiteV45.Tests/Shared/Person.cs deleted file mode 100644 index 6131cfd8e..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/Shared/Person.cs +++ /dev/null @@ -1,54 +0,0 @@ -using ServiceStack.DataAnnotations; - -namespace ServiceStack.OrmLite.Tests.Shared -{ - public class Person - { - public static Person[] Rockstars = new[] { - new Person(1, "Jimi", "Hendrix", 27), - new Person(2, "Janis", "Joplin", 27), - new Person(3, "Jim", "Morrisson", 27), - new Person(4, "Kurt", "Cobain", 27), - new Person(5, "Elvis", "Presley", 42), - new Person(6, "Michael", "Jackson", 50), - }; - - public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public int Age { get; set; } - - public Person() { } - public Person(int id, string firstName, string lastName, int age) - { - Id = id; - FirstName = firstName; - LastName = lastName; - Age = age; - } - } - - public class PersonWithAutoId - { - [AutoIncrement] - public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public int Age { get; set; } - } - - public class PersonWithNullableAutoId - { - [AutoIncrement] - public int? Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public int Age { get; set; } - } - - public class EntityWithId - { - public int Id { get; set; } - } - -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/Shared/Poco.cs b/tests/ServiceStack.OrmLiteV45.Tests/Shared/Poco.cs deleted file mode 100644 index 476cbb551..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/Shared/Poco.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ServiceStack.Common.Tests.Models -{ - public class Poco - { - public string Name { get; set; } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/SqlExpressionTests.cs b/tests/ServiceStack.OrmLiteV45.Tests/SqlExpressionTests.cs deleted file mode 100644 index 963f98749..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/SqlExpressionTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests.UseCase; -using ServiceStack.Text; - -namespace ServiceStack.OrmLite.Tests -{ - public class SqlExpressionTests - : OrmLiteTestBase - { - [Test] - public async Task Can_select_limit_on_Table_with_References_Async() - { - using (var db = OpenDbConnection()) - { - CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table - db.DropAndCreateTable(); - db.DropAndCreateTable(); - db.DropAndCreateTable(); - - var customer1 = LoadReferencesTests.GetCustomerWithOrders("1"); - db.Save(customer1, references: true); - - var customer2 = LoadReferencesTests.GetCustomerWithOrders("2"); - db.Save(customer2, references: true); - - var results = await db.LoadSelectAsync(q => q - .OrderBy(x => x.Id) - .Limit(1, 1)); - - //db.GetLastSql().Print(); - - Assert.That(results.Count, Is.EqualTo(1)); - Assert.That(results[0].Name, Is.EqualTo("Customer 2")); - Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street")); - Assert.That(results[0].Orders.Count, Is.EqualTo(2)); - - results = await db.LoadSelectAsync(q => q - .Join() - .OrderBy(x => x.Id) - .Limit(1, 1)); - - db.GetLastSql().Print(); - - Assert.That(results.Count, Is.EqualTo(1)); - Assert.That(results[0].Name, Is.EqualTo("Customer 2")); - Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street")); - Assert.That(results[0].Orders.Count, Is.EqualTo(2)); - } - } - - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Poco.cs b/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Poco.cs deleted file mode 100644 index b1f78ee5b..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Poco.cs +++ /dev/null @@ -1,2228 +0,0 @@ - -// This file was automatically generated by the PetaPoco T4 Template -// Do not make changes directly to this file - edit the template instead -// -// The following connection settings were used to generate this file -// -// Connection String Name: `AppDb` -// Provider: `System.Data.SqlClient` -// Connection String: `Server=localhost;Database=test;User Id=test;password=**zapped**;` -// Schema: `` -// Include Views: `False` - -// Factory Name: `SqlClientFactory` -// -// This file was generated by a T4 template. -// Don't change it directly as your change would get overwritten. Instead, make changes -// to the .tt file (i.e. the T4 template) and save it to regenerate this file. - -// Make sure the compiler doesn't complain about missing Xml comments -#pragma warning disable 1591 - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; - -using ServiceStack.OrmLite; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace AppDb -{ - [Alias("T05")] - [Schema("dbo")] - public partial class T05 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("ModelIntValue")] - [Schema("dbo")] - public partial class ModelIntValue : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public int? Value { get; set;} - public string Text { get; set;} - [Required] - public long LongMismatch { get; set;} - public int? LongMismatch2 { get; set;} - } - [Alias("Product")] - [Schema("dbo")] - public partial class Product : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string Name { get; set;} - [Required] - public decimal UnitPrice { get; set;} - } - [Alias("Fortune")] - [Schema("dbo")] - public partial class Fortune : IHasId - { - [Alias("id")] - [AutoIncrement] - public int Id { get; set;} - public string message { get; set;} - } - [Alias("T06")] - [Schema("dbo")] - public partial class T06 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("DbPoco")] - [Schema("dbo")] - public partial class DbPoco : IHasId - { - [Alias("Id_primary")] - [Required] - public string Id { get; set;} - public string Other_Id { get; set;} - } - [Alias("Customer")] - [Schema("dbo")] - public partial class Customer : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string FirstName { get; set;} - public string LastName { get; set;} - public string Email { get; set;} - public string PhoneNumbers { get; set;} - public string Addresses { get; set;} - [Required] - public DateTime CreatedAt { get; set;} - } - [Alias("DateTimeObject")] - [Schema("dbo")] - public partial class DateTimeObject : IHasId - { - [Alias("Test")] - [Required] - public DateTime Id { get; set;} - } - [Alias("T07")] - [Schema("dbo")] - public partial class T07 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("Note")] - [Schema("dbo")] - public partial class Note : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string SchemaUri { get; set;} - public string NoteText { get; set;} - public DateTime? LastUpdated { get; set;} - public string UpdatedBy { get; set;} - } - [Alias("ModelWithCompositeIndexFields")] - [Schema("dbo")] - public partial class ModelWithCompositeIndexField : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Name { get; set;} - public string AlbumId { get; set;} - public string UniqueName { get; set;} - public string Composite1 { get; set;} - public string Composite2 { get; set;} - } - [Alias("Order")] - [Schema("dbo")] - public partial class Order : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int CustomerId { get; set;} - [Required] - public int EmployeeId { get; set;} - public string ShippingAddress { get; set;} - public DateTime? OrderDate { get; set;} - public DateTime? RequiredDate { get; set;} - public DateTime? ShippedDate { get; set;} - public int? ShipVia { get; set;} - [Required] - public decimal Freight { get; set;} - [Required] - public decimal Total { get; set;} - } - [Alias("T08")] - [Schema("dbo")] - public partial class T08 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("ModelWithIndexFields")] - [Schema("dbo")] - public partial class ModelWithIndexField : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Name { get; set;} - public string AlbumId { get; set;} - public string UniqueName { get; set;} - } - [Alias("Shipper")] - [Schema("dbo")] - public partial class Shipper : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string CompanyName { get; set;} - public string Phone { get; set;} - [Required] - public int ShipperTypeId { get; set;} - } - [Alias("T09")] - [Schema("dbo")] - public partial class T09 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("ModelWithNamedCompositeIndex")] - [Schema("dbo")] - public partial class ModelWithNamedCompositeIndex : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Name { get; set;} - public string AlbumId { get; set;} - public string UniqueName { get; set;} - public string Composite1 { get; set;} - public string Composite2 { get; set;} - } - [Alias("OrderDetail")] - [Schema("dbo")] - public partial class OrderDetail : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int OrderId { get; set;} - [Required] - public int ProductId { get; set;} - [Required] - public decimal UnitPrice { get; set;} - [Required] - public int Quantity { get; set;} - [Required] - public decimal Discount { get; set;} - } - [Alias("Manufacturer")] - [Schema("dbo")] - public partial class Manufacturer : IHasId - { - [Alias("Id")] - [Required] - public Guid Id { get; set;} - public string Name { get; set;} - } - [Alias("T10")] - [Schema("dbo")] - public partial class T10 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("Addresses")] - [Schema("dbo")] - public partial class Address : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int UserId { get; set;} - public string City { get; set;} - public string Countryalias { get; set;} - } - [Alias("TableName")] - [Schema("dbo")] - public partial class TableName : IHasId - { - [Alias("TableId")] - [Required] - public int Id { get; set;} - [Required] - public long Long { get; set;} - [Required] - public Guid Guid { get; set;} - } - [Alias("T11")] - [Schema("dbo")] - public partial class T11 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("table_alias")] - [Schema("dbo")] - public partial class table_alias : IHasId - { - [Alias("id")] - [Required] - public string Id { get; set;} - public string column_alias { get; set;} - public string album_id { get; set;} - public string album_name { get; set;} - } - [Alias("TaskQueue")] - [Schema("dbo")] - public partial class TaskQueue : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public Guid? UserId { get; set;} - public string Task { get; set;} - public string ContentUrn { get; set;} - public string Status { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - [Required] - public int Priority { get; set;} - [Required] - public int NoOfAttempts { get; set;} - public string ErrorMessage { get; set;} - } - [Alias("Hello")] - [Schema("dbo")] - public partial class Hello : IHasId - { - [Alias("Name")] - [Required] - public string Id { get; set;} - } - [Alias("ModelWithRowVersionBase")] - [Schema("dbo")] - public partial class ModelWithRowVersionBase : IHasId - { - public string MoreData { get; set;} - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - public string Text { get; set;} - [Required] - public byte[] RowVersion { get; set;} - } - [Alias("Child")] - [Schema("dbo")] - public partial class Child : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string Value { get; set;} - } - [Alias("ModelWithRowVersion")] - [Schema("dbo")] - public partial class ModelWithRowVersion : IHasId - { - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - public string Text { get; set;} - [Required] - public byte[] RowVersion { get; set;} - } - [Alias("Parent")] - [Schema("dbo")] - public partial class Parent : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public int? ChildId { get; set;} - } - [Alias("Activity")] - [Schema("dbo")] - public partial class Activity : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public string ActivityType { get; set;} - public string Comment { get; set;} - } - [Alias("ModelWithRowVersionAlias")] - [Schema("dbo")] - public partial class ModelWithRowVersionAlias : IHasId - { - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - public string Text { get; set;} - [Required] - public byte[] VersionAlias { get; set;} - } - [Alias("TestRowVersion")] - [Schema("dbo")] - public partial class TestRowVersion : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - [Required] - public byte[] RowVersion { get; set;} - } - [Alias("Movie")] - [Schema("dbo")] - public partial class Movie : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Title { get; set;} - [Required] - public decimal Rating { get; set;} - public string Director { get; set;} - [Required] - public DateTime ReleaseDate { get; set;} - public string TagLine { get; set;} - public string Genres { get; set;} - } - [Alias("TestType")] - [Schema("dbo")] - public partial class TestType : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string TextCol { get; set;} - [Required] - public bool BoolCol { get; set;} - [Required] - public DateTime DateCol { get; set;} - [Required] - public string EnumCol { get; set;} - public string ComplexObjCol { get; set;} - } - [Alias("ModelWithRowVersionAndParent")] - [Schema("dbo")] - public partial class ModelWithRowVersionAndParent : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int ModelWithOptimisticChildrenId { get; set;} - public string Text { get; set;} - [Required] - public long Version { get; set;} - } - [Alias("ModelWithOptimisticChildren")] - [Schema("dbo")] - public partial class ModelWithOptimisticChild : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Text { get; set;} - } - [Alias("ReferencedType")] - [Schema("dbo")] - public partial class ReferencedType : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("Table2")] - [Schema("dbo")] - public partial class Table2 : IHasId - { - [Alias("Key")] - [AutoIncrement] - public int Id { get; set;} - public string Tri { get; set;} - [Required] - public int Table1 { get; set;} - } - [Alias("TypeWithOnDeleteAndUpdateCascade")] - [Schema("dbo")] - public partial class TypeWithOnDeleteAndUpdateCascade : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public int? RefId { get; set;} - } - [Alias("ShipperTypes")] - [Schema("dbo")] - public partial class ShipperType : IHasId - { - [Alias("ShipperTypeID")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public string Name { get; set;} - } - [Alias("Tabela1")] - [Schema("dbo")] - public partial class Tabela1 : IHasId - { - [Alias("Key")] - [AutoIncrement] - public int Id { get; set;} - public string Ena { get; set;} - } - [Alias("NullableActivity")] - [Schema("dbo")] - public partial class NullableActivity : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string ActivityType { get; set;} - public string Comment { get; set;} - } - [Alias("Table3")] - [Schema("dbo")] - public partial class Table3 : IHasId - { - [Alias("Key")] - [AutoIncrement] - public int Id { get; set;} - public string Tri { get; set;} - public int? TableTwoKey { get; set;} - } - [Alias("PersonWithNullableAutoId")] - [Schema("dbo")] - public partial class PersonWithNullableAutoId : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string FirstName { get; set;} - public string LastName { get; set;} - [Required] - public int Age { get; set;} - } - [Alias("tab_ModelWithIdAndName")] - [Schema("dbo")] - public partial class tab_ModelWithIdAndName : IHasId - { - [Alias("col_Id")] - [AutoIncrement] - public int Id { get; set;} - public string col_Name { get; set;} - } - [Alias("TypeWithOnDeleteRestrict")] - [Schema("dbo")] - public partial class TypeWithOnDeleteRestrict : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public int? RefId { get; set;} - } - [Alias("Tabela2")] - [Schema("dbo")] - public partial class Tabela2 : IHasId - { - [Alias("Key")] - [AutoIncrement] - public int Id { get; set;} - public string Tri { get; set;} - [Required] - public int Tabela1 { get; set;} - } - [Alias("CustomerAddress")] - [Schema("dbo")] - public partial class CustomerAddress : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int CustomerId { get; set;} - public string AddressLine1 { get; set;} - public string AddressLine2 { get; set;} - public string City { get; set;} - public string State { get; set;} - public string Country { get; set;} - } - [Alias("tab_ModelWithFieldsOfDifferentTypes")] - [Schema("dbo")] - public partial class tab_ModelWithFieldsOfDifferentType : IHasId - { - [Alias("col_Id")] - [AutoIncrement] - public int Id { get; set;} - public string col_Name { get; set;} - [Required] - public long col_LongId { get; set;} - [Required] - public Guid col_Guid { get; set;} - [Required] - public bool col_Bool { get; set;} - [Required] - public DateTime col_DateTime { get; set;} - [Required] - public double col_Double { get; set;} - } - [Alias("Country")] - [Schema("dbo")] - public partial class Country : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string CountryName { get; set;} - public string CountryCode { get; set;} - } - [Alias("TypeWithOnDeleteSetDefault")] - [Schema("dbo")] - public partial class TypeWithOnDeleteSetDefault : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int RefId { get; set;} - } - [Alias("Baz")] - [Schema("dbo")] - public partial class Baz : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public string Name { get; set;} - } - [Alias("MultipleConnection")] - [Schema("dbo")] - public partial class MultipleConnection : IHasId - { - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - public string Data { get; set;} - } - [Alias("ModelAliasWithSpace")] - [Schema("dbo")] - public partial class ModelAliasWithSpace : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Alias("The Name")] - public string The_Name { get; set;} - } - [Alias("LetterStat")] - [Schema("dbo")] - public partial class LetterStat : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public long LetterFrequencyId { get; set;} - public string Letter { get; set;} - [Required] - public int Weighting { get; set;} - } - [Alias("Order2")] - [Schema("dbo")] - public partial class Order2 : IHasId - { - [Alias("ID")] - [Required] - public int Id { get; set;} - public int? CustomerID { get; set;} - } - [Alias("Band")] - [Schema("dbo")] - public partial class Band : IHasId - { - [Alias("Name")] - [Required] - public string Id { get; set;} - [Required] - public int PersonId { get; set;} - } - [Alias("BarJoin")] - [Schema("dbo")] - public partial class BarJoin : IHasId - { - [Alias("Id")] - [Required] - public Guid Id { get; set;} - [Required] - public string Name { get; set;} - } - [Alias("ModelWithIdAndName")] - [Schema("dbo")] - public partial class ModelWithIdAndName : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("OrderItem2")] - [Schema("dbo")] - public partial class OrderItem2 : IHasId - { - [Alias("ID")] - [Required] - public int Id { get; set;} - public int? Order2Id { get; set;} - public string ProductID { get; set;} - } - [Alias("Entity1")] - [Schema("dbo")] - public partial class Entity1 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string COL_A { get; set;} - } - [Alias("TypeWithOnDeleteSetNull")] - [Schema("dbo")] - public partial class TypeWithOnDeleteSetNull : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public int? RefId { get; set;} - } - [Alias("ModelWithGuidPK")] - [Schema("dbo")] - public partial class ModelWithGuidPK : IHasId - { - [Alias("Id")] - [Required] - public Guid Id { get; set;} - [Required] - public long Long { get; set;} - } - [Alias("FooBar")] - [Schema("dbo")] - public partial class FooBar : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public Guid fkBarId { get; set;} - } - [Alias("tab_Users")] - [Schema("dbo")] - public partial class tab_User : IHasId - { - [Alias("col_Id")] - [AutoIncrement] - public int Id { get; set;} - public string col_Name { get; set;} - [Required] - public int col_Age { get; set;} - } - [Alias("TableA")] - [Schema("dbo")] - public partial class TableA : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public bool Bool { get; set;} - } - [Alias("TypeWithSimpleForeignKey")] - [Schema("dbo")] - public partial class TypeWithSimpleForeignKey : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int RefId { get; set;} - } - [Alias("TableB")] - [Schema("dbo")] - public partial class TableB : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public int TableAId { get; set;} - public string Name { get; set;} - } - [Alias("FooBarBaz")] - [Schema("dbo")] - public partial class FooBarBaz : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int fkFooBarId { get; set;} - [Required] - public int fkBazId { get; set;} - [Required] - public decimal Amount { get; set;} - } - [Alias("TypeWithOnDeleteCascade")] - [Schema("dbo")] - public partial class TypeWithOnDeleteCascade : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public int? RefId { get; set;} - } - [Alias("TypeWithTimeSpan")] - [Schema("dbo")] - public partial class TypeWithTimeSpan : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public long TimeSpan { get; set;} - } - [Alias("Q_Customer")] - [Schema("dbo")] - public partial class Q_Customer : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("Can_use_nested_transactions_Table1")] - [Schema("dbo")] - public partial class Can_use_nested_transactions_Table1 : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public DateTime Dummy { get; set;} - } - [Alias("Can_use_nested_transactions_Table2")] - [Schema("dbo")] - public partial class Can_use_nested_transactions_Table2 : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public DateTime Dummy { get; set;} - } - [Alias("CountTestTable")] - [Schema("dbo")] - public partial class CountTestTable : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string StringValue { get; set;} - public int? CountColumn { get; set;} - } - [Alias("MigrateSqlServerTypes")] - [Schema("dbo")] - public partial class MigrateSqlServerType : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public DateTime? SqlServerTime { get; set;} - public int? OrmLiteTicks { get; set;} - public long? OrmLiteTimeSpan { get; set;} - } - [Alias("CompositeKey")] - [Schema("dbo")] - public partial class CompositeKey - { - [Required] - public long SubId1 { get; set;} - [Required] - public long SubId2 { get; set;} - public string Data { get; set;} - } - [Alias("PocoTable")] - [Schema("dbo")] - public partial class PocoTable : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string CharColumn { get; set;} - public decimal? DecimalColumn { get; set;} - } - [Alias("ModelWithSeedDataSql")] - [Schema("dbo")] - public partial class ModelWithSeedDataSql : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("ModelWithOnlyStringFields")] - [Schema("dbo")] - public partial class ModelWithOnlyStringField : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Name { get; set;} - public string AlbumId { get; set;} - public string AlbumName { get; set;} - } - [Alias("SampleOrderLine")] - [Schema("dbo")] - public partial class SampleOrderLine : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string OrderUrn { get; set;} - [Required] - public long OrderId { get; set;} - [Required] - public long OrderLineId { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - [Required] - public Guid UserId { get; set;} - public string UserName { get; set;} - [Required] - public Guid ProductId { get; set;} - public string MflowUrn { get; set;} - public string ProductType { get; set;} - public string Description { get; set;} - public string UpcEan { get; set;} - public string Isrc { get; set;} - public Guid? RecommendationUserId { get; set;} - public string RecommendationUserName { get; set;} - public string SupplierKeyName { get; set;} - public string CostTierKeyName { get; set;} - public string PriceTierKeyName { get; set;} - [Required] - public decimal VatRate { get; set;} - [Required] - public int ProductPriceIncVat { get; set;} - [Required] - public int Quantity { get; set;} - [Required] - public decimal TransactionValueExVat { get; set;} - [Required] - public decimal TransactionValueIncVat { get; set;} - [Required] - public decimal RecommendationDiscountRate { get; set;} - [Required] - public decimal DistributionDiscountRate { get; set;} - [Required] - public decimal RecommendationDiscountAccruedExVat { get; set;} - [Required] - public decimal DistributionDiscountAccruedExVat { get; set;} - [Required] - public decimal PromoMix { get; set;} - [Required] - public decimal DiscountMix { get; set;} - [Required] - public decimal CashMix { get; set;} - [Required] - public decimal PromoMixValueExVat { get; set;} - [Required] - public decimal DiscountMixValueExVat { get; set;} - [Required] - public decimal CashMixValueIncVat { get; set;} - public string ContentUrn { get; set;} - public string TrackUrn { get; set;} - public string Title { get; set;} - public string ArtistUrn { get; set;} - public string ArtistName { get; set;} - public string AlbumUrn { get; set;} - public string AlbumName { get; set;} - } - [Alias("DynamicAttributeSeedData")] - [Schema("dbo")] - public partial class DynamicAttributeSeedDatum : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("Contact")] - [Schema("dbo")] - public partial class Contact : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Email { get; set;} - [Required] - public int Age { get; set;} - public string Tags { get; set;} - public string FullName { get; set;} - } - [Alias("TestEntity")] - [Schema("dbo")] - public partial class TestEntity : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Foo { get; set;} - public string Bar { get; set;} - public int? NullInt { get; set;} - [Required] - public decimal Baz { get; set;} - } - [Alias("ModelWithIdOnly")] - [Schema("dbo")] - public partial class ModelWithIdOnly : IHasId - { - [Alias("Id")] - [Required] - public long Id { get; set;} - } - [Alias("ModelWithComplexTypes")] - [Schema("dbo")] - public partial class ModelWithComplexType : IHasId - { - [Alias("Id")] - [Required] - public long Id { get; set;} - public string StringList { get; set;} - public string IntList { get; set;} - public string StringMap { get; set;} - public string IntMap { get; set;} - public string Child { get; set;} - } - [Alias("HasDateTimeOffsetMember")] - [Schema("dbo")] - public partial class HasDateTimeOffsetMember : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public DateTimeOffset MomentInTime { get; set;} - } - [Alias("WithAListOfGuids")] - [Schema("dbo")] - public partial class WithAListOfGuid : IHasId - { - [Alias("GuidOne")] - [Required] - public Guid Id { get; set;} - [Required] - public Guid GuidTwo { get; set;} - public string TheGuids { get; set;} - } - [Alias("EntityAttribute")] - [Schema("dbo")] - public partial class EntityAttribute : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int EntityId { get; set;} - [Required] - public string EntityType { get; set;} - [Required] - public string AttributeName { get; set;} - [Required] - public string AttributeValue { get; set;} - } - [Alias("TestEntityWithAliases")] - [Schema("dbo")] - public partial class TestEntityWithAlias : IHasId - { - [Alias("Id Column")] - [AutoIncrement] - public int Id { get; set;} - [Alias("Foo Column")] - public string Foo_Column { get; set;} - [Alias("Bar Column")] - public string Bar_Column { get; set;} - [Alias("Baz Column")] - [Required] - public decimal Baz_Column { get; set;} - } - [Alias("HasNullableDateTimeOffsetMember")] - [Schema("dbo")] - public partial class HasNullableDateTimeOffsetMember : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public DateTimeOffset? MomentInTime { get; set;} - } - [Alias("TestPocoImpl")] - [Schema("dbo")] - public partial class TestPocoImpl : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public DateTime DateCreated { get; set;} - public string Name { get; set;} - } - [Alias("DateTimeOffsetObject")] - [Schema("dbo")] - public partial class DateTimeOffsetObject : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public DateTimeOffset Test { get; set;} - } - [Alias("Unicode_poco")] - [Schema("dbo")] - public partial class Unicode_poco : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Text { get; set;} - } - [Alias("NullableDateTimeOffsetObject")] - [Schema("dbo")] - public partial class NullableDateTimeOffsetObject : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public DateTimeOffset? Test { get; set;} - } - [Alias("Location")] - [Schema("dbo")] - public partial class Location : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Description { get; set;} - public string GeoLocation { get; set;} - } - [Alias("TypeWithEnumAsInt")] - [Schema("dbo")] - public partial class TypeWithEnumAsInt : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public string EnumValue { get; set;} - } - [Alias("ModelWithFieldsOfDifferentTypes")] - [Schema("dbo")] - public partial class ModelWithFieldsOfDifferentType : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - [Required] - public long LongId { get; set;} - [Required] - public Guid Guid { get; set;} - [Required] - public bool Bool { get; set;} - [Required] - public DateTime DateTime { get; set;} - [Required] - public double Double { get; set;} - } - [Alias("AuditTableA")] - [Schema("dbo")] - public partial class AuditTableA : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - [Required] - public DateTime ModifiedDate { get; set;} - public string ModifiedBy { get; set;} - } - [Alias("UserEntity")] - [Schema("dbo")] - public partial class UserEntity : IHasId - { - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - [Required] - public DateTime Created { get; set;} - [Required] - public DateTime Updated { get; set;} - public DateTime? Deleted { get; set;} - [Required] - public bool IsDeleted { get; set;} - } - [Alias("DoubleState")] - [Schema("dbo")] - public partial class DoubleState : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - [Required] - public string State1 { get; set;} - [Required] - public string State2 { get; set;} - } - [Alias("AuditTableB")] - [Schema("dbo")] - public partial class AuditTableB : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - [Required] - public DateTime ModifiedDate { get; set;} - public string ModifiedBy { get; set;} - } - [Alias("AnswerEntity")] - [Schema("dbo")] - public partial class AnswerEntity : IHasId - { - [Required] - public long UserId { get; set;} - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - [Required] - public DateTime Created { get; set;} - [Required] - public DateTime Updated { get; set;} - public DateTime? Deleted { get; set;} - [Required] - public bool IsDeleted { get; set;} - } - [Alias("Author")] - [Schema("dbo")] - public partial class Author : IHasId - { - [Alias("AuthorID")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - [Required] - public DateTime Birthday { get; set;} - public DateTime? LastActivity { get; set;} - [Required] - public decimal Earnings { get; set;} - public decimal? NEarnings { get; set;} - [Required] - public bool Active { get; set;} - public string JobCity { get; set;} - public string Comment { get; set;} - [Required] - public int Rate { get; set;} - public int? NRate { get; set;} - [Required] - public double FloatProperty { get; set;} - public double? NFloatProperty { get; set;} - [Required] - public double DoubleProperty { get; set;} - public double? NDoubleProperty { get; set;} - } - [Alias("Todo")] - [Schema("dbo")] - public partial class Todo : IHasId - { - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - public string Content { get; set;} - [Required] - public int Order { get; set;} - [Required] - public bool Done { get; set;} - } - [Alias("User")] - [Schema("dbo")] - public partial class User : IHasId - { - [Alias("Id")] - [Required] - public long Id { get; set;} - public string Name { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - } - [Alias("SimpleType")] - [Schema("dbo")] - public partial class SimpleType : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("ModelWithLongIdAndStringFields")] - [Schema("dbo")] - public partial class ModelWithLongIdAndStringField : IHasId - { - [Alias("Id")] - [Required] - public long Id { get; set;} - public string Name { get; set;} - public string AlbumId { get; set;} - public string AlbumName { get; set;} - } - [Alias("SimpleAliasedType")] - [Schema("dbo")] - public partial class SimpleAliasedType : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string NewName { get; set;} - } - [Alias("ModelWithFieldsOfDifferentAndNullableTypes")] - [Schema("dbo")] - public partial class ModelWithFieldsOfDifferentAndNullableType : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public int? NId { get; set;} - [Required] - public long LongId { get; set;} - public long? NLongId { get; set;} - [Required] - public Guid Guid { get; set;} - public Guid? NGuid { get; set;} - [Required] - public bool Bool { get; set;} - public bool? NBool { get; set;} - [Required] - public DateTime DateTime { get; set;} - public DateTime? NDateTime { get; set;} - [Required] - public double Float { get; set;} - public double? NFloat { get; set;} - [Required] - public double Double { get; set;} - public double? NDouble { get; set;} - [Required] - public decimal Decimal { get; set;} - public decimal? NDecimal { get; set;} - [Required] - public long TimeSpan { get; set;} - public long? NTimeSpan { get; set;} - } - [Alias("tab_Employee")] - [Schema("dbo")] - public partial class tab_Employee : IHasId - { - [Alias("col_Id")] - [Required] - public int Id { get; set;} - public string col_Name { get; set;} - } - [Alias("PersonWithAutoId")] - [Schema("dbo")] - public partial class PersonWithAutoId : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string FirstName { get; set;} - public string LastName { get; set;} - [Required] - public int Age { get; set;} - } - [Alias("ModelWithFieldsOfNullableTypes")] - [Schema("dbo")] - public partial class ModelWithFieldsOfNullableType : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public int? NId { get; set;} - public long? NLongId { get; set;} - public Guid? NGuid { get; set;} - public bool? NBool { get; set;} - public DateTime? NDateTime { get; set;} - public double? NFloat { get; set;} - public double? NDouble { get; set;} - public decimal? NDecimal { get; set;} - public long? NTimeSpan { get; set;} - } - [Alias("tab_Product")] - [Schema("dbo")] - public partial class tab_Product : IHasId - { - [Alias("col_Id")] - [Required] - public int Id { get; set;} - public string col_Name { get; set;} - [Required] - public decimal col_UnitPrice { get; set;} - } - [Alias("Model Alias Space")] - [Schema("dbo")] - public partial class Model_Alias_Space : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Alias("The Name")] - public string The_Name { get; set;} - } - [Alias("tab_Customer")] - [Schema("dbo")] - public partial class tab_Customer : IHasId - { - [Alias("col_Id")] - [AutoIncrement] - public int Id { get; set;} - public string col_FirstName { get; set;} - public string col_LastName { get; set;} - public string col_Email { get; set;} - public string col_PhoneNumbers { get; set;} - public string col_Addresses { get; set;} - [Required] - public DateTime col_CreatedAt { get; set;} - } - [Alias("Person")] - [Schema("dbo")] - public partial class Person : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("ModelWithIndexer")] - [Schema("dbo")] - public partial class ModelWithIndexer : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("tab_Order")] - [Schema("dbo")] - public partial class tab_Order : IHasId - { - [Alias("col_Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int col_CustomerId { get; set;} - [Required] - public int col_EmployeeId { get; set;} - public string col_ShippingAddress { get; set;} - public DateTime? col_OrderDate { get; set;} - public DateTime? col_RequiredDate { get; set;} - public DateTime? col_ShippedDate { get; set;} - public int? col_ShipVia { get; set;} - [Required] - public decimal col_Freight { get; set;} - [Required] - public decimal col_Total { get; set;} - } - [Alias("UserAuth")] - [Schema("dbo")] - public partial class UserAuth : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string UserName { get; set;} - public string Email { get; set;} - public string PrimaryEmail { get; set;} - public string FirstName { get; set;} - public string LastName { get; set;} - public string DisplayName { get; set;} - public string Salt { get; set;} - public string PasswordHash { get; set;} - public string Roles { get; set;} - public string Permissions { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - [Required] - public DateTime ModifiedDate { get; set;} - public string Meta { get; set;} - } - [Alias("ModelWithNumerics")] - [Schema("dbo")] - public partial class ModelWithNumeric : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public int Byte { get; set;} - [Required] - public int SByte { get; set;} - [Required] - public int Short { get; set;} - [Required] - public int UShort { get; set;} - [Required] - public int Int { get; set;} - [Required] - public int UInt { get; set;} - [Required] - public long Long { get; set;} - [Required] - public long ULong { get; set;} - [Required] - public double Float { get; set;} - [Required] - public double Double { get; set;} - [Required] - public decimal Decimal { get; set;} - } - [Alias("ModelWithGuid")] - [Schema("dbo")] - public partial class ModelWithGuid : IHasId - { - [Alias("Id")] - [Required] - public long Id { get; set;} - [Required] - public Guid Guid { get; set;} - } - [Alias("TypeWithEnum")] - [Schema("dbo")] - public partial class TypeWithEnum : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public string EnumValue { get; set;} - } - [Alias("tab_OrderDetail")] - [Schema("dbo")] - public partial class tab_OrderDetail : IHasId - { - [Alias("col_Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int col_OrderId { get; set;} - [Required] - public int col_ProductId { get; set;} - [Required] - public decimal col_UnitPrice { get; set;} - [Required] - public int col_Quantity { get; set;} - [Required] - public decimal col_Discount { get; set;} - } - [Alias("T01")] - [Schema("dbo")] - public partial class T01 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("Attachment")] - [Schema("dbo")] - public partial class Attachment : IHasId - { - [Alias("Description")] - [Required] - public string Id { get; set;} - public string FileName { get; set;} - public string Type { get; set;} - public byte[] Data { get; set;} - } - [Alias("TableName2")] - [Schema("dbo")] - public partial class TableName2 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public long Long { get; set;} - [Required] - public Guid Guid { get; set;} - } - [Alias("T02")] - [Schema("dbo")] - public partial class T02 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("ClassA")] - [Schema("dbo")] - public partial class ClassA : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string A { get; set;} - } - [Alias("TypeWithFlagsEnum")] - [Schema("dbo")] - public partial class TypeWithFlagsEnum : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public int Flags { get; set;} - } - [Alias("T03")] - [Schema("dbo")] - public partial class T03 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("ClassB")] - [Schema("dbo")] - public partial class ClassB : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string ColumnB { get; set;} - } - [Alias("Table_for_datetime2_tests")] - [Schema("dbo")] - public partial class Table_for_datetime2_test : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public DateTime SomeDateTime { get; set;} - public DateTime? ToVerifyPrecision { get; set;} - public DateTime? NullableDateTimeLeaveItNull { get; set;} - } - [Alias("T04")] - [Schema("dbo")] - public partial class T04 : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("Employee")] - [Schema("dbo")] - public partial class Employee : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("Submission")] - [Schema("dbo")] - public partial class Submission : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public DateTime StoryDate { get; set;} - public string Headline { get; set;} - public string Body { get; set;} - } - [Alias("World")] - [Schema("dbo")] - public partial class World : IHasId - { - [Alias("id")] - [Required] - public int Id { get; set;} - [Required] - public int randomNumber { get; set;} - } - [Alias("ConfigSetting")] - [Schema("dbo")] - public partial class ConfigSetting : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Value { get; set;} - } - [Alias("Group")] - [Schema("dbo")] - public partial class Group : IHasId - { - [Alias("GroupID")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - public string ShortName { get; set;} - [Required] - public int GroupTypeID { get; set;} - public string ContactDetails { get; set;} - [Required] - public DateTime BirthDay { get; set;} - } - [Alias("QO_Customer")] - [Schema("dbo")] - public partial class QO_Customer : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("PersonDescriptor")] - [Schema("dbo")] - public partial class PersonDescriptor : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string FirstName { get; set;} - public string LastName { get; set;} - [Required] - public int Age { get; set;} - } - [Alias("QO_CustomerAddress")] - [Schema("dbo")] - public partial class QO_CustomerAddress : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int QO_CustomerId { get; set;} - public string AddressLine1 { get; set;} - public string AddressLine2 { get; set;} - public string City { get; set;} - public string State { get; set;} - public string Country { get; set;} - } - [Alias("ProductWithManufacturer")] - [Schema("dbo")] - public partial class ProductWithManufacturer : IHasId - { - [Alias("ProductId")] - [Required] - public Guid Id { get; set;} - public string ProductName { get; set;} - [Required] - public Guid fkManufacturerId { get; set;} - public string ManufacturerName { get; set;} - } - [Alias("HasDateTimeOffsetMemeber")] - [Schema("dbo")] - public partial class HasDateTimeOffsetMemeber : IHasId - { - [Alias("MomentInTime")] - [Required] - public DateTimeOffset Id { get; set;} - } - [Alias("Rockstar")] - [Schema("dbo")] - public partial class Rockstar : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public string FirstName { get; set;} - public string LastName { get; set;} - public int? Age { get; set;} - } - [Alias("DynamicCacheEntry")] - [Schema("dbo")] - public partial class DynamicCacheEntry : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Data { get; set;} - public DateTime? ExpiryDate { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - [Required] - public DateTime ModifiedDate { get; set;} - } - [Alias("FooCustomer")] - [Schema("dbo")] - public partial class FooCustomer : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("HasNullableDateTimeOffsetMemeber")] - [Schema("dbo")] - public partial class HasNullableDateTimeOffsetMemeber : IHasId - { - [Alias("MomentInTime")] - [Required] - public DateTimeOffset Id { get; set;} - } - [Alias("RockstarAlbum")] - [Schema("dbo")] - public partial class RockstarAlbum : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int RockstarId { get; set;} - public string Name { get; set;} - } - [Alias("CacheEntry")] - [Schema("dbo")] - public partial class CacheEntry : IHasId - { - [Alias("Id")] - [Required] - public string Id { get; set;} - public string Data { get; set;} - public DateTime? ExpiryDate { get; set;} - [Required] - public DateTime CreatedDate { get; set;} - [Required] - public DateTime ModifiedDate { get; set;} - } - [Alias("OrderBlob")] - [Schema("dbo")] - public partial class OrderBlob : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Customer { get; set;} - public string Employee { get; set;} - public DateTime? OrderDate { get; set;} - public DateTime? RequiredDate { get; set;} - public DateTime? ShippedDate { get; set;} - public int? ShipVia { get; set;} - [Required] - public decimal Freight { get; set;} - public string ShipName { get; set;} - public string ShipAddress { get; set;} - public string ShipCity { get; set;} - public string ShipRegion { get; set;} - public string ShipPostalCode { get; set;} - public string ShipCountry { get; set;} - public string OrderDetails { get; set;} - public string IntIds { get; set;} - public string CharMap { get; set;} - } - [Alias("BarCustomerAddress")] - [Schema("dbo")] - public partial class BarCustomerAddress : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int BarCustomerId { get; set;} - public string AddressLine1 { get; set;} - public string AddressLine2 { get; set;} - public string City { get; set;} - public string State { get; set;} - public string Country { get; set;} - } - [Alias("USERPROFILES")] - [Schema("dbo")] - public partial class USERPROFILE : IHasId - { - [Alias("USERPROFILEID")] - [Required] - public decimal Id { get; set;} - [Required] - public decimal PROFILEID { get; set;} - [Required] - public string USER_ID { get; set;} - [Required] - public decimal ISPRIMARY { get; set;} - } - [Alias("TypeWithByteArrayField")] - [Schema("dbo")] - public partial class TypeWithByteArrayField : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - public byte[] Content { get; set;} - } - [Alias("SelfCustomerAddress")] - [Schema("dbo")] - public partial class SelfCustomerAddress : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string AddressLine1 { get; set;} - public string AddressLine2 { get; set;} - public string City { get; set;} - public string State { get; set;} - public string Country { get; set;} - } - [Alias("Target")] - [Schema("dbo")] - public partial class Target : IHasId - { - public string Name { get; set;} - [Alias("Id")] - [Required] - public int Id { get; set;} - } - [Alias("MultiSelfCustomer")] - [Schema("dbo")] - public partial class MultiSelfCustomer : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - public int? HomeAddressId { get; set;} - public int? WorkAddressId { get; set;} - } - [Alias("LetterFrequency")] - [Schema("dbo")] - public partial class LetterFrequency : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Letter { get; set;} - } - [Alias("LetterWeighting")] - [Schema("dbo")] - public partial class LetterWeighting : IHasId - { - [Alias("LetterFrequencyId")] - [Required] - public long Id { get; set;} - [Required] - public int Weighting { get; set;} - } - [Alias("ModelWithDifferentNumTypes")] - [Schema("dbo")] - public partial class ModelWithDifferentNumType : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int Short { get; set;} - [Required] - public int Int { get; set;} - [Required] - public long Long { get; set;} - [Required] - public double Float { get; set;} - [Required] - public double Double { get; set;} - [Required] - public decimal Decimal { get; set;} - } - [Alias("ModelWithPreDropSql")] - [Schema("dbo")] - public partial class ModelWithPreDropSql : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("SelfCustomer")] - [Schema("dbo")] - public partial class SelfCustomer : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - public int? SelfCustomerAddressId { get; set;} - } - [Alias("Foo")] - [Schema("dbo")] - public partial class Foo : IHasId - { - [Alias("SOME_COLUMN_NAME")] - [Required] - public string Id { get; set;} - } - [Alias("Point")] - [Schema("dbo")] - public partial class Point : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int Width { get; set;} - [Required] - public double Height { get; set;} - [Required] - public double Top { get; set;} - [Required] - public decimal Left { get; set;} - } - [Alias("Table1")] - [Schema("dbo")] - public partial class Table1 : IHasId - { - [Alias("Key")] - [AutoIncrement] - public int Id { get; set;} - public string Ena { get; set;} - } - [Alias("TheModelWithAliasedRowVersion")] - [Schema("dbo")] - public partial class TheModelWithAliasedRowVersion : IHasId - { - [Alias("Id")] - [AutoIncrement] - public long Id { get; set;} - public string Text { get; set;} - [Required] - public long TheVersion { get; set;} - } - [Alias("Q_CustomerAddress")] - [Schema("dbo")] - public partial class Q_CustomerAddress : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int Q_CustomerId { get; set;} - public string AddressLine1 { get; set;} - public string AddressLine2 { get; set;} - public string City { get; set;} - public string State { get; set;} - public string Country { get; set;} - } - [Alias("Poco")] - [Schema("dbo")] - public partial class Poco : IHasId - { - [Alias("Name")] - [Required] - public string Id { get; set;} - } - [Alias("Bar")] - [Schema("dbo")] - public partial class Bar : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string Baz { get; set;} - } - [Alias("SchemaWithRowVersion")] - [Schema("Schema")] - public partial class SchemaWithRowVersion : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - public string RandomStringProperty { get; set;} - [Required] - public byte[] RowVersion { get; set;} - } - [Alias("Section")] - [Schema("Schema")] - public partial class Section : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int ReportSectionId { get; set;} - public string Name { get; set;} - [Required] - public decimal ReportId { get; set;} - } - [Alias("PageAlias")] - [Schema("Schema")] - public partial class PageAlias : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int ReportSectionIdAlias { get; set;} - [Required] - public int SectionIdAlias { get; set;} - } - [Alias("Page")] - [Schema("Schema")] - public partial class Page : IHasId - { - [Alias("Id")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int SectionId { get; set;} - [Required] - public int ReportSectionId { get; set;} - } - [Alias("SectionAlias")] - [Schema("Schema")] - public partial class SectionAlias : IHasId - { - [Alias("Id")] - [Required] - public int Id { get; set;} - [Required] - public int ReportSectionIdAlias { get; set;} - public string NameAlias { get; set;} - [Required] - public int ReportIdAlias { get; set;} - } - [Alias("ReportSections")] - [Schema("MicroSite")] - public partial class ReportSection : IHasId - { - [Alias("ReportSectionID")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - [Required] - public int ReportID { get; set;} - } - [Alias("ReportPages")] - [Schema("MicroSite")] - public partial class ReportPage : IHasId - { - [Required] - public int AccessLevel { get; set;} - [Required] - public int AssignedEmployeeId { get; set;} - [Required] - public bool Cover { get; set;} - [Required] - public bool Deleted { get; set;} - [Required] - public bool Disabled { get; set;} - [Alias("ReportPageID")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int Index { get; set;} - public string Name { get; set;} - [Required] - public int ReportSectionID { get; set;} - public string Template { get; set;} - } - [Alias("LogEntries")] - [Schema("MicroSite")] - public partial class LogEntry : IHasId - { - [Required] - public DateTime Date { get; set;} - [Alias("LogEntriesID")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int KlasId { get; set;} - [Required] - public int PageTrackerId { get; set;} - [Required] - public int ReportID { get; set;} - [Required] - public int ReportPageID { get; set;} - public string RequestUrl { get; set;} - [Required] - public int Type { get; set;} - } - [Alias("Reports")] - [Schema("MicroSite")] - public partial class Report : IHasId - { - [Required] - public int DefaultAccessLevel { get; set;} - [Required] - public bool Deleted { get; set;} - public string Description { get; set;} - [Alias("ReportID")] - [AutoIncrement] - public int Id { get; set;} - public string Name { get; set;} - } - [Alias("EditableRevisions")] - [Schema("MicroSite")] - public partial class EditableRevision : IHasId - { - public string Content { get; set;} - [Required] - public DateTime Date { get; set;} - [Required] - public int EditableID { get; set;} - [Required] - public int EmployeeId { get; set;} - [Alias("EditableRevisionsID")] - [AutoIncrement] - public int Id { get; set;} - public string Reason { get; set;} - public string Styles { get; set;} - } - [Alias("Editables")] - [Schema("MicroSite")] - public partial class Editable : IHasId - { - public string Content { get; set;} - [Alias("EditableID")] - [AutoIncrement] - public int Id { get; set;} - [Required] - public int Index { get; set;} - [Required] - public int ReportPageID { get; set;} - public string Styles { get; set;} - [Required] - public int Type { get; set;} - } -} -#pragma warning restore 1591 - - diff --git a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Poco.tt b/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Poco.tt deleted file mode 100644 index 90419ace3..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.Poco.tt +++ /dev/null @@ -1,105 +0,0 @@ -<#@ include file="OrmLite.Core.ttinclude" #> -<# - // Settings - ConnectionStringName = ""; // Uses last connection string in config if not specified - Namespace = ""; - ClassPrefix = ""; - ClassSuffix = ""; - bool SplitIntoMultipleFiles = false; // if true: Generates one file for every class - bool MakeSingular = true; // if true: Changes the classname to singular if tablename is not singular - bool UseIdAsPK = true; // if true: Changes the primary key property name to Id - bool GenerateConstructor = false; // if true: Generates the default empty constructor - bool UseSchemaAttribute = true; // if true: Adds explicit '[Schema]' attribute - - // Read schema - var tables = LoadTables(MakeSingular); - - -/* - // Tweak Schema - tables["tablename"].Ignore = true; // To ignore a table - tables["tablename"].ClassName = "newname"; // To change the class name of a table - tables["tablename"]["columnname"].Ignore = true; // To ignore a column - tables["tablename"]["columnname"].PropertyName="newname"; // To change the property name of a column - tables["tablename"]["columnname"].PropertyType="bool"; // To change the property type of a column -*/ - - // Generate output - if (tables.Count>0) - { -#> -<# -if (string.IsNullOrEmpty(Namespace)) Namespace=ConnectionStringName; -if (string.IsNullOrEmpty(Namespace)) Namespace="OrmLitePoco"; -var manager = Manager.Create(Host, GenerationEnvironment); -manager.StartHeader(); #>// -// This file was generated by a T4 template. -// Don't change it directly as your change would get overwritten. Instead, make changes -// to the .tt file (i.e. the T4 template) and save it to regenerate this file. - -// Make sure the compiler doesn't complain about missing Xml comments -#pragma warning disable 1591 - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; - -using ServiceStack.OrmLite; -using ServiceStack.DataAnnotations; -using ServiceStack.Model; - -namespace <#=Namespace #> -{ -<#manager.EndBlock(); #> -<# -foreach(Table tbl in from t in tables where !t.Ignore select t) -{ -manager.StartNewFile(tbl.Name + ".cs"); -#> -<# if (MakeSingular) {#> - [Alias("<#=tbl.Name#>")] -<#}#> -<# if (UseSchemaAttribute && !string.IsNullOrEmpty(tbl.Schema)) {#> - [Schema("<#=tbl.Schema#>")] -<#}#> - public partial class <#=tbl.ClassName#><#if (tbl.HasPK() && UseIdAsPK) { #> : IHasId<<#=tbl.PK.PropertyType#>><#}#> - { -<# if (GenerateConstructor) { #> - public <#=tbl.ClassName#>() - { - } - -<# } -foreach(Column col in from c in tbl.Columns where !c.Ignore select c) -{ - if ((col.Name!=col.PropertyName) || (col.IsPK && UseIdAsPK)) { #> - [Alias("<#=col.Name#>")] -<# } if (col.PropertyType == "string" && col.Size > 0) { #> - [StringLength(<#=col.Size#>)] -<# } if (col.IsAutoIncrement) { #> - [AutoIncrement] -<# } if (col.IsComputed) { #> - [Compute] -<# } if (col.IsNullable != true && col.IsAutoIncrement != true) { #> - [Required] -<# } if (!col.IsPK){#> - public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set;} -<# } if (col.IsPK && UseIdAsPK) { #> - public <#=col.ProperPropertyType#> Id { get; set;} -<# } if (col.IsPK && !UseIdAsPK) { #> - [PrimaryKey] - public <#=col.ProperPropertyType#> <#=col.PropertyName#> { get; set;} -<# } #> -<# } #> - } -<# manager.EndBlock(); #> -<# } #> -<#manager.StartFooter(); #> -} -#pragma warning restore 1591 -<#manager.EndBlock(); #> -<#manager.Process(SplitIntoMultipleFiles); #> -<# } #> - - diff --git a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.SP.cs b/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.SP.cs deleted file mode 100644 index c8196ba33..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.SP.cs +++ /dev/null @@ -1,83 +0,0 @@ - -// This file was automatically generated by the PetaPoco T4 Template -// Do not make changes directly to this file - edit the template instead -// -// The following connection settings were used to generate this file -// -// Connection String Name: `AppDb` -// Provider: `System.Data.SqlClient` -// Connection String: `Server=localhost;Database=test;User Id=test;password=**zapped**;` -// Schema: `` -// Include Views: `False` - -// Factory Name: `SqlClientFactory` -using System; -using System.Data.Common; -using System.Data; -using System.Collections.Generic; -using ServiceStack.OrmLite; - -namespace StoredProcedures -{ - public static class SPList - { - private static DbParameter CreateNewParameter(DbCommand dbCommand, string paramName, object paramValue, ParameterDirection paramDirection, DbType paramType) - { - DbParameter param = dbCommand.CreateParameter(); - param.Direction = paramDirection; - param.DbType = paramType; - param.ParameterName = paramName; - param.Value = paramValue; - return param; - } - - public static OrmLiteSPStatement DummyColumn(this IDbConnection db, int? times = null) - { - var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); - dbCmd.CommandText = "DummyColumn"; - dbCmd.CommandType = CommandType.StoredProcedure; - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"Times",times,ParameterDirection.Input,DbType.Int32)); - return new OrmLiteSPStatement(db, dbCmd); - } - - public static OrmLiteSPStatement DummyProc(this IDbConnection db, string name = null) - { - var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); - dbCmd.CommandText = "DummyProc"; - dbCmd.CommandType = CommandType.StoredProcedure; - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"Name",name,ParameterDirection.Input,DbType.String)); - return new OrmLiteSPStatement(db, dbCmd); - } - - public static OrmLiteSPStatement SP_upload_file(this IDbConnection db, string filename = null, string filetype = null, byte[] filecontent = null) - { - var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); - dbCmd.CommandText = "SP_upload_file"; - dbCmd.CommandType = CommandType.StoredProcedure; - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"filename",filename,ParameterDirection.Input,DbType.AnsiString)); - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"filetype",filetype,ParameterDirection.Input,DbType.AnsiString)); - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"filecontent",filecontent,ParameterDirection.Input,DbType.Binary)); - return new OrmLiteSPStatement(db, dbCmd); - } - - public static OrmLiteSPStatement DummyTable(this IDbConnection db, int? times = null) - { - var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); - dbCmd.CommandText = "DummyTable"; - dbCmd.CommandType = CommandType.StoredProcedure; - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"Times",times,ParameterDirection.Input,DbType.Int32)); - return new OrmLiteSPStatement(db, dbCmd); - } - - public static OrmLiteSPStatement DummyScalar(this IDbConnection db, int? times = null) - { - var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); - dbCmd.CommandText = "DummyScalar"; - dbCmd.CommandType = CommandType.StoredProcedure; - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"Times",times,ParameterDirection.Input,DbType.Int32)); - return new OrmLiteSPStatement(db, dbCmd); - } - - } -} - diff --git a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.SP.tt b/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.SP.tt deleted file mode 100644 index f10b4b13c..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLite.SP.tt +++ /dev/null @@ -1,56 +0,0 @@ -<#@ include file="OrmLite.Core.ttinclude" #> -<# - // Settings - ConnectionStringName = ""; // Uses last connection string in config if not specified - var SPNamespace = "StoredProcedures"; - ClassPrefix = ""; - ClassSuffix = ""; - - // Read schema - var sps = LoadSPs(); - - // Generate output - if (sps.Count>0) - { -#> -<# -if (string.IsNullOrEmpty(SPNamespace)) SPNamespace=ConnectionStringName; -if (string.IsNullOrEmpty(SPNamespace)) SPNamespace="StoredProcedures"; -#> -using System; -using System.Data.Common; -using System.Data; -using System.Collections.Generic; -using ServiceStack.OrmLite; - -namespace <#=SPNamespace#> -{ - public static class SPList - { - private static DbParameter CreateNewParameter(DbCommand dbCommand, string paramName, object paramValue, ParameterDirection paramDirection, DbType paramType) - { - DbParameter param = dbCommand.CreateParameter(); - param.Direction = paramDirection; - param.DbType = paramType; - param.ParameterName = paramName; - param.Value = paramValue; - return param; - } - -<#foreach(var sp in sps){#> - public static OrmLiteSPStatement <#=sp.CleanName#>(this IDbConnection db<#foreach(var param in sp.Parameters){#>, <#=param.NullableSysType#> <#=Inflector.MakeInitialLowerCase(param.Name)#> = null<#}#>) - { - var dbCmd = (DbCommand)OrmLiteConfig.ExecFilter.CreateCommand(db).ToDbCommand(); - dbCmd.CommandText = "<#=sp.Name#>"; - dbCmd.CommandType = CommandType.StoredProcedure; -<#if (sp.Parameters.Count > 0) { foreach(var param in sp.Parameters){#> - dbCmd.Parameters.Add(CreateNewParameter(dbCmd,"<#=param.Name#>",<#=Inflector.MakeInitialLowerCase(param.Name)#>,ParameterDirection.Input,<#=param.DbType#>)); -<#}#> <#}#> - return new OrmLiteSPStatement(db, dbCmd); - } - -<#}#> - } -} -<# } #> - diff --git a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLiteT4Tests.cs b/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLiteT4Tests.cs deleted file mode 100644 index d1ab7e00d..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/T4/OrmLiteT4Tests.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Data; -using NUnit.Framework; -using ServiceStack.OrmLite.Tests.Shared; -using ServiceStack.Text; -using StoredProcedures; - -namespace ServiceStack.OrmLite.Tests.T4 -{ - [TestFixture] - public class OrmLiteT4Tests - : OrmLiteTestBase - { - private IDbConnection db; - - [SetUp] - public void SetUp() - { - SuppressIfOracle("SQL Server tests"); - db = CreateSqlServerDbFactory().OpenDbConnection(); - } - - [TearDown] - public void TearDown() - { - db.Dispose(); - } - - public class DummyProc - { - public int Id { get; set; } - public string Name { get; set; } - } - - [Test] - public void Can_call_Dummy_Proc() - { - //defined in SqlServerProviderTests.Can_SqlList_StoredProc_passing_null_parameter() - using (var spResult = db.DummyProc("name")) - { - var results = spResult.ConvertToList(); - - Assert.That(results.Count, Is.GreaterThan(0)); - Assert.That(results[0].Id, Is.GreaterThan(0)); - Assert.That(results[0].Name, Is.StringStarting("Name")); - } - } - - [Test] - public void Can_call_Dummy_Proc_in_Transaction() - { - using (var dbTrans = db.OpenTransaction()) - using (var spResult = db.DummyProc("name")) - { - var results = spResult.ConvertToList(); - - dbTrans.Commit(); - - Assert.That(results.Count, Is.GreaterThan(0)); - Assert.That(results[0].Id, Is.GreaterThan(0)); - Assert.That(results[0].Name, Is.StringStarting("Name")); - } - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/TestHelpers.cs b/tests/ServiceStack.OrmLiteV45.Tests/TestHelpers.cs deleted file mode 100644 index 3c0028353..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/TestHelpers.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace ServiceStack.OrmLite.Tests -{ - public enum Dialect - { - Sqlite, - SqlServer, - PostgreSql, - MySql, - SqlServerMdf, - Oracle, - VistaDb, - } - - public static class TestHelpers - { - public static string NormalizeSql(this string sql) - { - return sql.ToLower() - .Replace("\"", "") - .Replace("`", "") - .Replace("_", "") - .Replace(":", "@") //postgresql - .Replace("\n", " ") - .TrimEnd(); - } - } -} \ No newline at end of file diff --git a/tests/ServiceStack.OrmLiteV45.Tests/UseCase/CustomerOrdersUseCase.cs b/tests/ServiceStack.OrmLiteV45.Tests/UseCase/CustomerOrdersUseCase.cs deleted file mode 100644 index aa518e0be..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/UseCase/CustomerOrdersUseCase.cs +++ /dev/null @@ -1,225 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using NUnit.Framework; -using ServiceStack.DataAnnotations; -using ServiceStack.Logging; - -namespace ServiceStack.OrmLite.Tests.UseCase -{ - public enum PhoneType - { - Home, - Work, - Mobile, - } - - public enum AddressType - { - Home, - Work, - Other, - } - - public class Address - { - public string Line1 { get; set; } - public string Line2 { get; set; } - public string ZipCode { get; set; } - public string State { get; set; } - public string City { get; set; } - public string Country { get; set; } - } - - public class Customer - { - public Customer() - { - this.PhoneNumbers = new Dictionary(); - this.Addresses = new Dictionary(); - } - - [AutoIncrement] // Creates Auto primary key - public int Id { get; set; } - - public string FirstName { get; set; } - - public string LastName { get; set; } - - [Index(Unique = true)] // Creates Unique Index - public string Email { get; set; } - - public Dictionary PhoneNumbers { get; set; } - - public Dictionary Addresses { get; set; } - - public DateTime CreatedAt { get; set; } - } - - public class Order - { - [AutoIncrement] - public int Id { get; set; } - - [References(typeof(Customer))] //Creates Foreign Key - public int CustomerId { get; set; } - - [References(typeof(Employee))] //Creates Foreign Key - public int EmployeeId { get; set; } - - public Address ShippingAddress { get; set; } //Blobbed (no Address table) - - public DateTime? OrderDate { get; set; } - - public DateTime? RequiredDate { get; set; } - - public DateTime? ShippedDate { get; set; } - - public int? ShipVia { get; set; } - - public decimal Freight { get; set; } - - public decimal Total { get; set; } - } - - public class OrderDetail - { - [AutoIncrement] - public int Id { get; set; } - - [References(typeof(Order))] //Creates Foreign Key - public int OrderId { get; set; } - - public int ProductId { get; set; } - - public decimal UnitPrice { get; set; } - - public short Quantity { get; set; } - - public decimal Discount { get; set; } - } - - public class Employee - { - public int Id { get; set; } - - public string Name { get; set; } - } - - public class Product - { - public int Id { get; set; } - - public string Name { get; set; } - - public decimal UnitPrice { get; set; } - } - - /// - /// Stand-alone class, No other configs, nothing but POCOs. - /// - [TestFixture] - public class CustomerOrdersUseCase : OrmLiteTestBase - { - [Test] - public async Task Can_run_Customer_Orders_UseCase() - { - LogManager.LogFactory = new ConsoleLogFactory(); - - using (IDbConnection db = OpenDbConnection()) - { - //Re-Create all table schemas: - RecreateTables(db); - - await db.InsertAsync(new Employee { Id = 1, Name = "Employee 1" }); - await db.InsertAsync(new Employee { Id = 2, Name = "Employee 2" }); - var product1 = new Product { Id = 1, Name = "Product 1", UnitPrice = 10 }; - var product2 = new Product { Id = 2, Name = "Product 2", UnitPrice = 20 }; - await db.SaveAsync(product1, product2); - - var customer = new Customer { - FirstName = "Orm", - LastName = "Lite", - Email = "ormlite@servicestack.net", - PhoneNumbers = - { - { PhoneType.Home, "555-1234" }, - { PhoneType.Work, "1-800-1234" }, - { PhoneType.Mobile, "818-123-4567" }, - }, - Addresses = - { - { AddressType.Work, new Address { Line1 = "1 Street", Country = "US", State = "NY", City = "New York", ZipCode = "10101" } }, - }, - CreatedAt = DateTime.UtcNow, - }; - - var customerId = await db.InsertAsync(customer, selectIdentity: true); //Get Auto Inserted Id - customer = await db.SingleAsync(new { customer.Email }); //Query - Assert.That(customer.Id, Is.EqualTo(customerId)); - - //Direct access to System.Data.Transactions: - using (IDbTransaction trans = db.OpenTransaction(IsolationLevel.ReadCommitted)) - { - var order = new Order { - CustomerId = customer.Id, - EmployeeId = 1, - OrderDate = DateTime.UtcNow, - Freight = 10.50m, - ShippingAddress = new Address { Line1 = "3 Street", Country = "US", State = "NY", City = "New York", ZipCode = "12121" }, - }; - await db.SaveAsync(order); //Inserts 1st time - - //order.Id populated on Save(). - - var orderDetails = new[] { - new OrderDetail { - OrderId = order.Id, - ProductId = product1.Id, - Quantity = 2, - UnitPrice = product1.UnitPrice, - }, - new OrderDetail { - OrderId = order.Id, - ProductId = product2.Id, - Quantity = 2, - UnitPrice = product2.UnitPrice, - Discount = .15m, - } - }; - - await db.SaveAsync(orderDetails); - - order.Total = orderDetails.Sum(x => x.UnitPrice * x.Quantity * x.Discount) + order.Freight; - - await db.SaveAsync(order); //Updates 2nd Time - - trans.Commit(); - } - } - } - - public static void RecreateTables(IDbConnection db) - { - DropTables(db); - - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - } - - public static void DropTables(IDbConnection db) - { - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - } - } - -} diff --git a/tests/ServiceStack.OrmLiteV45.Tests/packages.config b/tests/ServiceStack.OrmLiteV45.Tests/packages.config deleted file mode 100644 index ad37a5282..000000000 --- a/tests/ServiceStack.OrmLiteV45.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/tests/readme.md b/tests/readme.md new file mode 100644 index 000000000..c5fdcab7f --- /dev/null +++ b/tests/readme.md @@ -0,0 +1,120 @@ +# OrmLite Testing + +The following describes some typical testing scenarios + +## Docker Db instances + +For integration testing, there is a docker-compose file that can spin up all versions of supported providers. See the readme in /src/docker for more details + +## Test Basics + +To create tests to run against one or more providers, inherit from `OrmLiteProvidersTestBase` +and use the `TestFixtureOrmLiteAttribute` class. + +```csharp +[TestFixtureOrmLite] +public class DbFeatures1 : OrmLiteProvidersTestBase +{ + // Required Ctor, Dialects will be injected by attribute + public DbFeatures1(Dialect dialect) : base(dialect) + { + } + + // Tests can be repeated for one or more providers + [Test] + public void Test1() + { + // Current test dialect + var dialect = base.Dialect; + + // current test dialectprovider + var dialectProvider = base.DialectProvider; + + // current DbFactory + var dbFactory = base.DbFactory; + + // open the correct db connection based on dialect + using(var db = OpenConnection()) + { + // db agnostic tests + } + } +} +``` + +By default, the tests will run against in-memory instances of Sqlite. +This is set in `TestConfig.DefaultDialects` and can be overridden either by changing +the value assigned or by setting an Environment Variable named `DefaultDialects` to one of the Dialect enum values. + +The accepted values come from the enum `Dialect` which is injected into the class constructor. + +## Targeting specific providers + +To run tests against specific providers, use `TestFixtureOrmLiteDialectsAttribute`. + +```csharp +[TestFixtureOrmLiteDialects(Dialect.SqlServer2008 | Dialect.SqlServer2012)] +public class SqlDbFeatures1 : OrmLiteProvidersTestBase +{ + ... + + [Test] + public void Test1() + { + // Will execute for SqlServer provider and dialect versions + + // Current test dialect + var dialect = base.Dialect; + + // current test dialectprovider + var dialectProvider = base.DialectProvider + + // open the correct db connection based on dialect + using(var db = OpenConnection()) + { + // db agnostic tests + } + } +} +``` + +## Excluding specific tests + +### For all tests in fixture + +To exclude testing specific dialects for all tests in a fixture, use the `IgnoreDialectAttribute` + +```csharp +[TestFixtureOrmLite()] +[IgnoreDialect(Dialects.AnyMySql | Dialects.PostgreSql9, "Not supported by database")] +public class SqlDbFeatures1 : OrmLiteProvidersTestBase +{ +} +``` + +### Individual tests + +To exclude individual tests for one or more db providers, use the `IgnoreDialectAttribute` + +```csharp +[Test] +[IgnoreDialect(Dialect.PostgreSql9 | Dialect.PostgreSql10, "ignore message to output")] +[IgnoreDialect(Dialect.AnySqlServer, "diff ignore message to output")] +public void Test1() +{ + // Test will not run for any dialects ignored above but any others +} +``` + +### Test runner filtering + +Each test has a category added corresponding to the dialect which allows for filtering +tests using the existing Category filters for nunit runners or dotnet test. + +```bash +# Only run Sql server dialect tests +dotnet test --filter TestCategory=AnySqlServer + +# Run all tests except MySql5_5 +dotnet test --filter TestCategory!=MySql5_5 +```